Scrapy 和 scrapy-redis的区别

Scrapy 是一个通用的爬虫框架,但是不支持分布式,Scrapy-redis是为了更方便地实现Scrapy分布式爬取,而提供了一些以redis为基础的组件(仅有组件)。

pip install scrapy-redis

Scrapy-redis提供了下面四种组件(components):(四种组件意味着这四个模块都要做相应的修改)

  • Scheduler
  • Duplication Filter
  • Item Pipeline
  • Base Spider

scrapy-redis架构

Scheduler

Scrapy改造了python本来的collection.deque(双向队列)形成了自己的Scrapy queue(https://github.com/scrapy/queuelib/blob/master/queuelib/queue.py)),但是Scrapy多个spider不能共享待爬取队列Scrapy queue, 即Scrapy本身不支持爬虫分布式,scrapy-redis 的解决是把这个Scrapy queue换成redis数据库(也是指redis队列),从同一个redis-server存放要爬取的request,便能让多个spider去同一个数据库里读取。

Scrapy中跟“待爬队列”直接相关的就是调度器Scheduler,它负责对新的request进行入列操作(加入Scrapy queue),取出下一个要爬取的request(从Scrapy queue中取出)等操作。它把待爬队列按照优先级建立了一个字典结构,比如:

    {
优先级0 : 队列0
优先级1 : 队列1
优先级2 : 队列2
}

然后根据request中的优先级,来决定该入哪个队列,出列时则按优先级较小的优先出列。为了管理这个比较高级的队列字典,Scheduler需要提供一系列的方法。但是原来的Scheduler已经无法使用,所以使用Scrapy-redis的scheduler组件。

Duplication Filter

Scrapy中用集合实现这个request去重功能,Scrapy中把已经发送的request指纹放入到一个集合中,把下一个request的指纹拿到集合中比对,如果该指纹存在于集合中,说明这个request发送过了,如果没有则继续操作。这个核心的判重功能是这样实现的:

    def request_seen(self, request):
# self.request_figerprints就是一个指纹集合
fp = self.request_fingerprint(request) # 这就是判重的核心操作
if fp in self.fingerprints:
return True
self.fingerprints.add(fp)
if self.file:
self.file.write(fp + os.linesep)

在scrapy-redis中去重是由Duplication Filter组件来实现的,它通过redis的set 不重复的特性,巧妙的实现了Duplication Filter去重。scrapy-redis调度器从引擎接受request,将request的指纹存⼊redis的set检查是否重复,并将不重复的request push写⼊redis的 request queue。

引擎请求request(Spider发出的)时,调度器从redis的request queue队列⾥里根据优先级pop 出⼀个request 返回给引擎,引擎将此request发给spider处理。

Item Pipeline

引擎将(Spider返回的)爬取到的Item给Item Pipeline,scrapy-redis 的Item Pipeline将爬取到的 Item 存⼊redis的 items queue。

修改过Item Pipeline可以很方便的根据 key 从 items queue 提取item,从⽽实现 items processes集群。

Base Spider

不在使用scrapy原有的Spider类,重写的RedisSpider继承了Spider和RedisMixin这两个类,RedisMixin是用来从redis读取url的类。

当我们生成一个Spider继承RedisSpider时,调用setup_redis函数,这个函数会去连接redis数据库,然后会设置signals(信号):

  • 一个是当spider空闲时候的signal,会调用spider_idle函数,这个函数调用schedule_next_request函数,保证spider是一直活着的状态,并且抛出DontCloseSpider异常。

  • 一个是当抓到一个item时的signal,会调用item_scraped函数,这个函数会调用schedule_next_request函数,获取下一个request。

scrapy基础知识之 Scrapy 和 scrapy-redis的区别:的更多相关文章

  1. 0.Python 爬虫之Scrapy入门实践指南(Scrapy基础知识)

    目录 0.0.Scrapy基础 0.1.Scrapy 框架图 0.2.Scrapy主要包括了以下组件: 0.3.Scrapy简单示例如下: 0.4.Scrapy运行流程如下: 0.5.还有什么? 0. ...

  2. scrapy基础知识之 CrawlSpiders爬取lagou招聘保存在mysql(分布式):

    items.py import scrapy class LagouItem(scrapy.Item): # define the fields for your item here like: # ...

  3. scrapy基础知识之 CrawlSpiders(爬取腾讯校内招聘):

    import scrapyfrom scrapy.spider import CrawlSpider,Rulefrom scrapy.linkextractors import LinkExtract ...

  4. scrapy基础知识之 处理Redis里的数据:

    数据爬回来了,但是放在Redis里没有处理.之前我们配置文件里面没有定制自己的ITEM_PIPELINES,而是使用了RedisPipeline,所以现在这些数据都被保存在redis的xx:items ...

  5. scrapy基础知识之 RedisCrawlSpider:

    这个RedisCrawlSpider类爬虫继承了RedisCrawlSpider,能够支持分布式的抓取.因为采用的是crawlSpider,所以需要遵守Rule规则,以及callback不能写pars ...

  6. scrapy基础知识之 关于爬虫部分一些建议:

    1.尽量减少请求次数,能抓列表页就不抓详情页,减轻服务器压力,程序员都是混口饭吃不容易. 2.不要只看 Web 网站,还有手机 App 和 H5,这样的反爬虫措施一般比较少. 3.实际应用时候,一般防 ...

  7. scrapy基础知识之 pycharm 调试小技巧:

    在项目根目录下新建main.py文件,用于调试 from scrapy.cmdline import executeexecute(["scrapy","crawl&qu ...

  8. scrapy基础知识之 scrapy 三种模拟登录策略:

    注意:模拟登陆时,必须保证settings.py里的 COOKIES_ENABLED (Cookies中间件) 处于开启状态 COOKIES_ENABLED = True或 # COOKIES_ENA ...

  9. scrapy基础知识之下载中间件使用案例:

    1. 创建middlewares.py文件. Scrapy代理IP.Uesr-Agent的切换都是通过DOWNLOADER_MIDDLEWARES进行控制,我们在settings.py同级目录下创建m ...

随机推荐

  1. 用户控件(UserControl)

    简介 "用户控件"继承自UserControl,而UserControl继承自ContentControl,也就是内容控件UserControl和Window是一个层次上的,都有x ...

  2. UNITY VR 视频/图片 开发心得(二)

    上回说到了普通的全景图片,这回讲真正的VR. 由于这种图片分为两部分,所以我们需要两个Camera对象以及两个球体.首先新建一个Camera对象,并将其命名为RightEye(其它名字也无妨,只要你自 ...

  3. 将QuickReport报表保存为图片(使用TMetaFile和TMetafileCanvas)

    //将报表第iPageNo页存为BMP文件     procedure   ReportSaveToBMPFile(sFileName   :string;   iPageNo   :integer) ...

  4. .NET VS 自定义新建代码文件模板

    参考:http://www.cnblogs.com/fightingtong/p/3765914.html 在VS中新建文件时,可使用模板在文件中生成指定内容.只需要把IDE安装目录下的模板进行修改保 ...

  5. Debian下编译安装驱动模块

    在Linux下,我们常有需要自己来编译安装驱动模块的情况,例如要安装显卡驱动,要安装无线驱动,有的时候某个程序的安装使用与需要安装相应的驱动模块.Debian Linux下的生活本已十分简单,使用ap ...

  6. 什么是BSON?

    BSON( Binary Serialized Document Format) 是一种二进制形式的存储格式,采用了类似于 C 语言结构体的名称.对表示方法,支持内嵌的文档对象和数组对象,具有轻量性. ...

  7. mysql练习(一)

    练习一 创建表,并插入相关数据 CREATE TABLE email ( ID INT NOT NULL PRIMARY KEY, Email VARCHAR() ) INSERT INTO emai ...

  8. Qt 开发WEB Services客户端代码(使用gSoap)

    1.   首先下载gSoap开发包 http://sourceforge.net/projects/gsoap2  目录包含 wsdl2h.exe( 由wsdl生成接口头文件C/C++格式的头文件 ) ...

  9. c# 文本超长截断

    根据控件大小进行截断 private void SetStringTruncat(Static.LabelEx lbl) { string oldStr = lbl.Text; if (string. ...

  10. 解决vuejs 创建数据后设置对象的属性实现不了双向绑定问题

    抛出踩坑:vue创建后的数据,自定义设置对象的属性,实现不了双向绑定 当业务场景,需要在请求接口数据新增自定义的属性 let foodList = [ {title: '回锅肉', price: 99 ...