文档章节

scrapy-redis 和 scrapy 有什么区别?

Airship
 Airship
发布于 2017/06/30 08:58
字数 1793
阅读 31
收藏 0

scrapy-redis 和 scrapy 有什么区别?

刚刚接触scrapy,想让scrapy实现分布式爬取,发现还有个东西叫做scrapy-redis,请问二者却别是什么

作者:知乎用户
链接:https://www.zhihu.com/question/32302268/answer/55724369
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

一时兴起写了篇回复,能给大家解决一点小问题,十分高兴。但偶尔被误认为是大牛,诚惶诚恐。
只是当初一点小爱好而已,大牛实在是不敢当。

另外要对私信给我请求帮助的朋友说声抱歉,我已经离开技术岗位很长时间了,手头上早已没有了编程的环境,加上目前工作太多,对大家的问题也是有心无力(我这人太怂,也不敢给大家随便丢个回复)。

最后祝大家学习爬虫的路上一帆风顺~(虽然不大可能,不过加油吧)

 

以下是正文
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
不妖自来~
我刚刚接触scrapy的时候,也看过这个项目,奈何对scrapy本身就不怎么熟悉,所以当时怎么也想不明白,直到后来开始看scrapy 的源代码,才渐渐明白。这里提一下我的看法,水平有限,不敢保证完全正确,欢迎指正。

一、scrapy和scrapy-redis的主要区别在哪里?
个人认为,scrapy和scrapy-redis不应该讨论区别。

scrapy 是一个通用的爬虫框架,其功能比较完善,可以帮你迅速的写一个简单爬虫,并且跑起来。scrapy-redis是为了更方便地实现scrapy分布式爬取,而提供了一些以redis为基础的组件(注意,scrapy-redis只是一些组件,而不是一个完整的框架)。你可以这么认为,scrapy是一工厂,能够出产你要的spider。而scrapy-redis是其他厂商为了帮助scrapy工厂更好的实现某些功能而制造了一些设备,用于替换scrapy工厂的原设备。
所以要想跑分布式,先让scrapy工厂搭建起来,再用scrapy-redis设备去更换scrapy的某些设备。

那么这些scrapy-redis组件有什么突出特点呢?他们使用了redis数据库来替换scrapy原本使用的队列结构(deque),换了数据结构,那么相应的操作当然都要换啦,所以与队列相关的这些组件都做了更换。

二、scrapy-redis提供了哪些组件?
Scheduler、Dupefilter、Pipeline、Spider
提供了哪些组件具体见darkrho/scrapy-redis · GitHub

三、为什么要提供这些组件?
这要从哪哪哪说起(喝口水,默默地望着远方......)

我们先从scrapy的“待爬队列”和“Scheduler”入手:
咱们玩过爬虫(什么玩过,是学习过,研究过,爱过也被虐过)的同学都多多少少有些了解,在爬虫爬取过程当中,有一个主要的数据结构是“待爬队列”,以及能够操作这个队列的调度器(也就是Scheduler啦)。scrapy官方文档对这二者的描述不多,基本上没提。

scrapy使用什么样的数据结构来存放待爬取的request呢?
其实没用高大上的数据结构,就是python自带的collection.deque,不过当然是改造过后的啦(后面所说到的deque均是指scrapy改造之后的队列,至于如何改造的,就去看代码吧)。
详见源代码queuelib/queue.py at master · scrapy/queuelib · GitHub
不过咱们用一用deque就会意识到,该怎么让两个以上的Spider共用这个deque呢?答案是,我水平不够,不知道。那分布式怎么实现呢,待爬队列都不能共享,还玩个泥巴呀。scrapy-redis提供了一个解决方法,把deque换成redis数据库,我们从同一个redis服务器存放要爬取的request,这样就能让多个spider去同一个数据库里读取,这样分布式的主要问题就解决了嘛。

---------------------------------------------------分割线的随地大小便----------------------------------------------------------
那么问题又来了,我们换了redis来存放队列,哪scrapy就能直接分布式了么?(当初天真的我呀~
当然不能。我们接着往下说。scrapy中跟“待爬队列”直接相关的就是调度器“Scheduler”:scrapy/scheduler.py at master · scrapy/scrapy · GitHub,它负责对新的request进行入列操作(加入deque),取出下一个要爬取的request(从deque中取出)等操作。
在scrapy中,Scheduler并不是直接就把deque拿来就粗暴的使用了,而且提供了一个比较高级的组织方法,它把待爬队列按照优先级建立了一个字典结构,比如:
{
priority0:队列0
priority1:队列2
priority2:队列2
}
然后根据request中的priority属性,来决定该入哪个队列。而出列时,则按priority较小的优先出列。为了管理这个比较高级的队列字典,Scheduler需要提供一系列的方法。说这么多有什么意义呢?最主要的指导意义就是:你要是换了redis做队列,这个scrapy下的Scheduler就用不了,所以自己写一个吧。

于是就出现了scrapy-redis的专用scheduler:scrapy-redis/scheduler.py at master · darkrho/scrapy-redis · GitHub,其实可以对比一下看,操作什么的都差不太多。主要是操作的数据结构变了。

----------------------------------------------被当众抓住的分割线---------------------------------------------------------
那么既然使用了redis做主要数据结构,能不能把其他使用自带数据结构关键功能模块也换掉呢?(关键部分使用自带数据结构简直有种没穿小内内的危机感,这是本人的想法~)
在我们爬取过程当中,还有一个重要的功能模块,就是request去重(已经发送过得请求就别再发啦,也要考虑一下服务器君的感受好伐)。

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

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

详见源代码:scrapy/dupefilters.py at master · scrapy/scrapy · GitHub

为了分布式,把这个集合也换掉吧,换了redis,照样也得把去重类给换了。
于是就有了scrapy-redis的dupefilter:scrapy-redis/dupefilter.py at master · darkrho/scrapy-redis · GitHub

------------------------------------------把分割线掀起来(╯‵□′)╯︵||||||\\\\\\\\\\\\\------------------------------------
那么依次类推,接下来的其他组件(Pipeline和Spider),我们也可以轻松的猜到,他们是为什么要被修改呢。对,都是因为redis,全怪redis,redis是罪魁祸首。(其实我不知道,我只是在凑字数而已)

以上是我个人见解,不代表权威说法。希望对你有帮助。如有纰漏请指正(但是别打我

本文转载自:https://www.zhihu.com/question/32302268

Airship
粉丝 46
博文 1065
码字总数 21602
作品 0
南京
高级程序员
私信 提问
windows下如何安装scrapy-redis

如何在windows平台下安装scrapy-redis,(此处特别注意中是用短横线连接的,而非下划线)。 scrapy和scrapy-redis的区别,见下面这篇知乎上的文章 https://www.zhihu.com/question/32302268/...

高正杰
2017/12/24
0
0
爱玛士关于爬虫的scrapy框架的心得

前言 Scrapy是爬虫必须学会的一个框架!一般人确实很难搞的透彻!不过他的功能方面确实特别好用。 scrapy scrapy 是一个异步爬虫框架,使用它,可以屏蔽很多复杂的底层设计,只需要解析下载下...

无也Python
2018/10/25
50
0
scrapy-redis分布式爬虫的搭建过程

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

zwq912318834
2017/12/20
0
0
scrapy-redis之简介,安装

(scrapy_redis框架源码: https://github.com/rmax/scrapy-redis) 1 概念原理 scrapy-redis是一个基于redis的分布式爬虫框架,用于在爬取大量请求数据的情况下,单个主机的处理能力不足问题.(可...

LinQiH
2017/10/21
0
0
Scrapy-Redis分布式爬取链家上海17个区房源信息(二)

免责声明:本项目旨在学习Scrapy爬虫框架和MongoDB数据库,不可使用于商业和个人其他意图。若使用不当,均由个人承担。 简介 之前用requests + bs4 抓取过宝山区的房源信息,今天我们用scrap...

Treehl
2018/01/10
0
0

没有更多内容

加载失败,请刷新页面

加载更多

全面兼容IE6/IE7/IE8/FF的CSS HACK写法

浏览器市场的混乱,给设计师造成很大的麻烦,设计的页面兼容完这个浏览器还得兼容那个浏览器,本来ie6跟ff之间的兼容是很容易解决的。加上个ie7会麻烦点,ie8的出现就更头疼了,原来hack ie...

前端老手
7分钟前
3
0
常用快递电子面单批量打印api接口对接demo-JAVA示例

目前有三种方式对接电子面单: 1.快递公司:各家快递公司逐一对接接口 2.菜鸟:支持常用15家快递电子面单打印 3.快递鸟:仅对接一次,支持常用30多家主流快递电子面单打印 目前也是支持批量打...

程序的小猿
10分钟前
5
0
Yii 框架中rule规则必须搭配验证函数才能使用

public $store_id;public $user_id;public $page;public $limit;public $list;public $mch_list;public $cart_id;public $is_community;public $shop_id;public $cart_typ......

chenhongjiang
12分钟前
2
0
Flutter使用Rammus实现阿里云推送

前言: 最近新的Flutter项目有“阿里云推送通知”的需求,就是Flutter的App启动后检测到有新的通知,点击通知栏然后跳转到指定的页面。在这里我使用的是第三方插件Rammus来实现通知的推送,之...

EmilyWu
13分钟前
26
0
Knative 实战:三步走!基于 Knative Serverless 技术实现一个短网址服务

短网址顾名思义就是使用比较短的网址代替很长的网址。维基百科上面的解释是这样的: 短网址又称网址缩短、缩短网址、URL 缩短等,指的是一种互联网上的技术与服务,此服务可以提供一个非常短...

阿里巴巴云原生
28分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部