scrapy-redis分布式爬虫的搭建过程(理论篇)


Posted in Python onSeptember 29, 2020

1. 背景

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

 2. 环境

  • 系统:win7
  • scrapy-redis
  • redis 3.0.5
  • python 3.6.1

3. 原理

3.1. 对比一下scrapy 和 Scrapy-redis 的架构图。

scrapy架构图:

scrapy-redis分布式爬虫的搭建过程(理论篇)

scrapy-redis 架构图:

scrapy-redis分布式爬虫的搭建过程(理论篇)

多了一个redis组件,主要影响两个地方:第一个是调度器。第二个是数据的处理。 3.2. Scrapy-Redis分布式策略。

scrapy-redis分布式爬虫的搭建过程(理论篇)

作为一个分布式爬虫,是需要有一个Master端(核心服务器)的,在Master端,会搭建一个Redis数据库,用来存储start_urls、request、items。Master的职责是负责url指纹判重,Request的分配,以及数据的存储(一般在Master端会安装一个mongodb用来存储redis中的items)。出了Master之外,还有一个角色就是slaver(爬虫程序执行端),它主要负责执行爬虫程序爬取数据,并将爬取过程中新的Request提交到Master的redis数据库中。

如上图,假设我们有四台电脑:A, B, C, D ,其中任意一台电脑都可以作为 Master端 或 Slaver端。整个流程是:

  • 首先Slaver端从Master端拿任务(Request、url)进行数据抓取,Slaver抓取数据的同时,产生新任务的Request便提交给 Master 处理;
  • Master端只有一个Redis数据库,负责将未处理的Request去重和任务分配,将处理后的Request加入待爬队列,并且存储爬取的数据。

scrapy-redis分布式爬虫的搭建过程(理论篇) 

scrapy-redis分布式爬虫的搭建过程(理论篇)

Scrapy-Redis默认使用的就是这种策略,我们实现起来很简单,因为任务调度等工作Scrapy-Redis都已经帮我们做好了,我们只需要继承RedisSpider、指定redis_key就行了。

缺点是,Scrapy-Redis调度的任务是Request对象,里面信息量比较大(不仅包含url,还有callback函数、headers等信息),可能导致的结果就是会降低爬虫速度、而且会占用Redis大量的存储空间,所以如果要保证效率,那么就需要一定硬件水平。

4. 运行流程

第一步:在slaver端的爬虫中,指定好 redis_key,并指定好redis数据库的地址,比如:

class MySpider(RedisSpider):
  """Spider that reads urls from redis queue (myspider:start_urls)."""
  name = 'amazon'
  redis_key = 'amazonCategory:start_
# 指定redis数据库的连接参数
'REDIS_HOST': '172.16.1.99',
'REDIS_PORT': 6379,

第二步:启动slaver端的爬虫,爬虫进入等待状态,等待 redis 中出现 redis_key ,Log如下:

2017-12-12 15:54:18 [scrapy.utils.log] INFO: Scrapy 1.4.0 started (bot: scrapybot)
2017-12-12 15:54:18 [scrapy.utils.log] INFO: Overridden settings: {'SPIDER_LOADER_WARN_ONLY': True}
2017-12-12 15:54:18 [scrapy.middleware] INFO: Enabled extensions:
['scrapy.extensions.corestats.CoreStats',
 'scrapy.extensions.telnet.TelnetConsole',
 'scrapy.extensions.logstats.LogStats']
2017-12-12 15:54:18 [myspider_redis] INFO: Reading start URLs from redis key 'myspider:start_urls' (batch size: 110, encoding: utf-8
2017-12-12 15:54:18 [scrapy.middleware] INFO: Enabled downloader middlewares:
['scrapy.downloadermiddlewares.httpauth.HttpAuthMiddleware',
 'scrapy.downloadermiddlewares.downloadtimeout.DownloadTimeoutMiddleware',
 'scrapy.downloadermiddlewares.defaultheaders.DefaultHeadersMiddleware',
 'redisClawerSlaver.middlewares.ProxiesMiddleware',
 'redisClawerSlaver.middlewares.HeadersMiddleware',
 'scrapy.downloadermiddlewares.retry.RetryMiddleware',
 'scrapy.downloadermiddlewares.redirect.MetaRefreshMiddleware',
 'scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware',
 'scrapy.downloadermiddlewares.redirect.RedirectMiddleware',
 'scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware',
 'scrapy.downloadermiddlewares.stats.DownloaderStats']
2017-12-12 15:54:18 [scrapy.middleware] INFO: Enabled spider middlewares:
['scrapy.spidermiddlewares.httperror.HttpErrorMiddleware',
 'scrapy.spidermiddlewares.offsite.OffsiteMiddleware',
 'scrapy.spidermiddlewares.referer.RefererMiddleware',
 'scrapy.spidermiddlewares.urllength.UrlLengthMiddleware',
 'scrapy.spidermiddlewares.depth.DepthMiddleware']
2017-12-12 15:54:18 [scrapy.middleware] INFO: Enabled item pipelines:
['redisClawerSlaver.pipelines.ExamplePipeline',
 'scrapy_redis.pipelines.RedisPipeline']
2017-12-12 15:54:18 [scrapy.core.engine] INFO: Spider opened
2017-12-12 15:54:18 [scrapy.extensions.logstats] INFO: Crawled 0 pages (at 0 pages/min), scraped 0 items (at 0 items/min)
2017-12-12 15:55:18 [scrapy.extensions.logstats] INFO: Crawled 0 pages (at 0 pages/min), scraped 0 items (at 0 items/min)
2017-12-12 15:56:18 [scrapy.extensions.logstats] INFO: Crawled 0 pages (at 0 pages/min), scraped 0 items (at 0 items/min)

第三步:启动脚本,往redis数据库中填入redis_key(start_urls)

#!/usr/bin/env python
# -*- coding:utf-8 -*-

import redis

# 将start_url 存储到redis中的redis_key中,让爬虫去爬取
redis_Host = "172.16.1.99"
redis_key = 'amazonCategory:start_urls'

# 创建redis数据库连接
rediscli = redis.Redis(host = redis_Host, port = 6379, db = "0")

# 先将redis中的requests全部清空
flushdbRes = rediscli.flushdb()
print(f"flushdbRes = {flushdbRes}")
rediscli.lpush(redis_key, https://www.baidu.com)

scrapy-redis分布式爬虫的搭建过程(理论篇)

第四步:slaver端的爬虫开始爬取数据。Log如下:

2017-12-12 15:56:18 [scrapy.extensions.logstats] INFO: Crawled 0 pages (at 0 pages/min), scraped 0 items (at 0 items/min)
parse url = https://www.baidu.com, status = 200, meta = {'download_timeout': 25.0, 'proxy': 'http://proxy.abuyun.com:9020', 'download_slot': 'www.baidu.com', 'download_latency': 0.2569999694824219, 'depth': 7}
parse url = https://www.baidu.com, status = 200, meta = {'download_timeout': 25.0, 'proxy': 'http://proxy.abuyun.com:9020', 'download_slot': 'www.baidu.com', 'download_latency': 0.8840000629425049, 'depth': 8}
2017-12-12 15:57:18 [scrapy.extensions.logstats] INFO: Crawled 2 pages (at 2 pages/min), scraped 1 items (at 1 items/min)

第五步:启动脚本,将redis中的items,转储到mongodb中。

这部分代码,请参照:scrapy-redis分布式爬虫的搭建过程(代码篇)

5. 环境安装以及代码编写

5.1. scrapy-redis环境安装

pip install scrapy-redis

scrapy-redis分布式爬虫的搭建过程(理论篇) 

scrapy-redis分布式爬虫的搭建过程(理论篇)

代码位置:后面可以进行修改定制。

scrapy-redis分布式爬虫的搭建过程(理论篇) 

5.2. scrapy-redis分布式爬虫编写

第一步,下载官网的示例代码,地址:https://github.com/rmax/scrapy-redis (需要安装过git)

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

scrapy-redis分布式爬虫的搭建过程(理论篇)

官网提供了两种示例代码,分别继承自 Spider + redisCrawlSpider + redis

scrapy-redis分布式爬虫的搭建过程(理论篇)

第二步,根据官网提供的示例代码进行修改。

到此这篇关于scrapy-redis分布式爬虫的搭建过程(理论篇)的文章就介绍到这了,更多相关scrapy redis分布式爬虫搭建内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
在Python程序中实现分布式进程的教程
Apr 28 Python
在Python中使用PIL模块对图片进行高斯模糊处理的教程
May 05 Python
Python中的with语句与上下文管理器学习总结
Jun 28 Python
python中pandas.DataFrame排除特定行方法示例
Mar 12 Python
python实现逻辑回归的方法示例
May 02 Python
Python2实现的LED大数字显示效果示例
Sep 04 Python
selenium python浏览器多窗口处理代码示例
Jan 15 Python
Python字典遍历操作实例小结
Mar 05 Python
基于python plotly交互式图表大全
Dec 07 Python
解决Python列表字符不区分大小写的问题
Dec 19 Python
Python创建空列表的字典2种方法详解
Feb 13 Python
解析目标检测之IoU
Jun 26 Python
python ssh 执行shell命令的示例
Sep 29 #Python
Scrapy基于scrapy_redis实现分布式爬虫部署的示例
Sep 29 #Python
浅析python 字典嵌套
Sep 29 #Python
详解基于Scrapy的IP代理池搭建
Sep 29 #Python
Python 创建守护进程的示例
Sep 29 #Python
Python 解析xml文件的示例
Sep 29 #Python
Python 字典一个键对应多个值的方法
Sep 29 #Python
You might like
用PHP读注册表
2006/10/09 PHP
PHP 长文章分页函数 带使用方法,不会分割段落,翻页在底部
2009/10/22 PHP
PHP中new static()与new self()的区别异同分析
2014/08/22 PHP
ThinkPHP模版中导入CSS和JS文件的方法
2014/11/29 PHP
laravel 5 实现模板主题功能
2015/03/02 PHP
使用phpstorm和xdebug实现远程调试的方法
2015/12/29 PHP
thinkPHP js文件中U方法不被解析问题的解决方法
2016/12/05 PHP
laravel 实现设置时区的简单方法
2019/10/10 PHP
jQuery 常见学习网站与参考书
2009/11/09 Javascript
JS 模态对话框和非模态对话框操作技巧汇总
2013/04/15 Javascript
javascript实现des解密加密全过程
2014/04/03 Javascript
nodejs中转换URL字符串与查询字符串详解
2014/11/26 NodeJs
JS实现仿京东淘宝竖排二级导航
2014/12/08 Javascript
javascript实现列表滚动的方法
2015/07/30 Javascript
关于JS中prototype的理解
2015/09/07 Javascript
老生常谈js中的MVC
2017/07/25 Javascript
nodejs使用http模块发送get与post请求的方法示例
2018/01/08 NodeJs
基于Vue中点击组件外关闭组件的实现方法
2018/03/06 Javascript
vue生命周期与钩子函数简单示例
2019/03/13 Javascript
vue项目中将element-ui table表格写成组件的实现代码
2019/06/12 Javascript
小程序分页实践之编写可复用分页组件
2019/07/18 Javascript
详解webpack引用jquery(第三方模块)的三种办法
2019/08/21 jQuery
[01:03:37]Secret vs VGJ.S Supermajor小组赛C组 BO3 第二场 6.3
2018/06/04 DOTA
python中map的基本用法示例
2018/09/10 Python
Python采集猫眼两万条数据 对《无名之辈》影评进行分析
2018/12/05 Python
解决Tensorflow2.0 tf.keras.Model.load_weights() 报错处理问题
2020/06/12 Python
总结Pyinstaller的坑及终极解决方法(小结)
2020/09/21 Python
Selenium环境变量配置(火狐浏览器)及验证实现
2020/12/07 Python
CSS3实现图片抽屉式效果的示例代码
2019/11/06 HTML / CSS
如何拷贝一整个Java对象,包括它的状态
2013/12/27 面试题
教育学习自我评价
2014/02/03 职场文书
班长竞选演讲稿
2014/04/24 职场文书
努力学习演讲稿
2014/05/10 职场文书
表彰大会策划方案
2014/05/13 职场文书
法定代表人身份证明书(含说明)
2014/10/02 职场文书
2019年描写人生经典诗句大全
2019/07/08 职场文书