分布式爬虫的演习。

分布式爬虫问题其实也就是多台机器多个 spider 对 多个 url 的同时处理问题,怎样 schedule 这些 url,怎样汇总 spider 抓取的数据。最简单粗暴的方法就是将 url 进行分片,交给不同机器,最后对不同机器抓取的数据进行汇总。然而这样每个 spider 只能对自己处理的 url 去重,没办法全局的去重,另外性能也很难控制,可能有某台机器很早就跑完了,而别的机器还要跑很久。另一种思路就是把 url 存在某个地方,共享给所有的机器,总的调度器来分配请求,判断 spider 有没有闲置,闲置了就继续给它任务,直到所有的 url 都爬完,这种方法解决了去重问题(下面会具体讲到),也能提高性能,scrapy-redis 就实现了这样一个完整框架,总的来说,这更适合广度优先的爬取。

Scrapyd

Scrapy 并没有提供内置的分布式抓取功能,不过有很多方法可以帮你实现。

如果你有很多个spider,最简单的方式就是启动多个 Scrapyd 实例,然后将spider分布到各个机器上面。

如果你想多个机器运行同一个spider,可以将url分片后交给每个机器上面的spider。比如你把URL分成3份

http://somedomain.com/urls-to-crawl/spider1/part1.list
http://somedomain.com/urls-to-crawl/spider1/part2.list
http://somedomain.com/urls-to-crawl/spider1/part3.list

然后运行3个 Scrapyd 实例,分别启动它们,并传递part参数

curl http://scrapy1.mycompany.com:6800/schedule.json -d project=myproject -d spider=spider1 -d part=1
curl http://scrapy2.mycompany.com:6800/schedule.json -d project=myproject -d spider=spider1 -d part=2
curl http://scrapy3.mycompany.com:6800/schedule.json -d project=myproject -d spider=spider1 

Crawlera

这个,花钱就可以轻易解决~ 直达

Scrapy-redis

Redis 是高性能的 key-value 数据库。我们知道 MongoDB 将数据保存在了硬盘里,而 Redis 的神奇之处在于它将数据保存在了内存中,因此带来了更高的性能。

分布式原理

scrapy-redis实现分布式,其实从原理上来说很简单,这里为描述方便,我们把自己的核心服务器称为 master,而把用于跑爬虫程序的机器称为 slave。

回顾 scrapy 框架,我们首先给定一些start_urls,spider 最先访问 start_urls 里面的 url,再根据我们的 parse 函数,对里面的元素、或者是其他的二级、三级页面进行抓取。而要实现分布式,只需要在这个starts_urls里面做文章就行了。进一步描述如下:

  1. master 产生 starts_urls,url 会被封装成 request 放到 redis 中的 spider:requests,总的 scheduler 会从这里分配 request,当这里的 request 分配完后,会继续分配 start_urls 里的 url。

  2. slave 从 master 的 redis 中取出待抓取的 request,下载完网页之后就把网页的内容发送回 master 的 redis,key 是 spider:items。scrapy 可以通过 settings 来让 spider 爬取结束之后不自动关闭,而是不断的去询问队列里有没有新的 url,如果有新的 url,那么继续获取 url 并进行爬取,所以这一过程将不断循环。

  3. master 里的 reids 还有一个 key 是 “spider:dupefilter” 用来存储抓取过的 url 的 fingerprint(使用哈希函数将url运算后的结果),防止重复抓取,只要 redis 不清空,就可以进行断点续爬。

对于已有的 scrapy 程序,对其扩展成分布式程序还是比较容易的。总的来说就是以下几步:

  1. 找一台高性能服务器,用于 redis 队列的维护以及数据的存储。
  2. 扩展 scrapy 程序,让其通过服务器的 redis 来获取 start_urls,并改写 pipeline 里数据存储部分,把存储地址改为服务器地址。
  3. 在服务器上写一些生成url的脚本,并定期执行。

关于 scheduler 到底是怎么进行调度的,需要看源码进行分析。

源码分析

可能上面的描述还是不够清楚,干脆看一下源码吧,scrapy-redis 主要要一下几个文件。

零件分析

  1. connection.py
    根据 settings 里的配置实例化 redis 连接,被 dupefilter 和 scheduler 调用。

  2. dupefilter.py
    对 request 进行去重,使用了 redis 的 set。

  3. queue.py
    三种 queue, SpiderQueue(FIFO), SpiderPriorityQueue,以及 SpiderStack(LIFI)。默认使用的是第二种。

  4. pipelines.py
    分布式处理,将 item 存储在 redis 中。

  5. scheduler.py
    取代 scrapy 自带的 scheduler,实现分布式调度,数据结构来自 queue。

  6. spider.py
    定义 RedisSpider.py, 继承了 RedisMixin 和 CrawlSpider。

由上可知,scrapy-redis 实现的 爬虫分布式 和 item处理分布式 就是由模块 scheduler 和模块 pipelines 实现。上述其它模块作为为二者辅助的功能模块。

调度过程

初始化

spider 被初始化时,同时会初始化一个对应的 scheduler 对象,这个调度器对象通过读取 settings,配置好自己的调度容器 queue 和判重工具dupefilter。

判重 & 进入调度池

每当一个 spider 产出一个 request 的时候,scrapy 内核会把这个 request 递交给这个 spider 对应的 scheduler 对象进行调度,scheduler 对象通过访问 redis 对 request 进行判重,如果不重复就把他添加进 redis 中的调度池。

调度

当调度条件满足时,scheduler 对象就从 redis 的调度池中取出一个 request 发送给spider,让 spider 爬取,若爬取过程中返回更多的url,那么继续进行直至所有的 request 完成。在这个过程中通过 connect signals.spider_idle 信号对 crawler 状态的监视,scheduler 对象发现 这个 spider 爬取了所有暂时可用 url,对应的 redis 的调度池空了,于是触发信号 spider_idle,spider收到这个信号之后,直接连接 redis 读取 strart_url池,拿去新的一批 url,返回新的 make_requests_from_url(url) 给引擎,进而交给调度器调度。

熟悉了原理其实可以自己来写 scheduler,自己定义调度优先级和顺序,

爬虫总结(四)-- 分布式爬虫相关推荐

  1. python3爬虫(9)分布式爬虫与对等分布式爬虫

    原文链接:http://www.dataguru.cn/thread-529666-1-1.html 谈谈主从分布式爬虫与对等分布式爬虫的优劣 主从式(Master-Slave) 对于主从式而言,有一 ...

  2. python爬虫:scrapy-redis分布式爬虫(详细版)

    本文是将现有的scrapy爬虫改造为分布式爬虫,为详细版,简略版请看https://blog.csdn.net/Aacheng123/article/details/114265960 使用scrap ...

  3. Scrapy-Redis使用教程将现有爬虫修改为分布式爬虫

    前言 scrapy爬虫框架非常好用,如果再配合scrapy-redis进行分布式爬取,爬取速度将进一步提升! 本文小结了scrapy-redis的使用方法以及如何将现有爬虫通过scrapy-redis ...

  4. python微博爬虫教程_Python爬虫教程-新浪微博分布式爬虫分享

    爬虫功能: 此项目实现将单机的新浪微博爬虫重构成分布式爬虫. Master机只管任务调度,不管爬数据:Slaver机只管将Request抛给Master机,需要Request的时候再从Master机拿 ...

  5. python 协程可以嵌套协程吗_Python实战异步爬虫(协程)+分布式爬虫(多进程)

    引言:我们在写爬虫时常会遇到这样的问题,当需要爬取多个URL时,写一个普通的基于requests库的爬虫程序爬取时间会很长.因为是顺序请求网页的,而网页请求和获得响应过程比较耗费时间,程序不得不等待获 ...

  6. python异步爬虫_Python实战异步爬虫(协程)+分布式爬虫(多进程)

    转自:https://blog.csdn.net/SL_World/article/details/86633611 在讲解之前,我们先来通过一幅图看清多进程和协程的爬虫之间的原理及其区别.(图片来源 ...

  7. 分布式爬虫原理之分布式爬虫原理

    我们在前面已经实现了Scrapy微博爬虫,虽然爬虫是异步加多线程的,但是我们只能在一台主机上运行,所以爬取效率还是有限的,分布式爬虫则是将多台主机组合起来,共同完成一个爬取任务,这将大大提高爬取的效率 ...

  8. 【Python3爬虫】学习分布式爬虫第一步--Redis分布式爬虫初体验

    一.写在前面 之前写的爬虫都是单机爬虫,还没有尝试过分布式爬虫,这次就是一个分布式爬虫的初体验.所谓分布式爬虫,就是要用多台电脑同时爬取数据,相比于单机爬虫,分布式爬虫的爬取速度更快,也能更好地应对I ...

  9. python爬虫(四)爬虫的溯源(爬取mooc某个系列课程)

    前言 ​ 这次是针对需要网页分析的爬虫,分析过后往往会获得你需要的每节视频源地址,但是假如一节视频课是有很多节课你就必须要去一个个的去搜寻每个视频的源地址,这样一来非常浪费时间而且也没有打到我们的对于 ...

最新文章

  1. Python的零基础超详细讲解(第二天)-Python的基础语法1
  2. Python 技巧篇-如何避免python报错导致强制关闭窗口
  3. 几种存储器的主要应用
  4. 小程序 -- [sitemap 索引情况提示] 根据 sitemap 的规则[0],当前页面 [pages/index/index] 将被索引
  5. spring boot + vue + element-ui全栈开发入门
  6. 轻量级web富文本框——wangEditor使用手册(4)——配置下拉菜单 demo
  7. HTML中制作循环广告条,一种循环展示广告的广告箱的制作方法
  8. 高帮足球鞋_高帮运动鞋和晕车症可以教给我们有关VR设计的知识
  9. python pytest框架
  10. 重写方法,重载方法,虚方法和抽象方法的使用
  11. VUE 生命周期图示
  12. PyCharm+PyTorch0.4.0安装使用
  13. 从源码的角度分析ViewGruop的事件分发
  14. 篮球比赛JAVA代码_Java编程实现NBA赛事接口调用实例代码
  15. Lumerical官方案例、FDTD时域有限差分法仿真学习(一)——闪耀光栅(Blazed grating)
  16. layabox2.0 开发微信小游戏经验分享
  17. (十三)中介者模式详解(玄幻版) - 转
  18. Android 安装包没有签名文件问题
  19. java并发机制_Java并发机制的底层实现原理.PDF
  20. “听觉”营销价值凸显,喜马拉雅迎来新局点

热门文章

  1. 科大星云诗社动态20210120
  2. 科大星云诗社动态20210429
  3. 科大星云诗社动态20210817
  4. [Python学习笔记]h5py入门讲解
  5. 十九、“文捷笔妙活如水,气定神闲稳若山。”(2021.6.7)
  6. Python 深度学习,你的 Keras 准备好了吗?
  7. python状态机实现_如何实现Python状态机设计?
  8. 新兴机器学习算法:从无监督降维到监督降维
  9. 双目立体视觉及正交偏振 3D 显示
  10. Delphi动态事件