当前位置:首页 > 公众号精选 > 21ic电子网
[导读]使用Scrapy开发一个分布式爬虫?你知道最快的方法是什么吗?一分钟真的能 开发好或者修改出 一个分布式爬虫吗? 话不多说,先让我们看看怎么实践,再详细聊聊细节。

1分钟搞定Scrapy分布式爬虫、队列和布隆过滤器


使用Scrapy开发一个分布式爬虫?你知道最快的方法是什么吗?一分钟真的能 开发好或者修改出 一个分布式爬虫吗?

话不多说,先让我们看看怎么实践,再详细聊聊细节。

快速上手

Step 0:

首先安装 Scrapy-Distributed :

pip install scrapy-distributed

如果你没有所需要的运行条件,你可以启动两个 Docker 镜像进行测试 (RabbitMQ 和 RedisBloom):

# pull and run a RabbitMQ container. 
docker run -d --name rabbitmq -p 0.0.0.0:15672:15672 -p 0.0.0.0:5672:5672 rabbitmq:3 
# pull and run a RedisBloom container. 
docker run -d --name redis-redisbloom -p 0.0.0.0:6379:6379 redislabs/rebloom:latest

Step 1 (非必须):

如果你有一个现成的爬虫,可以跳过这个 Step,直接到 Step 2。

创建一个爬虫工程,我这里以一个 sitemap 爬虫为例:

scrapy startproject simple_example

然后修改 spiders 文件夹下的爬虫程序文件:

from scrapy_distributed.spiders.sitemap import SitemapSpider
from scrapy_distributed.queues.amqp import QueueConfig
from scrapy_distributed.dupefilters.redis_bloom import RedisBloomConfig


class MySpider(SitemapSpider):
    name = "example"
    sitemap_urls = ["http://www.people.com.cn/robots.txt"]
    queue_conf: QueueConfig = QueueConfig(
        name="example", durable=True, arguments={"x-queue-mode""lazy""x-max-priority"255}
    )
    redis_bloom_conf: RedisBloomConfig = RedisBloomConfig(key="example:dupefilter")

    def parse(self, response):
        self.logger.info(f"parse response, url: {response.url}")

Step 2:

只需要修改配置文件 settings.py 下的SCHEDULERDUPEFILTER_CLASS 并且添加 RabbitMQ和 Redis 的相关配置,你就可以马上获得一个分布式爬虫,Scrapy-Distributed 会帮你初始化一个默认配置的 RabbitMQ 队列和一个默认配置的 RedisBloom 布隆过滤器。

# 同时集成 RabbitMQ 和 RedisBloom 的 Scheduler
# 如果仅使用 RabbitMQ 的 Scheduler,这里可以填 scrapy_distributed.schedulers.amqp.RabbitScheduler
SCHEDULER = "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"
BLOOM_DUPEFILTER_REDIS_PORT = 6379
# Redis Bloom 的客户端配置,复制即可
REDIS_BLOOM_PARAMS = {
    "redis_cls""redisbloom.client.Client"
}
# 布隆过滤器误判率配置,不写配置的情况下默认为 0.001
BLOOM_DUPEFILTER_ERROR_RATE = 0.001
# 布隆过滤器容量配置,不写配置的情况下默认为 100_0000
BLOOM_DUPEFILTER_CAPACITY = 100_0000

你也可以给你的 Spider 类,增加两个类属性,来初始化你的 RabbitMQ 队列或 RedisBloom 布隆过滤器:

class MySpider(SitemapSpider):
    ......
    # 通过 arguments 参数,可以配置更多参数,这里示例配置了 lazy 模式和优先级最大值
    queue_conf: QueueConfig = QueueConfig(
        name="example", durable=True, arguments={"x-queue-mode""lazy""x-max-priority"255}
    )
    # 通过 key,error_rate,capacity 分别配置布隆过滤器的redis key,误判率,和容量
    redis_bloom_conf: RedisBloomConfig = RedisBloomConfig(key="example:dupefilter", error_rate=0.001, capacity=100_0000)
    ......

