基于Redis的三种分布式爬虫策略

前言:

爬虫是偏IO型的任务,分布式爬虫的实现难度比分布式计算和分布式存储简单得多。
个人以为分布式爬虫须要考虑的点主要有下面几个:

  • 爬虫任务的统一调度
  • 爬虫任务的统一去重
  • 存储问题
  • 速度问题
  • 足够“健壮”的情况下实现起来越简单/方便越好
  • 最好支持“断点续爬”功能

Python分布式爬虫比較经常使用的应该是scrapy框架加上Redis内存数据库,中间的调度任务等用scrapy-redis模块实现。
此处简介一下基于Redis的三种分布式策略,事实上它们之间还是非常类似的。仅仅是为适应不同的网络或爬虫环境作了一些调整而已(如有错误欢迎留言拍砖)。


【策略一】

分布式爬虫策略一
Slaver端从Master端拿任务(Request/url/ID)进行数据抓取。在抓取数据的同一时候也生成新任务。并将任务抛给Master。Master端仅仅有一个Redis数据库,负责对Slaver提交的任务进行去重、增加待爬队列。

长处: scrapy-redis默认使用的就是这样的策略,我们实现起来非常easy。由于任务调度等工作scrapy-redis都已经帮我们做好了,我们仅仅须要继承RedisSpider、指定redis_key即可了。
缺点: scrapy-redis调度的任务是Request对象,里面信息量比較大(不仅包括url,还有callback函数、headers等信息)。导致的结果就是会减少爬虫速度、并且会占用Redis大量的存储空间。当然我们能够重写方法实现调度url或者用户ID。


【策略二】

分布式爬虫策略二
这是对策略的一种优化改进:在Master端跑一个程序去生成任务(Request/url/ID)。

Master端负责的是生产任务,并把任务去重、增加到待爬队列。Slaver仅仅管从Master端拿任务去爬。

长处: 将生成任务和抓取数据分开。分工明白。减少了Master和Slaver之间的数据交流;Master端生成任务另一个长处就是:能够非常方便地重写判重策略(当数据量大时优化判重的性能和速度还是非常重要的)。


缺点: 像QQ或者新浪微博这样的站点。发送一个请求,返回的内容里面可能包括几十个待爬的用户ID。即几十个新爬虫任务。但有些站点一个请求仅仅能得到一两个新任务,并且返回的内容里也包括爬虫要抓取的目标信息。假设将生成任务和抓取任务分开反而会减少爬虫抓取效率。

毕竟带宽也是爬虫的一个瓶颈问题,我们要秉着发送尽量少的请求为原则,同一时候也是为了减轻站点server的压力,要做一仅仅有道德的Crawler。

所以,视情况而定。



【策略三】

分布式爬虫策略三
Master中仅仅有一个集合,它仅仅有查询的作用。Slaver在遇到新任务时询问Master此任务是否已爬,假设未爬则增加Slaver自己的待爬队列中。Master把此任务记为已爬。它和策略一比較像,但明显比策略一简单。策略一的简单是由于有scrapy-redis实现了scheduler中间件。它并不适用于非scrapy框架的爬虫。

长处: 实现简单,非scrapy框架的爬虫也适用。Master端压力比較小。Master与Slaver的数据交流也不大。
缺点: “健壮性”不够,须要另外定时保存待爬队列以实现“断点续爬”功能。各Slaver的待爬任务不通用。


结语:

假设把Slaver比作工人,把Master比作工头。策略一就是工人遇到新任务都上报给工头。须要干活的时候就去工头那里领任务;策略二就是工头去找新任务,工人仅仅管从工头那里领任务干活;策略三就是工人遇到新任务时询问工头此任务是否有人做了。没有的话工人就将此任务加到自己的“行程表”。



转载请注明出处,谢谢!(原文链接:http://blog.csdn.net/bone_ace/article/details/50989104

原文地址:https://www.cnblogs.com/yjbjingcha/p/7111928.html