请教网络爬虫模式

18 views
Skip to first unread message

张高崇

unread,
Dec 1, 2009, 9:16:30 PM12/1/09
to dev4s...@googlegroups.com
最近公司要求做一个网络爬虫,现在我采用的是线程池加内存池,并做了3个队列, 一个队列放还没下载的url, 一个放已经下载好的url, 最后放失败的url,
语言是用c作的。没有用别的库。请教大虾们一个问题, 从还没下载的队列中取出一个url后, 线程在生成了一个request后, socket 应该设计成什么模式?
共用一个socket 还是 和线程池一样, 设计一个socket的队列, 每次要发送请求的时候, 从队列中取出一个socket, 然后发送?
搞的我焦头烂额。。谢谢了

张高崇

unread,
Dec 1, 2009, 10:05:58 PM12/1/09
to dev4s...@googlegroups.com
请大家帮帮忙, 在线等

2009/12/2 张高崇 <zhang...@gmail.com>

jrckkyy

unread,
Dec 1, 2009, 10:24:57 PM12/1/09
to dev4s...@googlegroups.com
我用的boost,异步io,你可以用select

2009/12/2 张高崇 <zhang...@gmail.com>

xi heng

unread,
Dec 1, 2009, 11:19:26 PM12/1/09
to dev4s...@googlegroups.com
最好采用生产者/消费者模式来做
通过生产者提取url
再把url送到消费者那边去爬取
这样有利于做分布式的爬虫,不易被一些自私型网站发现

2009/12/2 jrckkyy <jrc...@gmail.com>



--
blog:http://www.i7xh.com
Twitter:http://twitter.com/i7xh

xi heng

unread,
Dec 1, 2009, 11:20:38 PM12/1/09
to dev4s...@googlegroups.com
用c的话
可以去看看libevent的例子
有现成的爬虫

2009/12/2 张高崇 <zhang...@gmail.com>

张高崇

unread,
Dec 1, 2009, 11:34:57 PM12/1/09
to dev4s...@googlegroups.com
对的, 我现在就是用的 生产者, 消费者的模式来做的, 比如, 一个线程 从队列中取出一个url, 要发一个请求给服务器, 那么 发轻松的socket 该怎么设计呢?
第一:主线程 负责发请求, 也就是说只有一个socket, 主线程收到html后, 唤醒线程池中的一个线程, 进行逻辑处理, 并把html中的url 再次提出, 放到url 队列中。。。如果这样的话 会不会造成线程池的线程一直处于wait 状态。

第2:设计一个socket 队列(不知道可行不可行, 一台电脑), 主线程轮询url 队列, 如果有url, 唤醒线程池中的一个线程, 线程从socket 队列中取出一个 socket, 发请求, 并处理逻辑。把html中的url提出来, 放在url队列中。

请大家帮忙, 如果是第2种, socket 该如何实现。。。谢谢了

2009/12/2 xi heng <ixh.x...@gmail.com>

xi heng

unread,
Dec 2, 2009, 12:17:52 AM12/2/09
to dev4s...@googlegroups.com
我觉得可以不用线程
就用异步的io就可以搞定

2009/12/2 张高崇 <zhang...@gmail.com>

张高崇

unread,
Dec 2, 2009, 12:22:43 AM12/2/09
to dev4s...@googlegroups.com
因为这个程序估计要经常用。。。所以我用的是异步io 和线程都用到了。。异步io 这部分是没有问题了
就是socket 这个问题 。。

2009/12/2 xi heng <ixh.x...@gmail.com>

张高崇

unread,
Dec 2, 2009, 9:07:19 PM12/2/09
to dev4s...@googlegroups.com
请大家帮忙。。。谢谢

2009/12/2 张高崇 <zhang...@gmail.com>

关中刀客

unread,
Dec 3, 2009, 12:52:12 AM12/3/09
to 高性能服务器研发与运营邮件列表
前阵子正好自己做了一个类似的系统,说说我的架构于实现吧

一整套的框架:一个主要的总控服务器MasterServer,一系列网页爬虫服务器HTTPSpiderServer,一系列网页分析服务器
HTMLFilterServer,一个网页信息管理存储服务器URLServer,一系列索引服务器IndexServer。
网页信息管理存储服务器,使用BDB存储了所有待爬虫的网页,以爬虫但是暂未分析的网页,已经分析提取的网页,每次网页信息管理存储服务器,定时的提取
一批网页通过MasterServer发送给诸多的HTTPSpiderServer来爬虫,并且定时的提取一批网页通过MasterServer发送
给诸多的HTMLFilterServer去分析。URLServer保证网页不会被异常的丢失或者被重复的下载,分析等。所有的Server都是在自
己以前实现的一套库(包含公共代码库和网络处理等,网络是建立在win平台下,IOCP+多线程的异步处理方式)上面开发的,底层都是使用了自己的库,
只需要开发一下上层逻辑即可,很方便。

On 12月3日, 上午10时07分, 张高崇 <zhanggc0...@gmail.com> wrote:
> 请大家帮忙。。。谢谢
>
> 2009/12/2 张高崇 <zhanggc0...@gmail.com>


>
>
>
> > 因为这个程序估计要经常用。。。所以我用的是异步io 和线程都用到了。。异步io 这部分是没有问题了
> > 就是socket 这个问题 。。
>

> > 2009/12/2 xi heng <ixh.xih...@gmail.com>
>
> >> 我觉得可以不用线程
> >> 就用异步的io就可以搞定
>
> >> 2009/12/2 张高崇 <zhanggc0...@gmail.com>


>
> >>> 对的, 我现在就是用的 生产者, 消费者的模式来做的, 比如, 一个线程 从队列中取出一个url, 要发一个请求给服务器, 那么
> >>> 发轻松的socket 该怎么设计呢?
> >>> 第一:主线程 负责发请求, 也就是说只有一个socket, 主线程收到html后, 唤醒线程池中的一个线程, 进行逻辑处理,
> >>> 并把html中的url 再次提出, 放到url 队列中。。。如果这样的话 会不会造成线程池的线程一直处于wait 状态。
>
> >>> 第2:设计一个socket 队列(不知道可行不可行, 一台电脑), 主线程轮询url 队列, 如果有url, 唤醒线程池中的一个线程,
> >>> 线程从socket 队列中取出一个 socket, 发请求, 并处理逻辑。把html中的url提出来, 放在url队列中。
>
> >>> 请大家帮忙, 如果是第2种, socket 该如何实现。。。谢谢了
>

> >>> 2009/12/2 xi heng <ixh.xih...@gmail.com>
>
> >>>> 用c的话
> >>>> 可以去看看libevent的例子
> >>>> 有现成的爬虫
>
> >>>> 2009/12/2 张高崇 <zhanggc0...@gmail.com>


>
> >>>>> 最近公司要求做一个网络爬虫,现在我采用的是线程池加内存池,并做了3个队列, 一个队列放还没下载的url, 一个放已经下载好的url,
> >>>>> 最后放失败的url,
>
> >>>>> 语言是用c作的。没有用别的库。请教大虾们一个问题, 从还没下载的队列中取出一个url后, 线程在生成了一个request后, socket
> >>>>> 应该设计成什么模式?
> >>>>> 共用一个socket 还是 和线程池一样, 设计一个socket的队列, 每次要发送请求的时候, 从队列中取出一个socket, 然后发送?
> >>>>> 搞的我焦头烂额。。谢谢了
>
> >>>> --
> >>>> blog:http://www.i7xh.com
> >>>> Twitter:http://twitter.com/i7xh
>
> >> --
> >> blog:http://www.i7xh.com

> >> Twitter:http://twitter.com/i7xh- 隐藏被引用文字 -
>
> - 显示引用的文字 -

SevenCat

unread,
Dec 3, 2009, 1:22:41 AM12/3/09
to 高性能服务器研发与运营邮件列表
感觉可以共用一个socket,设计一个发送队列,每次发送请求的时候,把请求打包丢到发送队列中,另一个线程不停的从发送队列中取数据,并发送。

jonyare

unread,
Dec 8, 2009, 8:36:39 PM12/8/09
to dev4s...@googlegroups.com

crawl - a small and efficient HTTP crawler 用c写的一个 ,Berkeley db 和libevent,自己在 家装没装上

http://www.monkey.org/~provos/crawl/



2009/12/3 SevenCat <baste...@gmail.com>

femto Zheng

unread,
Dec 8, 2009, 11:55:42 PM12/8/09
to dev4s...@googlegroups.com
跑了,问题下载的网页到那去了?只看见一个crawl.db

2009/12/9 jonyare <liufab...@gmail.com>

jonyare

unread,
Dec 10, 2009, 5:48:04 AM12/10/09
to dev4s...@googlegroups.com

安装成功了??用的Berkeley db 吧
2009/12/9 femto Zheng <femt...@gmail.com>
问题下载的网页到那去了

jyf1987

unread,
Dec 10, 2009, 9:05:42 PM12/10/09
to 高性能服务器研发与运营邮件列表
频繁开socket是不现实的
要考虑给同一个host的url归到一类来 不关socket访问

On 12月2日, 上午10时16分, 张高崇 <zhanggc0...@gmail.com> wrote:

关中刀客

unread,
Dec 10, 2009, 10:15:23 PM12/10/09
to 高性能服务器研发与运营邮件列表
那样子是不现实的,尤其是一个分布式的系统中,如果不关闭的话,需要处理很多的事情,例如,每次GET完之后就关闭,那么我的爬虫在收到对方关闭的时
候,就可以认定一个网页完全的接收到了,然后做相应的处理,如果不关闭,自己需要实现很多的事情,有点得不偿失。当然,我在做的时候,每一个爬虫节点服
务器,内存内维护一个近期访问的所有网站对应的ip地址,这样子不需要每次都通过dns来查找,一定时间内没有访问的,自动剔除。

> > 搞的我焦头烂额。。谢谢了- 隐藏被引用文字 -
>
> - 显示引用的文字 -

Samuel Ji

unread,
Dec 11, 2009, 1:02:37 AM12/11/09
to dev4s...@googlegroups.com


2009/12/11 jyf1987 <jyf...@gmail.com>
频繁开socket是不现实的
要考虑给同一个host的url归到一类来 不关socket访问
搭车问一下:对于大规模的爬虫来说,epoll/iocp之类的网络模型也起到跟server一样的作用么? 

On 12月2日, 上午10时16分, 张高崇 <zhanggc0...@gmail.com> wrote:
> 最近公司要求做一个网络爬虫,现在我采用的是线程池加内存池,并做了3个队列, 一个队列放还没下载的url, 一个放已经下载好的url,
> 最后放失败的url,
> 语言是用c作的。没有用别的库。请教大虾们一个问题, 从还没下载的队列中取出一个url后, 线程在生成了一个request后, socket
> 应该设计成什么模式?
> 共用一个socket 还是 和线程池一样, 设计一个socket的队列, 每次要发送请求的时候, 从队列中取出一个socket, 然后发送?
> 搞的我焦头烂额。。谢谢了

--
高性能服务器研发与运营
 http://groups.google.com/group/dev4server

Reply all
Reply to author
Forward
0 new messages