Step 3:

scrapy crawl example

检查一下你的 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 的 list 作为队列,很多场景会有任务积压,会导致内存资源消耗过快,比如我们爬取网站 sitemap 时,链接入队的速度远远大于出队。

  • scrapy-rabbitmq 等 RabbitMQ 的 Scrapy 组件,在创建队列方面,没有提供 RabbitMQ 支持的各种参数,无法控制队列的持久化等参数。

  • scrapy-rabbitmq 等 rabbitmq 框架的 Scheduler 暂未支持分布式的 dupefilter ,需要使用者自行开发或接入相关组件。

  • 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 分布式化的非侵入式设计,只需要修改配置,就可以将普通爬虫分布式化。


作者:许臾insutanto
来源:https://insutanto.net/posts/scrapy/

免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!

21ic电子网

扫描二维码,关注更多精彩内容

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

仿真的概念其实使用非常广,最终的含义就是使用可控的手段来模仿真实的情况。在嵌入式系统的设计中,仿真应用的范围主要集中在对程序的仿真上。

关键字: 单片机 仿真器 程序

步进电动机是将电脉冲激励信号转换成相应的角位移或线位移的离散值控制电动机,这种电动机每当输入一个电脉冲就动一步,所以又称脉冲电动机。

关键字: 步进电机 正反转 程序

KeilμVision4是Keil软件公司为8051系列微控制器及其兼容产品设计的集成式软件开发环境。μVision4集成了C51编译器和A51汇编器,其界面类似于Microsoft VS,支持C语言和汇编语言程序的编写...

关键字: 程序 编译 链接

双方各执一词,谁也不退让,吴雄昂的身份成为薛定谔的猫:在Arm公司眼中,他已经被罢免一切职位;在安谋中国声明里,吴仍然一切照常。这种叠加态或许还会持续一段时间,但叠加态应该很快就会塌缩成一个确定结果。同样,安谋中国董事会...

关键字: ARM 中国董事会 程序

除了指令空间,自定义指令对应的程序出入口也有严格限制。自定义指令在使用过程中出现任何错误时,Arm的工具链都能及时对其进行识别、提取,并且进行相应的控制。目前也已经有第三方编译器,可以识别自定义指令集可能会出现的错误。专...

关键字: 指令空间 程序 ARM

如果说一众美国科技公司遵循特朗普命令断供华为,还算某种程度上维护所谓程序正义不得已而为之;那么各路本应对政治保持中立的国际技术标准组织,先后宣布剔除华为成员资格,绝对算助纣为虐;而联邦快递将华为委托寄送目的地为中国的快递...

关键字: 快递 华为 程序

在软件开发过程中,我们希望软件可以运行无误。但是常常事与愿违,程序经常跑飞,或者卡死。原因有很多,有可能是因为软件系统设计的原因,或者外部传感器的失效,再或者是程序的Bug等。为了防止程序在出现问题之后,可以顺利复位和重...

关键字: 软件 程序 传感器

进程是程序的执行过程。程序是静态的,是存在于外存之中的,电脑关机后依然存在。进程是动态的,是存在于内存之中的,是程序的执行过程,电脑关机后就不存在进程了。进程的内容来源于程序,进程的启动过程就是把程序从外存加载到内存的过...

关键字: 程序 静态 操作系统

摘 要:结合车联网高峰论坛上的一些最新观点,对车联网的一些新进展作了介绍。主要包括大数据和云计算在车联网 的应用,车联网的电商化及互联网化趋势。车联网的商业模式需要突破,跨界合作和服务创新是一种有益的尝试。认为只有开放的...

关键字: 车联网 进展 大数据 电商 程序 开放

这几天打算复习下stm32有关的硬件资源,就想着从最开始做起,熟悉下当初所学的知识。学习stm32最初都基本是从流水灯开始的,今天就开始点亮流水灯。

关键字: STM32 程序 编程
关闭
关闭