scrapy_redis原理分析并实现断点续爬以及分布式爬虫

scrapy_redis原理分析并实现断点续爬以及分布式爬虫

学习目标
  1. 了解 scrapy实现去重的原理
  2. 了解 scrapy中请求入队的条件
  3. 掌握 scrapy_redis基于url地址的增量式单机爬虫
  4. 掌握 scrapy_redis分布式爬虫

1. 下载github的demo代码

  1. clone github scrapy-redis源码文件

    git clone https://github.com/rolando/scrapy-redis.git

  2. 研究项目自带的demo

    mv scrapy-redis/example-project ~/scrapyredis-project

2. 观察dmoz文件

在domz爬虫文件中,实现方式就是之前的crawlspider类型的爬虫

from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Ruleclass DmozSpider(CrawlSpider):"""Follow categories and extract links."""name = 'dmoz'allowed_domains = ['dmoztools.net']start_urls = ['http://dmoztools.net/'] # 这里修改了url# 定义数据提取规则,使用了css选择器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(),}

但是在settings.py中多了以下内容,这几行表示scrapy_redis中重新实现的了去重的类,以及调度器,并且使用RedisPipeline管道类

DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
SCHEDULER = "scrapy_redis.scheduler.Scheduler"
SCHEDULER_PERSIST = TrueITEM_PIPELINES = {'example.pipelines.ExamplePipeline': 300,'scrapy_redis.pipelines.RedisPipeline': 400,
}

3. 运行dmoz爬虫,观察现象

  1. 首先我们需要添加redis的地址,程序才能够使用redis
REDIS_URL = "redis://127.0.0.1:6379"
#或者使用下面的方式
# REDIS_HOST = "127.0.0.1"
# REDIS_PORT = 6379
  1. 我们执行domz的爬虫,会发现redis中多了一下三个键:
  1. 中止进程后再次运行dmoz爬虫

继续执行程序,会发现程序在前一次的基础之上继续往后执行,所以domz爬虫是一个基于url地址的增量式的爬虫

4. scrapy_redis的原理分析

我们从settings.py中的三个配置来进行分析
分别是:

  • RedisPipeline # 管道类
  • RFPDupeFilter # 指纹去重类
  • Scheduler # 调度器类
  • SCHEDULER_PERSIST # 是否持久化请求队列和指纹集合
4.1 Scrapy_redis之RedisPipeline

RedisPipeline中观察process_item,进行数据的保存,存入了redis中

4.2 Scrapy_redis之RFPDupeFilter

RFPDupeFilter 实现了对request对象的加密

4.3 Scrapy_redis之Scheduler

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

4.4 由此可以总结出request对象入队的条件
  • request的指纹不在集合中
  • request的dont_filter为True,即不过滤
    • start_urls中的url地址会入队,因为他们默认是不过滤
4.5 实现单机断点续爬

改写网易招聘爬虫,该爬虫就是一个经典的基于url地址的增量式爬虫

5. 实现分布式爬虫

5.1 分析demo中代码

打开example-project项目中的myspider_redis.py文件

通过观察代码:

  1. 继承自父类为RedisSpider
  2. 增加了一个redis_key的键,没有start_urls,因为分布式中,如果每台电脑都请求一次start_url就会重复
  3. 多了__init__方法,该方法不是必须的,可以手动指定allow_domains
  4. 启动方法:
    1. 在每个节点正确的目录下执行scrapy crawl 爬虫名,使该节点的scrapy_redis爬虫程序就位
    2. 在共用的redis中 lpush redis_key 'start_url',使全部节点真正的开始运行
  5. settings.py中关键的配置
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
SCHEDULER = "scrapy_redis.scheduler.Scheduler"
SCHEDULER_PERSIST = TrueITEM_PIPELINES = {'example.pipelines.ExamplePipeline': 300,'scrapy_redis.pipelines.RedisPipeline': 400,
}
REDIS_URL = "redis://127.0.0.1:6379"
5.2 动手实现分布式爬虫

改写tencent爬虫为分布式爬虫

注意:启动方式发生改变

小结

  1. scrapy_redis的含义和能够实现的功能
    1. scrapy是框架
    2. scrapy_redis是scrapy的组件
    3. scrapy_redis能够实现断点续爬和分布式爬虫
  2. scrapy_redis流程和实现原理
    1. 在scrapy框架流程的基础上,把存储request对象放到了redis的有序集合中,利用该有序集合实现了请求队列
    2. 并对request对象生成指纹对象,也存储到同一redis的集合中,利用request指纹避免发送重复的请求
  3. request对象进入队列的条件
    1. request的指纹不在集合中
    2. request的dont_filter为True,即不过滤
  4. request指纹的实现
    • 请求方法
    • 排序后的请求地址
    • 排序并处理过的请求体或空字符串
    • 用hashlib.sha1()对以上内容进行加密
  5. scarpy_redis实现增量式爬虫、布式爬虫
    1. 对setting进行如下设置
      • DUPEFILTER_CLASS = “scrapy_redis.dupefilter.RFPDupeFilter”
      • SCHEDULER = “scrapy_redis.scheduler.Scheduler”
      • SCHEDULER_PERSIST = True
      • ITEM_PIPELINES = {‘scrapy_redis.pipelines.RedisPipeline’: 400,}
      • REDIS_URL = “redis://127.0.0.1:6379” # 请正确配置REDIS_URL
    2. 爬虫文件中的爬虫类继承RedisSpider类
    3. 爬虫类中redis_key替代了start_urls
    4. 启动方式不同
      • 通过scrapy crawl spider启动爬虫后,向redis_key放入一个或多个起始url(lpush或rpush都可以),才能够让scrapy_redis爬虫运行
    5. 除了以上差异点以外,scrapy_redis爬虫和scrapy爬虫的使用方法都是一样的

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/237082.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

比 style gan 更好的 style gan2

上一篇博客介绍了style gan 原理,但是 style gan 的结果会有水珠伪影,作者实验后发现是 Adain 导致的,AdaIN对每一个feature map的通道进行归一化,这样可能破坏掉feature之间的信息。当然实验证明发现,去除AdaIN的归一…

华为数通方向HCIP-DataCom H12-831题库(多选题:201-220)

第201题 在多集群RR组网中,每个集群中部署了一台RR设备及其客户机,各集群的RR与为非客户机关系,并建立IBGP全连接。以下关于BGP路由反射器发布路由规则的描述,正确的有哪些? A、若某RR从EBGP对等体学到的路由,此RR会传递给其他集群的RR B、若某RR从非客户机IBGP对等体学…

QT打包exe文件,在其它电脑里双击exe就可以直接运行

想要不依赖QT环境,在其它电脑里直接双击exe文件就可以运行当前程序。具体打包过程如下: 使用QT编译出release版本的exe release版本运行无误后,需要找到当前构建生成的exe所在文件夹 可以看到具体目录在这里 我在该目录下的bin文件夹里找到…

【科技前沿】数字孪生技术改革智慧供热,换热站3D可视化引领未来

换热站作为供热系统不可或缺的一部分,其能源消耗对城市环保至关重要。在双碳目标下,供热企业可通过搭建智慧供热系统,实现供热方式的低碳、高效、智能化,从而减少碳排放和能源浪费。通过应用物联网、大数据等高新技术,…

【小黑嵌入式系统第十一课】μC/OS-III程序设计基础(一)——任务设计、任务管理(创建基本状态内部任务)、任务调度、系统函数

上一课: 【小黑嵌入式系统第十课】μC/OS-III概况——实时操作系统的特点、基本概念(内核&任务&中断)、与硬件的关系&实现 文章目录 一、任务设计1.1 任务概述1.2 任务的类型1.2.1 单次执行类任务(运行至完成型&#…

Linux调试器gdb的用法

Linux调试器gdb的用法 1. debug/release版本之间的比较2. gdb调试器的基本指令3. 使用展示 1. debug/release版本之间的比较 在之前学习C语言的的时候出过一期vs的调试技巧。 而对于现在的Linux下的调试器gdb其实也是换汤不换药的,基本上的调试思路是不会改变的&am…

FreeSWITCH 1.10 源码阅读(7)-uuid_bridge 命令原理解析

文章目录 1. uuid_bridge 命令执行2. 源码分析3. uuid_bridge 问题处理 1. uuid_bridge 命令执行 uuid_bridge 命令用于将两条腿桥接在一起,以实现双方的通话。下图是该命令在 FreeSWITCH 中的处理流程,大致的流程可以分成以下几个步骤: uui…

手写单链表(指针)(next域)附图

目录 创建文件: 具体实现: 首先是头插。 注意:一定要注意:再定义tmp时,要给它赋一个初始值(推荐使用 new list_next) 接着是尾插: 随后是中间插: 然后是最简单的改值&#xf…

JS - 设计模式持续学习中

通过例子持续学习JS设计模式中,接下来请跟随我的步伐走进我的学习笔记世界~ 什么是设计模式?我们为什么需要学习设计模式? 设计模式是可以更好解决问题的一种方案。 这意味着什么?如果你开发的项目的功能是固定的,永…

Java中的继承

继承 什么是继承继承的特点继承后对象的创建 继承的好处与应用场景继承相关注意事项权限修饰符单继承、Object类方法重写什么是方法重写 子类中访问其他成员的特点子类构造器的特点 什么是继承 Java中提供了一个关键字extends,用这个关键字,可以让一个类…

【自用】Ubuntu20.4从Vivado到ddr200t运行HelloWorld

【自用】Ubuntu20.4新系统从输入法到ddr200t运行HelloWorld 一、编辑bashrc二、Vivado2022.2安装三、编译蜂鸟E203自测样例1. 环境准备2. 下载e203_hbirdv2工程文件3. 尝试编译自测案例1. 安装RISC-V GNU工具链2. 编译测试样例 4. 用vivado为FPGA生成mcs文件1.准备RTL2.生成bit…

对大学生创新创业某赛事目前存在的烂尾楼现象的一些研究的分享(1)

经过对”某某网”大学生创新创业大赛国赛第五届-第八届部分金奖项目的研究,进行较为充分的信息溯源、穿透调查,我发现不少项目存在赛事材料画大饼,严重不切合实际,参赛人员并非真正创新创业,赛后迅速销声匿迹、烂尾切割…

图论 | 网络流的基本概念

文章目录 流网路残留网络增广路径割最大流最小割定理最大流Edmonds-Karp 算法算法步骤程序代码时间复杂度 流网路 流网络: G ( V , E ) G (V, E) G(V,E) 有向图,不考虑反向边s:源点t:汇点 c ( u , v ) c(u, v) c(u,v)&#xff…

你以为出现NoClassDefFoundError错误会是什么原因?

你以为出现NoClassDefFoundError错误会是什么原因? 1、概述2、事情经过3、总结 1、概述 大家好,我是欧阳方超,可以关注我的公众号“欧阳方超”,后续内容将在公众号首发。 同样的错误,非一样的解决方式。NoClassDefFou…

【智慧校园】基于国标GB28181协议EasyCVR视频技术的高校宿舍智能监管方案

现如今,各大学校不乏众多住校生,但由于很多学生年龄较小 ,又缺乏独自生活的经历,如何给在校住宿生做到安全与生活双重保障?旭帆科技校园智能视频监控通过人工智能技术对住宿区域进行智能监管,确保学生住宿安…

【HCIP学习记录】OSPF Hello报文及状态机

字段长度含义Version1字节版本,OSPF的版本号。对于OSPFv2来说,其值为2。Type1字节类型,OSPF报文的类型,有下面几种类型: 1:Hello报文;● 2:DD报文;● 3:LSR报…

【终极教程】cocos2dx-js 分批次混淆压缩js文件

​ 说明: 1> 由于我们当前游戏框架的结构是平台形式的就是一个大厅里面有若干个子游戏,所以在发布的时候得区分子游戏和大厅了解了一下 project.json 里面有一个 jsList 可以把所有放进去的js文件压缩混淆成一个大的文件但是我们游戏的子游戏非常多 这样子弄显然不合适&…

青少年CTF-qsnctf-Web-登陆试试

题目环境: 题目难度:★题目描述:Syclover用户忘了他的密码,咋办哦,依稀记得密码为6位数字,以774开头,这次我们来爆爆他的密码,让他再也不犯相同的错了 先不着急进行爆破 看看源码里面有没有其它有用的信息 …

Shell三剑客:awk(内部变量)

一、$0 :完整的输入记录 [rootlocalhost ~]# awk -F: {print $0} passwd.txt root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/s…

软件分享--图片置顶工具

一个好的程序应该只做一件事情,并且将这件事情做好。 使用许多小工具的集合要比使用一个什么都做但什么都做不好的工具要好。 linux系统强大,组成它的是dd、sed、grep、awk、tar等各种命令工具的集合。 如果你能够合理使用各种小工具。效率会比使用任何…