三种分布式爬虫策略:
(1)Slaver端从Master端拿任务(Request/url/ID)进行数据抓取,在抓取数据的同时也生成新任务,并将任务分配给Master端。
Master端只有一个Redis数据库,负责对Slaver提交的任务进行去重、加入待爬队列。
优点
scrapy-redis默认使用的就是这种策略,我们实现起来很简单,因为任务调度等工作scrapy-redis都已经帮我们做好了,我们只需要继承RedisSpider、指定redis_key即可。
缺点
scrapy-redis调度的任务是Request对象,里面信息量比较大(不仅包含URL,还有callback函数、headers等信息),会降低爬虫速度,而且会占用Redis大量的存储空间。当然,我们可以重写方法实现调度URL或者用户ID。
(2)Master端跑一个程序去生成任务(Request/url/ID)。
Master端负责的是生产任务,并把任务去重,加入到待爬队列中。Slaver端只负责从Master端获取任务进行爬取。
优点
将生成任务和抓取数据分开,分工明确,减少了Master和Slaver端之间的数据交流;Master端生成任务还有一个好处,那就是可以便捷地重写判重策略(当数据量大时优化判重的性能和速度还是很重要的)。
缺点
像QQ或者新浪微博这种网站,发送一个请求,返回的内容里面可能包含几十个待爬的用户ID,即几十个新爬虫任务。但有些网站一个请求只能得到一两个新任务,并且返回的内容里也包含爬虫要抓取的目标信息,如果将生成任务和抓取任务分开反而会降低爬虫抓取效率,毕竟带宽也是爬虫的一个瓶颈问题。我们要秉着发送尽量少的请求为原则,同时也是为了减轻网站服务器的压力,要做一只有道德的Crawler。所以,视情况而定。
(3)Master中只有一个集合,它只有查询的作用。Slaver在遇到新任务时询问Master此任务是否已爬,如果未爬则加入Slaver自己的待爬队列中,Master把此任务记为已爬。它和策略一比较像,但明显比策略一简单。策略一的简单是因为有Scrapy-redis实现了scheduler中间件,它并不适用于非Scrapy框架的爬虫。
优点
实现简单,非Scrapy框架的爬虫也适用。Master端压力比较小,Master与Slaver的数据交流也不大。
缺点
“健壮性”不够,需要另外定时保存待爬队列以实现“断点续爬”功能。各Slaver的待爬任务不通用。
如果把Slaver比作工人,把Master比作工头。
策略一就是工人遇到新任务都上报给工头,需要干活的时候就去工头那里领任务;
策略二就是工头去找新任务,工人只管从工头那里领任务干活;
策略三就是工人遇到新任务时询问工头此任务是否有人做了,没有的话工人就将此任务加到自己的“行程表”。