scrapy_redis
一:scrapy_redis 的概念和作用
简单的说 分布式就是不同的节点(服务器,ip不同)共同完成一个任务
2. scrapy_redis的概念
scrapy_redis是scrapy框架的基于redis的分布式组件
3. scrapy_redis的作用
Scrapy_redis在scrapy的基础上实现了更多,更强大的功能,具体体现在:
通过持久化请求队列和请求的指纹集合来实现:
-
断点续爬
-
分布式快速抓取
-
在scrapy_redis中,所有的待抓取的request对象和去重的request对象指纹都存在所有的服务器公用的redis中
-
所有的服务器中的scrapy进程公用同一个redis中的request对象的队列
-
所有的request对象存入redis前,都会通过该redis中的request指纹集合进行判断,之前是否已经存入过
-
在默认情况下所有的数据会保存在redis中
具体流程如下:

二:
-
clone github scrapy-redis源码文件
git clone https://github.com/rolando/scrapy-redis.git -
研究项目自带的demo
mv scrapy-redis/example-project ~/scrapyredis-project
在domz爬虫文件中,实现方式就是之前的crawlspider类型的爬虫
from scrapy.linkextractors import LinkExtractor from scrapy.spiders import CrawlSpider, Rule class DmozSpider(CrawlSpider): """Follow categories and extract links.""" name = 'dmoz' allowed_domains = ['dmoz-odp.org'] start_urls = ['http://www.dmoz-odp.org/'] rules = [ Rule(LinkExtractor( restrict_css=('.top-cat', '.sub-cat', '.cat-item') ), callback='parse_directory', follow=True), ] def parse_directory(self, response): for div in response.css('.title-and-desc'): yield { 'name': div.css('.site-title::text').extract_first(), 'description': div.css('.site-descr::text').extract_first().strip(), 'link': div.css('a::attr(href)').extract_first(), }
#设置重复重复过滤器的模块
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
#设置调度器,scrapy_redis中的调度器具备与数据库的交互功能 SCHEDULER = "scrapy_redis.scheduler.Scheduler"
#设置当爬虫结束的时候是否保持redis数据库中的去重集合与任务队列
SCHEDULER_PERSIST = True ITEM_PIPELINES = { 'example.pipelines.ExamplePipeline': 300,
#当开启该管道,该管道会把数据存到redis数据库中 'scrapy_redis.pipelines.RedisPipeline': 400, }
REDIS_URL = "redis://127.0.0.1:6379" #或者使用下面的方式 # REDIS_HOST = "127.0.0.1" # REDIS_PORT = 6379
2:我们执行domz的爬虫,会发现redis中多了一下三个键:

3:继续执行程序,会发现程序在前一次的基础之上继续往后执行,
我们从settings.py中的三个配置来进行分析分别是:
-
RedisPipeline # 管道类
-
RFPDupeFilter # 指纹去重类
-
Scheduler # 调度器类
-
SCHEDULER_PERSIST # 是否持久化请求队列和指纹集合
4.1 Scrapy_redis之RedisPipeline
RedisPipeline中观察process_item,进行数据的保存,存入了redis中
1:配置项

2:查找位置

3:原理

RFPDupeFilter 实现了对request对象的加密
1:位置

2:源码分析

scrapy_redis调度器的实现了决定什么时候把request对象加入带抓取的队列,同时把请求过的request对象过滤掉

5.1 分析demo中代码
打开example-project项目中的myspider_redis.py文件
通过观察代码:
-
继承自父类为RedisSpider
-
增加了一个redis_key的键,没有start_urls,因为分布式中,如果每台电脑都请求一次start_url就会重复
-
多了
__init__方法,该方法不是必须的,可以手动指定allow_domains -
启动方法:
-
在每个节点正确的目录下执行
scrapy crawl 爬虫名,使该节点的scrapy_redis爬虫程序就位 -
在共用的redis中
lpush redis_key 'start_url',使全部节点真正的开始运行
-
-
settings.py中关键的配置
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter" SCHEDULER = "scrapy_redis.scheduler.Scheduler" SCHEDULER_PERSIST = True ITEM_PIPELINES = { 'example.pipelines.ExamplePipeline': 300, 'scrapy_redis.pipelines.RedisPipeline': 400, } REDIS_URL = "redis://127.0.0.1:6379"
5.2 动手实现分布式爬虫
改写tencent爬虫为分布式爬虫
注意:启动方式发生改变
5.3编写流程

浙公网安备 33010602011771号