一、Scrapy-redis架构如上图所示,scrapy-redis在scrapy架构上增加了redis,并根据redis的特点扩展了以下组件:1.Scheduler:Scrapy将python原有的collection.deque(双向队列)进行改造,形成自己的Scrapyqueue(https://github.com/scrapy/que...,但是Scrapy的多个spider无法共享队列成为爬取了Scrapyqueue,即Scrapy本身不支持分布式爬取,scrapy-redis的解决方案是将这个Scrapy队列换成redis数据库(也称为redis队列),将要爬取的请求存储在同一个redis-server,让多个spider去同一个数据库读取,在Scrapy中,Scheduler直接和“待爬队列”相关,负责对新的请求进行列操作(加入Scrapy队列)并取出下一个。The请求被抓取(从Scrapy队列中取出)等操作。它根据要爬取的队列的优先级构建一个字典结构,如:{priority0:queue0priority1:queue1priority2:Queue2}然后根据请求中的优先级,决定爬取哪个队列enter,出队时优先级低的先出队。为了管理这个比较高级的队列字典,Scheduler需要提供一系列的方法。但是原来的Scheduler已经不能用了,所以使用了Scrapy-redis的scheduler组件。2.DuplicationFilter在Scrapy中,通过一个集合来实现这个请求去重功能,Scrapy将发送的请求指纹放入一个集合中,取下一个请求的指纹到集合中进行比较。如果集合中存在指纹,则表示请求已发送。如果没有,继续操作。核心权重判断函数的实现如下:defrequest_seen(self,request):#self.request_figerprints是一组指纹fp=self.request_fingerprint(request)#iffpinself.fingerprints这是权重判断的核心操作:returnTrueself.fingerprints.add(fp)ifself.file:self.file.write(fp+os.linesep)#python爬虫全套学习教程请访问:https://item.taobao.com/item.htm?spm=a2oq0.12575281.0.0.4ace1deb9UZJB5&ft=t&id=619117901939scrapy-redis中的去重是通过DuplicationFilter组件实现的,通过redis集合的不重复特性巧妙的实现了DuplicationFilter的去重。scrapy-redis调度器接受来自引擎的请求,将请求的指纹存储在redis集合中,检查是否重复,将不重复的请求推送写入redis请求队列。当引擎请求一个请求(由蜘蛛发送)时,调度器根据优先级从redis请求队列中弹出一个请求返回给引擎,引擎将请求发送给蜘蛛进行处理。3、ItemPipeline引擎将爬取到的Item(Spider返回的)发送给ItemPipeline,scrapy-redisItemPipeline将爬取到的Item存储到redis的items队列中。修改后的ItemPipeline可以方便的根据key从items队列中提取item,从而实现items进程的集群化。4.BaseSpider不再使用scrapy原有的Spider类。重写后的RedisSpider继承了Spider和RedisMixin这两个类。RedisMixin是一个用来从redis中读取url的类。当我们生成Spider继承RedisSpider时,调用setup_redis函数,会连接redis数据库,然后设置信号(signals):一个是spider空闲时的信号,会调用spider_idle函数,和该函数调整schedule_next_request函数,保证蜘蛛一直存活,并抛出DontCloseSpider异常。一个是抓到item时的信号,会调用item_scraped函数,会调用schedule_next_request函数获取下一个请求。2、Scrapy和scrapy-redis的区别Scrapy是一个通用的爬虫框架,但是不支持分布式。Scrapy-redis提供了一些基于redis的组件(componentsonly)。pipinstallscrapy-redisScrapy-redis提供了以下四个组件(components):(四个组件的意思就是这四个模块都要相应修改)SchedulerDuplicationFilterItemPipelineBaseSpider
