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函数中参数的使用及默认参数的陷阱
Mar 13 Python
Python内置函数——__import__ 的使用方法
Nov 24 Python
django请求返回不同的类型图片json,xml,html的实例
May 22 Python
python使用magic模块进行文件类型识别方法
Dec 08 Python
pyhanlp安装介绍和简单应用
Feb 22 Python
Pycharm连接远程服务器并实现远程调试的实现
Aug 02 Python
TensorFlow2.1.0最新版本安装详细教程
Apr 08 Python
pandas中read_csv、rolling、expanding用法详解
Apr 21 Python
Python私有属性私有方法应用实例解析
Sep 15 Python
pycharm最新激活码有效期至2100年(亲测可用)
Feb 05 Python
OpenCV-Python使用cv2实现傅里叶变换
Jun 09 Python
Python卷积神经网络图片分类框架详解分析
Nov 07 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
第四节--构造函数和析构函数
2006/11/16 PHP
php中通过Ajax如何实现异步文件上传的代码实例
2011/05/07 PHP
浅析十款PHP开发框架的对比
2013/07/05 PHP
PHP实现QQ空间自动回复说说的方法
2015/12/02 PHP
yii用户注册表单验证实例
2015/12/26 PHP
最新28个很棒的jQuery 教程
2011/05/28 Javascript
JQuery判断子iframe何时加载完成解决方案
2013/08/20 Javascript
jquery+html5烂漫爱心表白动画代码分享
2015/08/24 Javascript
举例说明如何为JavaScript的方法参数设置默认值
2015/11/17 Javascript
JavaScript提高性能知识点汇总
2016/01/15 Javascript
悬浮广告方法日常收集整理
2016/03/18 Javascript
JavaScript解八皇后问题的方法总结
2016/06/12 Javascript
AngularJS学习笔记之表单验证功能实例详解
2017/07/06 Javascript
浅谈Node.js CVE-2017-14849 漏洞分析(详细步骤)
2017/11/10 Javascript
vue中使用codemirror的实例详解
2018/11/01 Javascript
vue + element-ui的分页问题实现
2018/12/17 Javascript
微信小程序使用二次贝塞尔曲线画波浪
2018/12/25 Javascript
微信小程序全局变量功能与用法详解
2019/01/22 Javascript
Nuxt.js的路由跳转操作(页面跳转nuxt-link)
2020/11/06 Javascript
[00:05]ChinaJoy现场 DOTA2玩家高呼“CN DOTA BEST DOTA”
2019/08/04 DOTA
Python 随机生成中文验证码的实例代码
2013/03/20 Python
python发送arp欺骗攻击代码分析
2014/01/16 Python
在Python中使用第三方模块的教程
2015/04/27 Python
全面解析Python的While循环语句的使用方法
2015/10/13 Python
pandas重新生成索引的方法
2018/11/06 Python
Python提取频域特征知识点浅析
2019/03/04 Python
python 遍历pd.Series的index和value
2019/11/26 Python
Python自动化之UnitTest框架实战记录
2020/09/08 Python
HTML5通过调用canvas对象的getContext()方法来获取绘图环境
2014/06/23 HTML / CSS
美国最流行的男士时尚网站:Touch of Modern
2018/02/05 全球购物
英国和爱尔兰的自炊式豪华度假小屋:Rural Retreats
2018/06/08 全球购物
WiFi云数码相框:Nixplay
2018/07/05 全球购物
.NET现在共支持多少种语言
2014/02/26 面试题
安全资金保障制度
2014/01/23 职场文书
2014年房产销售工作总结
2014/12/08 职场文书
离婚案件原告代理词
2015/05/23 职场文书