基于scrapy-redis两种形式的分布式爬虫
基于scrapy-redis两种形式的分布式爬虫
redis分布式部署
scrapy框架是否可以自己实现分布式?
不可以。原因有二
- 因为多台机器上部署的scrapy会各自拥有各自的调度器,这样就使得多台机器无法分配start_urls列表中的url。(多台机器无法共享同一个调度器)
- 多台机器爬取到的数据无法通过同一个管道对数据进行统一的数据持久出存储。(多台机器无法共享同一个管道)
基于scrapy-redis组件的分布式爬虫
scrapy-redis组件中为我们封装好了可以被多台机器共享的调度器和管道,我们可以直接使用并实现分布式数据爬取。
实现方式:
- 基于该组件的RedisSpider类
- 基于该组件的RedisCrawlSpider类
分布式实现流程
上述两种不同方式的分布式实现流程是统一的
-
下载scrapy-redis组件,
pip install scrapy_redis
-
导包,
from scrapy_redis.spiders import RedisCrawlSpider,RedisSpider
-
修改spider爬虫文件
- 将爬虫类的父类修改成
RedisCrawlSpider
(若原来继承于CrawlSpider
)或RedisSpider
(若原来继承于Spider
) - 删除
allowed_domains
和start_urls
这两个属性 - 添加一个新属性:
redis_key = 'xxx' # 调度器队列的名称
- 将爬虫类的父类修改成
-
配置使用指定的调度器和管道(在配置文件中增加如下配置)
# 增加了一个去重容器类的配置, 使用Redis的set集合来存储请求的指纹数据, 从而实现请求去重的持久化 DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter" # 使用scrapy-redis组件自己的调度器 SCHEDULER = "scrapy_redis.scheduler.Scheduler" # 配置调度器是否要持久化, 也就是当爬虫结束了, 要不要清空Redis中请求队列和去重指纹的set。如果是True, 就表示要持久化存储, 就不清空数据, 否则清空数据 SCHEDULER_PERSIST = True # 开启使用scrapy-redis组件中封装好的管道 ITEM_PIPELINES = { 'scrapy_redis.pipelines.RedisPipeline': 400 }
-
在配置文件中指定持久化存储对应redis的服务器:
REDIS_HOST = '127.0.0.1' REDIS_PORT = 6379 REDIS_ENCODING = 'utf-8' REDIS_PARAMS = {'password': '123456'}
-
修改redis配置:(redis.windows.conf)
# bind 127.0.0.1 # 注释该行,表示可以让其他ip访问redis protected-mode no # 将yes该为no,关闭保护模式,表示可以让其他ip操作redis
-
开启redis的服务端和客户端
redis-server 配置文件
redis-cli
-
运行工程
scrapy runspider spiderFilePath
-
向调度器的队列中仍入一个起始的url
- 在redis的客户端执行:
lpush xxx http://www.xxx.com
- 在redis的客户端执行: