使用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 <your_spider>

检查一下你的 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 作为任务队列,但是他们存在一些缺陷,我这里简单提出几个问题。

  1. Scrapy-Redis 使用 Redis 的 set 去重,链接数量越大占用的内存就越大,不适合任务数量大的分布式爬虫。
  2. Scrapy-Redis 使用 Redis 的 list 作为队列,很多场景会有任务积压,会导致内存资源消耗过快,比如我们爬取网站 sitemap 时,链接入队的速度远远大于出队。
  3. scrapy-rabbitmq 等 RabbitMQ 的 Scrapy 组件,在创建队列方面,没有提供 RabbitMQ 支持的各种参数,无法控制队列的持久化等参数。
  4. scrapy-rabbitmq 等 rabbitmq 框架的 Scheduler 暂未支持分布式的 dupefilter ,需要使用者自行开发或接入相关组件。
  5. Scrapy-Redis 和 scrapy-rabbitmq 等框架都是侵入式的,如果需要用这些框架开发分布式的爬虫,需要我们修改自己的爬虫代码,通过继承框架的 Spider 类,才能实现分布式功能。

于是,Scrapy-Distributed 框架就在这个时候诞生了,在非侵入式设计下,你只需要通过修改 settings.py 下的配置,框架就可以根据默认配置将你的爬虫分布式化。

为了解决Scrapy-Redis 和 scrapy-rabbitmq 存在的一些痛点,Scrapy-Distributed 做了下面几件事:

  1. 采用了 RedisBloom 的布隆过滤器,内存占用更少。
  2. 支持了 RabbitMQ 队列声明的所有参数配置,可以让 RabbitMQ 队列支持 lazy-mode 模式,将减少内存占用。
  3. RabbitMQ 的队列声明更加灵活,不同爬虫可以使用相同队列配置,也可以使用不同的队列配置。
  4. Scheduler 的设计上支持多个组件的搭配组合,可以单独使用 RedisBloom 的DupeFilter,也可以单独使用 RabbitMQ 的 Scheduler 模块。
  5. 实现了 Scrapy 分布式化的非侵入式设计,只需要修改配置,就可以将普通爬虫分布式化。

目前框架还有很多功能正在添加,感兴趣的小伙伴可以持续关注项目仓库的动向,有什么想法也可以一起讨论。

Scrapy-Distributed 的 github 仓库地址:github.com/Insutanto/s…

Scrapy分布式爬虫,分布式队列和布隆过滤器,一分钟搞定?的更多相关文章

  1. 3分钟搞定SpringBoot+Mybatis+druid多数据源和分布式事务

    文章来自: https://blog.csdn.net/qq_29242877/article/details/79033287 在一些复杂的应用开发中,一个应用可能会涉及到连接多个数据源,所谓多数据 ...

  2. 10分钟搞定 Java 并发队列好吗?好的

    | 好看请赞,养成习惯 你有一个思想,我有一个思想,我们交换后,一个人就有两个思想 If you can NOT explain it simply, you do NOT understand it ...

  3. 爬虫--Scrapy-CrawlSpider&基于CrawlSpide的分布式爬虫

    CrawlSpider 提问:如果想要通过爬虫程序去爬取”糗百“全站数据新闻数据的话,有几种实现方法? 方法一:基于Scrapy框架中的Spider的递归爬取进行实现(Request模块递归回调par ...

  4. 布隆过滤器(Bloom Filter)详解——基于多hash的概率查找思想

    转自:http://www.cnblogs.com/haippy/archive/2012/07/13/2590351.html   布隆过滤器[1](Bloom Filter)是由布隆(Burton ...

  5. [转载] 布隆过滤器(Bloom Filter)详解

    转载自http://www.cnblogs.com/haippy/archive/2012/07/13/2590351.html   布隆过滤器[1](Bloom Filter)是由布隆(Burton ...

  6. 布隆过滤器(Bloom Filter)详解

    直观的说,bloom算法类似一个hash set,用来判断某个元素(key)是否在某个集合中.和一般的hash set不同的是,这个算法无需存储key的值,对于每个key,只需要k个比特位,每个存储一 ...

  7. 布隆过滤器 zz

    布隆过滤器[1](Bloom Filter)是由布隆(Burton Howard Bloom)在1970年提出的.它实际上是由一个很长的二进制向量和一系列随机映射函数组成,布隆过滤器可以用于检索一个元 ...

  8. 布隆过滤器 Bloom Filter 2

    date: 2020-04-01 17:00:00 updated: 2020-04-01 17:00:00 Bloom Filter 布隆过滤器 之前的一版笔记 点此跳转 1. 什么是布隆过滤器 本 ...

  9. BloomFilter(布隆过滤器)

    原文链接:http://blog.csdn.net/qq_38646470/article/details/79431659 1.概念: 如果想判断一个元素是不是在一个集合里,一般想到的是将所有元素保 ...

随机推荐

  1. 深入浅出具有划时代意义的G1垃圾回收器

    G1诞生的背景 Garbage First(简称G1)收集器是垃圾收集器技术发展历史上的里程碑式的成果,它开创了收集器面向局部收集的设计思路和基于Region的内存布局形式.HotSpot开发团队最初 ...

  2. const、define 和 static 的区别

    目录 define.const static define.const 在 C++ 中,const 和 define 都可以用来定义常量.但是这二者之间有很大的区别: define 的作用 用 def ...

  3. ubuntu19.10如何设置固定ip

    $ip a 看见系统中有两块网卡 lo: ...... ens33: ...... #cd /etc/netplan$ls目录下面有文件01-network-manager-all.yaml $sud ...

  4. 2017-18一《电子商务概论》本科作业-商A1551

    第1次作业: 1 2017年双十一新营销方案 2 销售额达1682亿元分析组成及了解猫狗大战 3 破亿店铺举例. 第2次作业: 1.你如何来定义和理解电子商务?电子商务对社会经济带了怎样的影响,企业. ...

  5. spring框架中配置mysql8.0需要注意的地方(转载)

    8.0以后的mysql很强大,但是配置写法出现了不同 主要原因是时区不同,mysql默认用的是国外某个地方的时区,而我们要用的话用使用东八时区,这是中国统一时区. 装载自https://blog.cs ...

  6. nullptr解决了什么问题

    从0到NULL 在C++的世界中字面值0用来表示空指针,所以0可以当作所有指针类型的字面值.为了让语义更明确引入了NULL宏定义: #undef NULL #ifdef __cplusplus #de ...

  7. 【C语言/C++编程学习笔记】你的第一个Windows程序!高级操作~

    什么是windows编程?了解到Windows API 编程.Windows编程.Windows SDK 编程是一个概念.今天我们运用C语言来实现你的第一个真正的Windows程序. windows. ...

  8. 【不知道怎么分类】HDU - 5963 朋友

    题目内容 B君在围观一群男生和一群女生玩游戏,具体来说游戏是这样的: 给出一棵n个节点的树,这棵树的每条边有一个权值,这个权值只可能是0或1. 在一局游戏开始时,会确定一个节点作为根.接下来从女生开始 ...

  9. spring boot:spring security用mysql数据库实现RBAC权限管理(spring boot 2.3.1)

    一,用数据库实现权限管理要注意哪些环节? 1,需要生成spring security中user类的派生类,用来保存用户id和昵称等信息, 避免页面上显示用户昵称时需要查数据库 2,如果需要在页面上显示 ...

  10. scrapy 采集数据存入excel

    # -*- coding: utf-8 -*- # Define your item pipelines here # # Don't forget to add your pipeline to t ...