Scrapy - redis 分布式爬取淘宝商品数据

      上一篇文章我们用Scrapy单机爬取淘宝商品数据,由于CPU、IO和带宽等多重限制,单主机爬虫在爬取大量数据时可用性、稳定性和性能都不是很高。为了提高爬取效率、防止被网站反爬虫策略限制IP等各方面原因我们采取Scrapy分布式爬虫。

Scrapy分布式原理

       打造Scrapy分布式爬虫的关键是调度,因为需要将单机关联起来,我们采用的方式是消息队列。

Scrapy - redis 分布式爬取淘宝商品数据

单机架构,只在本机维护一个爬取队列,Scheduler进行调度,而要实现多台服务器共同爬取数据关键就是共享爬取队列。

Scrapy - redis 分布式爬取淘宝商品数据

重要的是队列通过什么维护?

这里一般我们通过Redis为维护。

Redis,非关系型数据库,Key-Value形式存储,结构灵活。

并且redis是内存中的数据结构存储系统,处理速度快,提供队列集合等多种存储结构,方便队列维护

如何去重?

这里借助redis的集合,redis提供集合数据结构,在redis集合中存储每个request的指纹

在向request队列中加入Request前先验证这个Request的指纹是否已经加入集合中。如果已经存在则不添加到request队列中,如果不存在,则将request加入到队列并将指纹加入集合

如何防止中断?如果某个机器因为特殊原因宕机,如何解决?

这里是做了启动判断,在每台机器的Scrapy启动的时候都会判断当前redis request队列是否为空

如果不为空,则从队列中获取下一个request执行爬取。如果为空则重新开始爬取,第一台丛集执行爬取向队列中添加request

如何实现上述这种架构?

scrapy-redis库为我们提供了上述的这些功能

scrapy-redis改写了Scrapy的调度器,队列等组件,利用他可以方便的实现Scrapy分布式架构

关于scrapy-redis的地址:https://github.com/rmax/scrapy-redis


搭建分布式爬虫

利用上一篇的代码改造成分布式爬虫:https://github.com/zhhaoqin/scrapy/tree/master/taobaoS

修改该settings中的配置信息:

替换scrapy调度器

SCHEDULER = "scrapy_redis.scheduler.Scheduler"

添加去重的class

DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"

共享的爬取队列,这里用需要redis的连接信息

这里的user:pass表示用户名和密码,如果没有则为空就可以

REDIS_URL = 'redis://user:[email protected]:9001'


分布式

将上述更改后的代码拷贝的各个服务器,当然关于数据库这里可以在每个服务器上都安装数据,也可以共用一个数据。这里用每个主机各自的mongodb数据库,当然各个服务器上也不能忘记安装 scrapy, scrapy_redis, pymongo

这样运行各个爬虫程序启动后,在 redis 数据库就可以看到 dupefilter 指纹队列

Scrapy - redis 分布式爬取淘宝商品数据


爬取结果

Scrapy - redis 分布式爬取淘宝商品数据


每台主机的爬取结果都保存到各自的mongodb数据库中

Scrapy - redis 分布式爬取淘宝商品数据

Scrapy - redis 分布式爬取淘宝商品数据


代码地址:https://github.com/zhhaoqin/scrapy/tree/distributed