Scrapy + Scrapy-Redis 组件实现的分布式。
概述
什么是分布式爬虫
- 需要搭建一个由n台电脑组成的机群,然后在每一台电脑中执行同一组程序,让其对同一网络资源进行联合且分布的数据爬取。
原生Scrapy无法实现分布式的原因
- 原生Scrapy中调度器不可以被共享- 每一台机器都拥有一个调度器,如果一个机群共享一个调度器就可以了。
 
- 原生Scrapy中管道不可以被共享- 每一台机器都拥有自己的管道,如果把Item发送到同一个管道就可以了。
 
Scrapy_redis组件的作用是什么?
- 提供可以被共享的管道和调度器
分布式的实现流程
实现分布式的重点在于配置
- 环境的安装 - pip install scrapy-redis
 
- 创建工程 - 基于Spider: scrapy genspider crawl spiderName
- 基于CrawlSpider: scrapy genspider -t crawl spiderName
 
- 基于Spider: 
- cd 工程 
- 创建爬虫文件 - 基于Spider
- 基于CrawlSpider
 
- 修改爬虫文件: - 导包:- from scrapy_redis.spiders import RedisCrawlSpider基于 CrawlSpider 爬虫文件
- from scrapy_redis.spiders import RedisSpider基于Spider爬虫文件
 
- 将父类修改为 RedisCrawlSpider 或 RedisSpider
- 删除 allowed_domains 和 start_urls
- 添加 redis_key = ‘队列名称’ :可被共享的调度器队列的名称,向这个队列中放入起始url
- 根据常规形式编写爬虫文件后续的代码
 
- 导包:
- 修改settings配置 - 指定管道 - 1 
 2
 3- ITEM_PIPELINES = { 
 'scrapy_redis.pipelines.RedisPipeline': 400
 }
 
- 指定调度器 - 1 
 2
 3
 4
 5
 6- # 增加了一个去重容器类的配置, 作用使用Redis的set集合来存储请求的指纹数据, 从而实现请求去重的持久化 
 DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
 # 使用scrapy-redis组件自己的调度器
 SCHEDULER = "scrapy_redis.scheduler.Scheduler"
 # 配置调度器是否要持久化, 也就是当爬虫结束了, 要不要清空Redis中请求队列和去重指纹的set。如果是True, 就表示要持久化存储, 就不清空数据, 否则清空数据
 SCHEDULER_PERSIST = True
- 指定redis数据库 - 1 
 2- REDIS_HOST = '192.168.13.254' 
 REDIS_PORT = 6379
- 修改redis的配置文件 - 关闭默认绑定- 56行 注释 bind 127.0.0.1
 
- 关闭保护模式- 75行 protected-mode no
- 这样就可以写数据了
 
 
- 关闭默认绑定
- 启动redis的服务端(携带配置文件)和客户端 - redis-server.exe redis.windows.conf
 
- 启动分布式的程序: - 启动之后才会有调度器对象和队列
- scrapy runspider xxx.py
- 启动后在等起始url
 
- 向调度器的队列中扔入一个起始的url - 队列是存在于redis中
- redis的客户端中:lpush sun www.xxx.com
 
- 在redis中就可以查看爬取到的数据 
例子
使用Scrapy + Scrapy-redis 组件实现的分布式爬取(阳光热线问政平台的投诉帖子)的主题、状态和详细内容
地址为:http://wz.sun0769.com/html/top/reply.shtml
①
scrapy startproject fbsPro 创建基于fbsPro的工程
scrapy genspider -t crawl fbs 域名 创建名为fbs的spider文件
| 1 | # fbs.py | 
②
定义Item
| 1 | # items.py | 
③
配置settings.py
| 1 | #指定管道 | 

