scrapy的去重原理

信号无处不在
【知其然且知其所以然,才能够更好的理解这个框架,而且在使用和改动的时候也能够想出更合理的方法。】

(开始测试前,到settings.py中注释掉下载中间件的设置,这里用jobbole爬虫来测试,所以之前写的调用chrome的两个方法init和spider_closed都要注释掉。)

这里你们可以用自己的爬虫来测试,不一定要按我的来测试。

到scrapy源码包

[项目\Lib\site-packages\scrapy\dupefilters.py]

里面找去重的代码,RFPDupeFilter类就是去重器,里面有个方法叫做request_seen,它在scheduler(发起请求的第一时间)的时候被调用。它代码里面调用了request_fingerprint方法(就是给request生成一个指纹),连续两次跟进代码就进入到了request.py文件的request_fingerprint方法中,方法中有一句代码:

fp = hashlib.sha1()
……cache[include_headers] = fp.hexdigest()

就是给每一个传递过来的url生成一个固定长度的唯一的哈希值。这种量级千万到亿的级别内存是可以应付的。

然后看到init方法:

    def __init__(self, path=None, debug=False):self.file = Noneself.fingerprints = set()self.logdupes = Trueself.debug = debugself.logger = logging.getLogger(__name__)if path:self.file = open(os.path.join(path, 'requests.seen'), 'a+')self.file.seek(0)self.fingerprints.update(x.rstrip() for x in self.file)

里面有一句代码 self.fingerprints = set(),就是通过set集合的特点(set不允许有重复值)进行去重。

可以用断点调试的方法进行跟踪查看。


Telnet

Telnet协议是TCP/IP协议族中的一员,是Internet远程登陆服务的标准协议和主要方式。它为用户提供了在本地计算机上完成远程主机工作的能力。在终端使用者的电脑上使用telnet程序,用它连接到服务器。终端使用者可以在telnet程序中输入命令,这些命令会在服务器上运行,就像直接在服务器的控制台上输入一样。可以在本地就能控制服务器。要开始一个telnet会话,必须输入用户名和密码来登录服务器。Telnet是常用的远程控制Web服务器的方法。

可以用这个在本地操控远程的scrapy,telnet是默认开启的,当scrapy运行的时候,会自动开启端口,运行框会有显示:

[scrapy.extensions.telnet] DEBUG: Telnet console listening on 127.0.0.1:6023

我们可以通过cmd连接测试。

要测试,就要开启windows电脑的telnet功能。在控制面板-程序与功能-启用或关闭windows功能,找到Telnet服务和客户端,打上勾即可。

linux系统也是默认没有Telnet的,需要安装,比如我的Deepin系统就需要用命令安装:

sudo apt-get install telnet

先运行scrap有,然后在cmd(linux在终端输入)中输入:

telnet localhost 6023

连接成功后会显示:

>>>

符号,我们输入est()可以查看当前scrapy的运行状态等属性。官方文档有Telnet的相关介绍,里面包括有一些可用的变量/查看引擎状态/暂停,恢复和停止scrapy/终端信号/设置等内容。

Telnet的源码在site-package/scrapy/extensions目录下的telnet.py文件中。


数据收集器

官方文档中有对数据收集器的介绍.

数据收集器可以应用在很多地方,举例子:如果你想知道scrapy总共发出了多少个request请求;或者你想记录总共发起了多少次yeild,都可以用数据收集器记录,它不用打开,默认可以直接使用。

在jobbole爬虫的JobboleSpider类里面新增代码:

# 收集jobbole.com所有的500、404页面及页面数量handle_httpstatus_list = [500,404]def __init__(self):self.fail_urls = []

然后到parse方法中新增代码:

        if response.status == 500 or response.status == 404:self.fail_urls.append(response.url)self.crawler.stats.inc_value("failed_url")

就可以实现对页面数量和页面url的收集,可以自定义保存.


信号

scrapy的中间件与通信都是通过信号来传递的,官网有文档

可以在您的Scrapy项目中捕捉一些信号(使用 extension)来完成额外的工作或添加额外的功能,扩展Scrapy。

信号提供了一些参数,不过处理函数不用接收所有的参数 - 信号分发机制(singal dispatching mechanism)仅仅提供处理器(handler)接受的参数。

代码演示:

from scrapy.xlib.pydispatch import dispatcher
from scrapy import signalsdef parse(self, response):""" 正式进入爬取区域 """dispatcher.connect(self.handler_spider_closed, signals.spider_closed)def handler_spider_closed(self, spider, reason):print("这个名为:" + spider.name + "的爬虫已经关闭了,原因是:" + reason)

得到的输出结果是在爬虫关闭后:

 'start_time': datetime.datetime(2018, 1, 20, 3, 5, 49, 791339)}
2018-01-20 11:05:51 [scrapy.core.engine] INFO: Spider closed (finished)这个名为:dongmeng的爬虫已经关闭了,原因是:finished

dispatcher.connect监听爬虫signals(信号),当收到爬虫关闭(signals.spider_closed)的信号时,调用handler_spider_closed方法。而handler_spider_closed我只是简单的编写了一个关闭的原因而已,还可以做更深入的操作。

由此可以看出,爬虫的信号监听和状态操作可以做很多的事情,比如打开爬虫时、爬虫空闲时可以收集当前request请求队列、记录404页面数量或者200状态的页面有那些、多少条等。


扩展

官方文档对扩展有介绍:

扩展框架提供一个机制,使得你能将自定义功能绑定到Scrapy。

扩展只是正常的类,它们在Scrapy启动时被实例化、初始化。

scrapy里面的中间件都是一种扩展。


为了更好的理解扩展,这里用源码跟踪的形式来理解,到[项目/Lib/site-packages/scrapy/extensions]目录下找到corestats.py文件。

from_crawler方法里面记录了很多的信号量:

@classmethoddef from_crawler(cls, crawler):o = cls(crawler.stats)crawler.signals.connect(o.spider_opened, signal=signals.spider_opened)crawler.signals.connect(o.spider_closed, signal=signals.spider_closed)crawler.signals.connect(o.item_scraped, signal=signals.item_scraped)crawler.signals.connect(o.item_dropped, signal=signals.item_dropped)crawler.signals.connect(o.response_received, signal=signals.response_received)return o

下面对应都写着具体的执行方法。比如spider_opened爬虫启动的时候就会:

    def spider_opened(self, spider):self.stats.set_value('start_time', datetime.datetime.utcnow(), spider=spider)

记录爬虫启动的时间。

还有spider_closed关闭爬虫的时候就会:

    def spider_closed(self, spider, reason):self.stats.set_value('finish_time', datetime.datetime.utcnow(), spider=spider)self.stats.set_value('finish_reason', reason, spider=spider)

记录下关闭时间和关闭的原因等。

到[项目/Lib/site-packages/scrapy/extensions]memusage.py文件是监控内存使用的。里面有一串代码:

        crawler.signals.connect(self.engine_started, signal=signals.engine_started)crawler.signals.connect(self.engine_stopped, signal=signals.engine_stopped)

是主要的绑定项

比如这个engine_started方法开始就记录内存使用信息。

        self.crawler = crawlerself.warned = Falseself.notify_mails = crawler.settings.getlist('MEMUSAGE_NOTIFY_MAIL')self.limit = crawler.settings.getint('MEMUSAGE_LIMIT_MB')*1024*1024self.warning = crawler.settings.getint('MEMUSAGE_WARNING_MB')*1024*1024self.check_interval = crawler.settings.getfloat('MEMUSAGE_CHECK_INTERVAL_SECONDS')self.mail = MailSender.from_settings(crawler.settings)

里面的大概意思就是设置了监控内存的定时时间/不同状态的操作等,可以在engine_started里面加逻辑,想对内存干什么就干什么。

Scrapy框架-去重原理讲解、数据收集以及信号量知识相关推荐

  1. python爬虫入门(六) Scrapy框架之原理介绍

    Scrapy框架 Scrapy简介 Scrapy是用纯Python实现一个为了爬取网站数据.提取结构性数据而编写的应用框架,用途非常广泛. 框架的力量,用户只需要定制开发几个模块就可以轻松的实现一个爬 ...

  2. Python Scrapy框架爬取微博数据

    -1.前言 最近导师接到了一个项目,要爬取社交网路的数据,其中有一部分是爬取微博,Twitter和Facebook.目前实现了微博部分.先写着. 整个工程是使用的python3.6+Scray框架+M ...

  3. python爬虫scrapy框架爬取网页数据_Scrapy-Python

    scrapy Scrapy:Python的爬虫框架 实例Demo 抓取:汽车之家.瓜子.链家 等数据信息 版本+环境库 Python2.7 + Scrapy1.12 初窥Scrapy Scrapy是一 ...

  4. 爬虫-豆瓣书籍排行榜及用户信息-2021.7.23-使用Scrapy框架-用MongoDB存储数据

    1.环境 python3.8或python3.7 pycharm2021.2 MongoDB Scrapy 2.信息提取 2.1 创建Scrapy项目 在cmd模式下创建Scrapy项目 # 进入要存 ...

  5. 实现Scrapy框架爬取酷狗音乐Top100名,并存储为TXT,JSON,CSV和Excel格式数据

    前言 实现Scrapy框架爬取网页数据(酷狗音乐Top100名,包括排名信息.歌手信息.歌曲名.歌曲时长) 一.创建项目 在cmd中输入: scrapy startproject kugouScrap ...

  6. Python网络爬虫数据采集实战:Scrapy框架爬取QQ音乐存入MongoDB

    ​    通过前七章的学习,相信大家对整个爬虫有了一个比较全貌的了解 ,其中分别涉及四个案例:静态网页爬取.动态Ajax网页爬取.Selenium浏览器模拟爬取和Fillder今日头条app爬取,基本 ...

  7. Python网络爬虫数据采集实战(八):Scrapy框架爬取QQ音乐存入MongoDB

    通过前七章的学习,相信大家对整个爬虫有了一个比较全貌的了解 ,其中分别涉及四个案例:静态网页爬取.动态Ajax网页爬取.Selenium浏览器模拟爬取和Fillder今日头条app爬取,基本涵盖了爬虫 ...

  8. 网络爬虫框架——Scrapy框架解析

    一.为什么使用Scrapy框架? Scrapy是一个快速.高层次的屏幕抓取和web抓取的框架,可用于数据挖掘.监测和自动化检测,任何人都可以根据需要去进行修改. 二.Scrapy框架每个组件介绍 1. ...

  9. Python之Scrapy框架的安装和使用

    Scrapy框架是目前Python中最受欢迎的爬虫框架之一,那么我们今天就来具体了解一下Scrapy框架 什么是Scrapy框架? Scrapy是一个快速.高层次.轻量级的屏幕抓取和web抓取的pyt ...

最新文章

  1. Meta 发布 Bean Machine 帮助衡量 AI 模型的不确定性
  2. 第一季度Teradata营收下降7.3% 利润下跌63%
  3. 已解决:Unable to register authentication agent: GDBus.Error:org.freedesktop.PolicyKit1.Error.Failed:
  4. jquery ajax json 数据的遍历
  5. Apache Ant运行时Unable to locate tools.jar解决方法
  6. 好友消息和群消息区别
  7. 基于递归算法,树形结构数据下业务场景,封装解决方法
  8. node-webki 基本程序结构
  9. Xcode调试项目时取消弹出框提示授权
  10. 草根最容易逆袭的地方就是互联网
  11. Cannot resolve table 't_daily'
  12. 阿里完成首个可控量子比特研发;45 名谷歌员工举报不公对待;Swoft 2.0.6 正式版发布 | 极客头条...
  13. Android开机优化之调整Launcher的加载时间
  14. 51汇编——矩阵键盘
  15. Pytorch:图像风格迁移
  16. python搭建下载/上传服务器
  17. 微信小程序开发者工具出现Framework inner error错误
  18. 黑群晖Apache Http Server 启动失败错误
  19. Ubuntu 20 更新后突然无法获取IP
  20. 写了几个排序算法的测试

热门文章

  1. java代码中fastjson生成字符串和解析字符串的方法和javascript文件中字符串和json数组之间的转换方法...
  2. RESTful API 设计最佳实践
  3. Yii中创建自己的Widget
  4. JavaScript:事件冒泡和事件委托
  5. C#文件和文件夹输入输出流代码
  6. 局域网怎样自动安装FLASH插件(浏览器不安装flashplayer都可以浏览.swf文件)
  7. cloudera之hadoop-0.20.1+152.tar.gz 安装出现找不到JAVA_HOME问题的解决办法
  8. modelsim的destbench模型1
  9. java 导出excel 注解_Java基于注解和反射导入导出Excel
  10. string 相等 java_java中String相等问题