使用Scrapy开发分布式爬虫?你知道最快的方法是什么吗?一个分布式爬虫能否在一分钟内开发或修改?话不多说,先看看如何实践,再详细说说细节。快速启动第0步:首先安装Scrapy-Distributed:pipinstallscrapy-distributed如果你不具备所需的运行条件,可以启动两个Docker镜像进行测试(RabbitMQ和RedisBloom):#pullandrunaRabbitMQcontainer.dockerrun-d--namerabbitmq-p0.0.0.0:15672:15672-p0.0.0.0:5672:5672rabbitmq:3#pullandrunaRedisBloomcontainer.dockerrun-d--nameredis-redisbloom-p0.0.0.0:6379:6379redislabs/rebloom:latestStep1(不需要):如果你有现成的爬虫,可以跳过这一步,直接进入第二步。创建一个爬虫工程,我这里以一个sitemap爬虫为例:scrapystartprojectsimple_example然后修改spiders文件夹下的爬虫程序文件:fromscrapy_distributed.spiders.sitemapimportSitemapSpiderfromscrapy_distributed.queues.amqpimportQueueConfigfromscrapy_distributed.dupefilters.redis_bloomimportRedisBloomConfigclassMySpider(SitemapSpider):name="example"sitemap_urls=["http://www.people.com.cn/robots.txt"]queue_conf:QueueConfigQueueConfig=QueueConfig(name="example",durable=True,arguments={"x-queue-mode":"lazy","x-max-priority":255})redis_bloom_conf:RedisBloomConfigRedisBloomConfig=RedisBloomConfig(key="example:dupefilter")defparse(self,response):self.logger.info(f"parseresponse,url:{response.url}")Step2:JustmodifytheSCHEDULER,DUPEFILTER_CLASSundertheconfigurationfilesettings.pyandaddtherelevantconfigurationofRabbitMQandRedis,youcangetadistributedcrawlerimmediately,Scrapy-DistributedwillhelpyouinitializeaRabbitMQqueueandARedisBloombloomfilterconfiguredbydefault.#同时集成RabbitMQ和RedisBloom的Scheduler#如果仅使用RabbitMQ的Scheduler,这里可以填scrapy_distributed.schedulers.amqp.RabbitSchedulerSCHEDULER="scrapy_distributed.schedulers.DistributedScheduler"SCHEDULER_QUEUE_CLASS="scrapy_distributed.queues.amqp.RabbitQueue"RABBITMQ_CONNECTION_PARAMETERS="amqp://guest:guest@localhost:5672/example/?heartbeat=0"DUPEFILTER_CLASS="scrapy_distributed.dupefilters.redis_bloom.RedisBloomDupeFilter"BLOOM_DUPEFILTER_REDIS_URL="redis://:@localhost:6379/0"BLOOM_DUPEFILTER_REDIS_HOST="localhost"BLOOM379FIL#RedisBloom的client配置,直接复制过来REDIS_BLOOM_PARAMS={"redis_cls":"redisbloom.client.Client"}#Bloomfilter误判率配置,如果不写配置,默认0.001BLOOM_DUPEFILTER_ERROR_RATE=0.001#clothlongfilter容量配置,不写配置的话默认是100_0000BLOOM_DUPEFILTER_CAPACITY=100_0000。你也可以在你的Spider类中添加两个类属性来初始化你的RabbitMQ队列或者RedisBloom布隆过滤器:classMySpider(SitemapSpider):......#通过arguments参数,你可以配置更多的参数。这是配置惰性模式和优先级的示例最大级别queue_conf:QueueConfigQueueConfig=QueueConfig(name="example",durable=True,arguments={"x-queue-mode":"lazy","x-max-priority":255})#passkey,error_rate,capacity分别配置rediskey,误报率,布隆过滤器的容量redis_bloom_conf:RedisBloomConfigRedisBloomConfig=RedisBloomConfig(key="example:dupefilter",error_rate=0.001,capacity=100_0000)...第三步:scrapycrawlexamplecheck检查你的RabbitMQ队列和RedisBloom过滤器,它们是否正常运行?可以看出,在Scrapy-Distributed的支持下,我们只需要修改配置文件就可以将普通的爬虫修改为支持RabbitMQ队列和RedisBloom布隆过滤器的分布式爬虫。在RabbitMQ和RedisBloom环境下,修改配置时间只有一分钟。关于Scrapy-Distributed目前Scrapy-Distributed主要是指Scrapy-Redis和scrapy-rabbitmq这两个库。如果你有使用过Scrapy的经验,你可能知道Scrapy-Redis这个库,可以快速做分布式爬虫。如果你尝试过使用RabbitMQ作为爬虫的任务队列,你可能已经看过scrapy-rabbitmq这个项目。诚然,Scrapy-Redis已经很方便了,scrapy-rabbitmq也可以将RabbitMQ实现为任务队列,但是它们都有一些缺陷。这里我简单问几个问题。Scrapy-Redis利用Redis的set去重。链接数越大,占用的内存就越多。不适合任务量大的分布式爬虫。Scrapy-Redis使用Redis的列表作为队列。很多场景下会出现任务积压,导致内存资源消耗过大。例如,我们在爬取网站站点地图时,链接入队的速度要比出队快很多。RabbitMQ的Scrapy组件如scrapy-rabbitmq在创建队列时没有提供RabbitMQ支持的各种参数,无法控制队列持久化等参数。scrapy-rabbitmq等rabbitmq框架的Scheduler暂不支持分布式dupefilters,需要用户自行开发或接入相关组件。Scrapy-Redis和scrapy-rabbitmq等框架具有侵入性。如果需要使用这些框架开发分布式爬虫,需要修改自己的爬虫代码,继承框架的Spider类实现分布式功能。因此,Scrapy-Distributed框架就在这个时候诞生了。在非侵入式设计下,你只需要修改settings.py下的配置,框架就会按照默认的配置分发你的爬虫。为了解决Scrapy-Redis和scrapy-rabbitmq的一些痛点,Scrapy-Distributed做了以下几件事:采用了RedisBloom的布隆过滤器,占用内存更少。支持RabbitMQ队列声明的所有参数配置,让RabbitMQ队列支持lazy-mode模式,减少内存占用。RabbitMQ的队列声明更加灵活。不同的爬虫可以使用相同的队列配置或不同的队列配置。Scheduler旨在支持多个组件的组合。可以单独使用RedisBloom的DupeFilter,也可以单独使用RabbitMQ的Scheduler模块。实现了Scrapy分布式的非侵入式设计,普通爬虫只需要修改配置即可进行分布式。目前框架中还有很多功能正在添加中。有兴趣的小伙伴可以持续关注项目仓库的动向,有什么想法一起探讨。
