基于redis的分布式爬虫
问题:
(1)为什么原生的scrapy框架不可以自己实现分布式爬虫?
原因有两个:
(1)因为多台机器上部署的scrapy会各自拥有各自的调度器,这样就使得多台机器无法分配start_urls列表中的url(调度器不能被共享)
(2)多台机器爬取到的数据无法通过同一个管道对数据进行统一的数据持久出存储。(管道不能被共享)
(2)scrapy-redis组件的作用是什么?
它提供了可以被共享的调度器和管道
(3)如何使用scrapy-redis组件来实现分布式爬虫?
其一:基于该组件的RedisSpider类
其二:基于该组件的RedisCrawlSpider类
但是这两种实现分布式爬虫的实现流程是一致的
分布式的实现流程:
1 下载scrapy-redis组件:
pip install scrapy_redis
2 创建工程
3 创建爬虫文件:RedisSpider RedisCrawlSpider
- scrapy genspider -t crawl xxx www.xxx.com
4 对爬虫文件中的相关属性进行修改:
- 导入:from scrapy_redis.spiders import RedisCrawlSpider
- 将爬虫类的父类修改成基于RedisSpider或者RedisCrawlSpider。注意:如果原始爬虫文件是基于Spider的,则应该将父类修改成RedisSpider,如果原始爬虫文件是基于CrawlSpider的,则应该将其父类修改成RedisCrawlSpider
- 注释或者删除start_urls列表,切加入redis_key属性。也就是将起始的URL列表替换成redis_key = 'xxx' (调度器队列的名称)
5 在配置文件中进行配置
-
使用组件中封装好的可以被共享的管道类
ITEM_PIPELINES = { 'scrapy_redis.pipelines.RedisPipeline': 400 }
-
配置调度器(使用组件中封装好的可以被共享的调度器)
增加了一个去重容器类的配置,作用使用Redis的set集合来存储请求的指纹数据,从而实现请求去重的持久化
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
-
使用scrapy_redis组件自己的调度器
SCHEDULER = "scrapy_redis.scheduler.Scheduler"
-
配置调度器是否要持久化,也就是当爬虫结束之后,要不要清空Redis中请求队列和去重指纹的set。如果是True,就表示要持久化存储,就不清空数据,否则清空数据
SCHEDULER_PERSIST = True
指定存储数据中的redis
REDIS_HOST = 'redis服务的ip地址'# 一般写127.0.0.1
REDIS_PORT = 6379
6 在redis数据库的配置文件中修改一些数据
-
取消保护模式:
protected-mode no #表示可以让其他ip操作redis
-
bind绑定:将这一行注释掉 因为只有注释掉了 才能进行分布式
#bind 127.0.0.1 表示可以让其他ip访问redis
启动redis
开启redis服务端:在终端中输入 redis-server
开启redis客户端: 在开启服务端之后 在终端输入 redis-cli
7 执行分布式程序
-
进入到项目下的spiders中
cd 该项目 cd spiders
在spiders目录下 查看你的爬虫文件存不存在
dir
-
在执行此命令
scrapy runspider xxx.py #xxx.py是你的爬虫文件名
8 向调度器队列中扔入一个url
-
在redis-cli执行之后,执行此命令
lpush chouti https://dig.chouti.com/ #这里要注意的是 chouti是 爬虫文件中redis_key = 'chouti'#调度器队列的名称 后面的地址是你要爬取的网站的地址
-
在查看redis中是否有存储到数据
key *