分布式爬虫概述
分布式爬虫,是一种能够将爬虫效率发挥到极致的爬虫方法。
实现方式:scrapy + redis(完整说法是 scrapy 结合着 scrapy-redis 组件)
原生的 scrapy 框架是无法实现分布式的。
什么是是分布式?
- 分布式就是搭建一个分布式的机群,然后让机群中的每一台电脑执行同一组程序,让其对同一组资源
进行联合且分布的数据爬取。
为什么原生的 scrapy 框架无法实现分布式?
- 调度器无法被分布式机群共享
- 管道无法分布式机群被共享
如何实现分布式?
- 使用scrapy-redis组件即可
scrapy-redis 组件的作用是,可以给原生的 scrapy 框架提供共享的管道和调度器。
scrapy-redis 的安装:
1 | pip install scrapy-redis |
分布式爬虫的实现流程
修改爬虫文件
导包方式:
1 | from scrapy_redis.spiders import RedisCrawlSpider |
然后修改当前爬虫类的父类为 RedisCrawlSpider,将 start_url 替换成 redis_keys 的属性,属性值为任意字符串,比如:
1 | from scrapy.linkextractors import LinkExtractor |
redis_key = 'xxx'
表示的是可以被共享的调度器队列的名称,最终是需要将起始的 url 手动放置到 redis_key 表示的队列中。
剩下的,就跟正常解析数据一样了。
配置 settings.py
文件
指定调度器。增加一个去重容器类的配置,作用是使用 Redis 的 set 集合来存储请求的指纹数据,从而实现请求去重的持久化。
1 | DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter" |
使用 scrapy-redis 组件自己的调度器。
1 | SCHEDULER = "scrapy_redis.scheduler.Scheduler" |
配置调度器是否要持久化。也就是当爬虫结束了,要不要清空 Redis 中请求队列和去重指纹的 set。如果是 True, 就表示要持久化存储,就不清空数据,否则清空数据。
1 | SCHEDULER_PERSIST = True |
指定管道。
1 | ITEM_PIPELINES = { |
特点:该种管道只可以将 item 写入 redis。
指定 redis。
1 | REDIS_HOST = 'redis服务的ip地址' |
配置 redis 的配置文件
Windows 中是 redis 安装目录下的 redis.window.conf
文件。
解除默认绑定,注释掉第 56 行的绑定 IP 的代码
1 | #bind 127.0.0.1 |
关闭保护模式,将第 75 行的 protected-mode 设置成 no
1 | protected-mode no |
启动 redis 服务和客户端
进入 redis 安装路径,执行命令启动 redis。
执行 scrapy 工程
1 | scrapy crawl fbs |
注意,执行 scrapy 工程时,不要在配置文件中加入 LOG_LEVEL。我们需要分析这些日志信息。
工程启动后,程序会停留在 listening 位置,等待起始的 url 加入。
向 redis_key 表示的队列中添加起始 url
需要在 redis 的客户端执行如下指令(调度器队列是存在于 redis 中):
1 | lpush sunQueue http://wz.sun0769.com/political/index/politicsNewest?id=1&page=1 |
分布式爬虫实例
需求:使用分布式爬虫爬取阳光问政平台全站的问政标题和状态
网址 url:http://wz.sun0769.com/political/index/politicsNewest?id=1&page=1
分析:分布式爬虫和普通爬虫的核心数据解析代码是一致的,只需要稍加修改,再进行一些配置,即可实现分布式。
爬虫源文件的写法:
1 | from scrapy.linkextractors import LinkExtractor |
然后按照前面所说的,配置 settings.py 即可。