使用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. Spring Boot+Spring Security+JWT 实现 RESTful Api 认证(一)

    标题 Spring Boot+Spring Security+JWT 实现 RESTful Api 认证(一) 技术 Spring Boot 2.Spring Security 5.JWT 运行环境 ...

  2. JVM 第四篇:可视化 JVM 故障处理工具

    本文内容过于硬核,建议有 Java 相关经验人士阅读. 1. 可视化工具 在 JDK 中为我们提供了大量的 JVM 故障处理工具,都在 JDK 的 bin 目录下: 这其中除了大量的命令行工具以外,还 ...

  3. java 的 callback

    Java 本身没有回调这一说,但是面向对象可以模拟出来. 1. 回调接口对象 ICommand package com.git.Cmder; public interface ICommand { v ...

  4. IdentityServer 3.1.x 迁移到 4.x

    一.前言 IdentityServer4 4.x已经正式发布了,根据官方的 Release Note,3.1.x 到 4.x 的变更也是非常多,今天在将代码迁移到 4.x 遇到了一些问题在此记录下来, ...

  5. python接口测试之excel的操作

    1 用到的第三方库openpyxl,需要在命令窗口中下载安装pip install openpyxl,主要对xlsx格式的excel进行读取和编辑: xlrd库从excel中读取数据,支持xlsx x ...

  6. k8s 命令创建pod

    [root@master kubernetes]# kubectl create deploy ngx-dep --image=nginx:1.14-alpine deployment.apps/ng ...

  7. monolog 日志

    1 安装 composer require monolog/monolog 2 使用 // 创建日志服务 $logger = new Logger('my_logger'); // 定义一个handl ...

  8. linux mount挂载命令

    [root@localhost src]# mount 查询系统中已经挂载的设备 [root@localhost src]# mount -a 依据配置文件 /etc/fstab的内容,自动挂载

  9. Spring源码解析之基础应用(三)

    组合Java配置 在XML中,我们可以使用<import/>标签,在一个XML文件中引入另一个XML文件,在Java类中,我们同样可以在一个配置类中用@Import引入另一个配置类,被引入 ...

  10. 第十二章 Linux三剑客之老三—grep

    一.Linux grep 命令用于查找文件里符合条件的字符串. Linux系统中的grep命令是一种功能强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹配的行打印出来.grep全称是Global ...