基于 RabbitMQ 的分布式爬虫

前面我们了解了 Scrapy 如何利用 Redis 实现分布式爬虫,可以注意到,当爬取数量过大时,Redis 占用的内存非常大,因此对于数据去重,我们使用了 Bloom Filter 来进行优化,大幅减少了 Redis 的内存占用。

不过,现在我们似乎依然面临一个问题,爬取队列仍旧是基于 Redis 实现的,那它同样会占据非常大的内存呀!其实在一般情况下,Redis 作为分布式爬取队列是完全够用的。但在数据量比较大。比如爬取上亿级别数据时,Redis 消耗的内存也是比较大的,这时候我们可以考将爬取队列进行迁移。

迁移到哪里呢?仔细想想,爬取队列类似一个消息队列,可以先进先出,先进后出、按优先级进出等,只要能满足类似的需求就可以。现如今,消息队列中间件也有很多,如 RabbitMQ、RocketMQ 等,它们都可以用来做爬取队列的实现。

本节我们就选取目前比较流行的 RabbitMQ 来实现一下 Scrapy 分布式爬虫吧!

准备工作

在本书 4.8 节中,我们已经初步了解了 RabbitMQ 的基本原理和使用方法,如果你还不了解 RabbitMQ 是什么,建议先回看一下前面的基础内容。

在本节开始之前,请确保已经正确安装好了 RabbitMQ 和 Python 的 pika 库,具体的安装说明可以参考本书 4.8 节。

对接 Scrapy

RabbitMQ 就是一个消息队列,那它怎么对接 Scrapy 实现分布式爬取呢?通过 Scrapy-Redis 的源码,我们可以知道 Scrapy-Redis 利用 Redis 实现了一个爬取队列,所以同样的原理,我们可以仿照 Scrapy-Redis 的实现,将 Redis 换成 RabbitMQ。

仿照 Scrapy-Redis 的源码,我们先来解决 RabbitMQ 的连接问题,首先定义一个 connection 对象:

迁移

总结

本节中我们介绍了利用 RabbitMQ 实现分布式爬取的过程,成功将爬取队列由 Redis 更换到了 RabbitMQ 上,解决了 Redis 的内存占用问题。

本节代码参见: https://github.com/Python3WebSpider/ScrapyCompositeDemo/tree/gerapy-rabbitmq ,注意是 gerapy-rabbitmq 分支。

本章的内容到此就结束了。在这一章,我们了解了分布式爬虫的原理,并介绍了 Scrapy 分布式爬虫基于 Redis 的实现以及一些优化方案。有了分布式爬虫的加持,一些超大规模数据量的爬取就可以得到有效解决了。