爬虫程序有一个很大的问题,就是服务端会限制一个 IP 的请求频率,甚至封禁一个 IP 。解决这个问题的一个办法就是用多个不同网络的主机或代理来发出请求(同时限制频率),最后再把爬取的结果汇总。
Scrapy Cloud 就是一个这样的分布式服务: https://www.scrapinghub.com/, 是 scrapy 的作者们写的一个商业化的 SaaS 服务,核心非开源。
问题是:在接收到一个爬虫请求以后,怎样分配爬取链接到各个 worker 上面?这个问题似乎比较复杂,因为需要爬取的链接不是一个线性的列表,而是一个图结构(图中每个节点是一个需要爬取的链接),在预先只有图的根节点的情况下,怎样把爬取任务分配给各个 Worker 节点,又使得各个节点的任务尽量平均又不重合呢?
比如一个策略是,从根节点展开第一个层次的所有链接,然后把这些链接平均分配到各个 worker 开始爬取,但是有可能第二层有很多个公共的链接,各个 worker 就会重复很多爬取动作。
有什么好的想法吗?
1
gouwudang 2016-02-22 12:15:09 +08:00
楼主对这方面感兴趣欢迎来我司,我们在找 Python 工程师加盟,更好的解决这方面的问题
|
2
yangqi 2016-02-22 12:41:19 +08:00
中间加一层 scraper ,专门爬链接,然后再分配给 worker 抓取页面
|
3
knightdf 2016-02-22 12:46:46 +08:00
我是写了一个基于 redis 的 bloomfilter 来做, master 节点只分配入口 url ,集群子节点只管抓取,管理全部 master 节点来管理,对 子节点定时关机换机器。跑在 AWS 上
|
4
yixiang 2016-02-22 12:48:32 +08:00 1
无经验。随意想到的思路:
多个 worker ,一个 center , center 负责分配任务,爬虫爬完后把结果返回给 center ,只在 center 这里存储整个图和工作怎样分配。 其实类似于…… 一个爬虫+一堆匿名代理,请求一个就换一个代理。 估计实际环境中会遇到许多问题。 |
5
wangleineo OP |
6
wangleineo OP @knightdf 那 bloomfilter 是做什么的?看一个 url 有没有被爬过?
|
7
Kirscheis 2016-02-22 14:05:29 +08:00
这样是否可行?
worker 首先 parse ,之后把抽取的 url 返回给 master ,然后从 master 的 waiting list 领取下一个 request 。 master 维护一个保存着爬过的 url 的库, worker 返回的所有链接用 bloomfilter 快速检查是否爬过,然后把没爬过的加入 waiting list 。 |
8
sohoer 2016-02-22 14:05:37 +08:00
一个 Crawler 负责任务调度,将需要采集网址通过负载均衡的方式分发给其它 Crawler
|
9
knightdf 2016-02-22 15:09:13 +08:00
@wangleineo 你不是要解决 URL 分配的问题么,这样我的子节点就只用接受根节点这一个 URL 任务了
|
10
izoabr 2016-02-22 15:28:18 +08:00
要分是不是得 hadoop 了?
|
11
chinajik 2016-02-22 15:49:45 +08:00
客户机方面:
ip ban 的话就用 ADSL 服务器. Captcha 用 selenium 截图用第三方平台解析 消费端: 走队列建索引, 基本数据传输走 websocket 请求 keepalive 穿透性强 再写些拨号脚本,重启脚本的,自动阀值调控, 多线程就不用讲了。 爬虫对实时性要求高的,基本看被爬的服务器的阀值峰值,基本上核心价值观就是你不影响他线上业务,一定程度的爬虫运维是睁一只眼闭一只眼的... |
12
wangleineo OP @Kirscheis
@knightdf scrapinghub 就是这么做的: https://github.com/scrapinghub/frontera 这个组件的功能就是根据一些策略给 worker 分配爬取任务, worker 爬到新的 url 再提交给 frontera. |
13
knightdf 2016-02-22 16:35:20 +08:00
@wangleineo 对的,这样设计集群靠谱点, slave 只做抓取的任务
|
14
yangqi 2016-02-22 22:28:16 +08:00
@wangleineo scraper 也可以是分布式的啊
|
15
SlipStupig 2016-02-23 00:50:46 +08:00
你如果是遇到被 ban 掉,你解决方案肯定不是去搞分布式,几种方案
1.伪造 x-forward-for 头部去欺骗,不一定能成功 2.去用 http 代理,一些网站会拉黑一些代理 3.用 tor 节点 4.adsl 重新拨号,这个不靠谱, adsl 的 ip 量有限,而且不一定恰好遇到 ip 释放 结论就是,花点钱去买代理吧 |