怎样设计一个分布式的爬虫服务?

2016-02-22 11:31:13 +08:00
 wangleineo

爬虫程序有一个很大的问题,就是服务端会限制一个 IP 的请求频率,甚至封禁一个 IP 。解决这个问题的一个办法就是用多个不同网络的主机或代理来发出请求(同时限制频率),最后再把爬取的结果汇总。

Scrapy Cloud 就是一个这样的分布式服务: https://www.scrapinghub.com/, 是 scrapy 的作者们写的一个商业化的 SaaS 服务,核心非开源。

问题是:在接收到一个爬虫请求以后,怎样分配爬取链接到各个 worker 上面?这个问题似乎比较复杂,因为需要爬取的链接不是一个线性的列表,而是一个图结构(图中每个节点是一个需要爬取的链接),在预先只有图的根节点的情况下,怎样把爬取任务分配给各个 Worker 节点,又使得各个节点的任务尽量平均又不重合呢?

比如一个策略是,从根节点展开第一个层次的所有链接,然后把这些链接平均分配到各个 worker 开始爬取,但是有可能第二层有很多个公共的链接,各个 worker 就会重复很多爬取动作。

有什么好的想法吗?

6147 次点击
所在节点    问与答
16 条回复
gouwudang
2016-02-22 12:15:09 +08:00
楼主对这方面感兴趣欢迎来我司,我们在找 Python 工程师加盟,更好的解决这方面的问题
yangqi
2016-02-22 12:41:19 +08:00
中间加一层 scraper ,专门爬链接,然后再分配给 worker 抓取页面
knightdf
2016-02-22 12:46:46 +08:00
我是写了一个基于 redis 的 bloomfilter 来做, master 节点只分配入口 url ,集群子节点只管抓取,管理全部 master 节点来管理,对 子节点定时关机换机器。跑在 AWS 上
yixiang
2016-02-22 12:48:32 +08:00
无经验。随意想到的思路:
多个 worker ,一个 center , center 负责分配任务,爬虫爬完后把结果返回给 center ,只在 center 这里存储整个图和工作怎样分配。

其实类似于……
一个爬虫+一堆匿名代理,请求一个就换一个代理。

估计实际环境中会遇到许多问题。
wangleineo
2016-02-22 13:00:12 +08:00
@gouwudang IT 桔子上没看到你们融资啊,是已经闷声发大财了吗?

@yangqi 这样的话, scraper 需要访问所有链接了,还是很容易被禁。 worker 只是分担了抓取动作本身。
wangleineo
2016-02-22 13:02:50 +08:00
@knightdf 那 bloomfilter 是做什么的?看一个 url 有没有被爬过?
Kirscheis
2016-02-22 14:05:29 +08:00
这样是否可行?
worker 首先 parse ,之后把抽取的 url 返回给 master ,然后从 master 的 waiting list 领取下一个 request 。
master 维护一个保存着爬过的 url 的库, worker 返回的所有链接用 bloomfilter 快速检查是否爬过,然后把没爬过的加入 waiting list 。
sohoer
2016-02-22 14:05:37 +08:00
一个 Crawler 负责任务调度,将需要采集网址通过负载均衡的方式分发给其它 Crawler
knightdf
2016-02-22 15:09:13 +08:00
@wangleineo 你不是要解决 URL 分配的问题么,这样我的子节点就只用接受根节点这一个 URL 任务了
izoabr
2016-02-22 15:28:18 +08:00
要分是不是得 hadoop 了?
chinajik
2016-02-22 15:49:45 +08:00
客户机方面:
ip ban 的话就用 ADSL 服务器.
Captcha 用 selenium 截图用第三方平台解析

消费端:
走队列建索引, 基本数据传输走 websocket 请求 keepalive 穿透性强



再写些拨号脚本,重启脚本的,自动阀值调控, 多线程就不用讲了。

爬虫对实时性要求高的,基本看被爬的服务器的阀值峰值,基本上核心价值观就是你不影响他线上业务,一定程度的爬虫运维是睁一只眼闭一只眼的...
wangleineo
2016-02-22 16:05:31 +08:00
@Kirscheis
@knightdf
scrapinghub 就是这么做的: https://github.com/scrapinghub/frontera
这个组件的功能就是根据一些策略给 worker 分配爬取任务, worker 爬到新的 url 再提交给 frontera.
knightdf
2016-02-22 16:35:20 +08:00
@wangleineo 对的,这样设计集群靠谱点, slave 只做抓取的任务
yangqi
2016-02-22 22:28:16 +08:00
@wangleineo scraper 也可以是分布式的啊
SlipStupig
2016-02-23 00:50:46 +08:00
你如果是遇到被 ban 掉,你解决方案肯定不是去搞分布式,几种方案
1.伪造 x-forward-for 头部去欺骗,不一定能成功
2.去用 http 代理,一些网站会拉黑一些代理
3.用 tor 节点
4.adsl 重新拨号,这个不靠谱, adsl 的 ip 量有限,而且不一定恰好遇到 ip 释放

结论就是,花点钱去买代理吧
ssllff123
2016-09-09 09:37:11 +08:00
@knightdf scrapy 实现了这个功能。 scrapy-redis 但是我正在学习中

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/258169

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX