Scrapy-Redis 空跑问题,redis_key链接跑完后,自动关闭爬虫
首先解决爬虫等待,不被关闭的问题:
1、scrapy内部的信号系统会在爬虫耗尽内部队列中的request时,就会触发spider_idle信号。
2、爬虫的信号管理器收到spider_idle信号后,将调用注册spider_idle信号的处理器进行处理。
3、当该信号的所有处理器(handler)被调用后,如果spider仍然保持空闲状态, 引擎将会关闭该spider。
scrapy-redis 中的解决方案 在信号管理器上注册一个对应在spider_idle信号下的spider_idle()方法,当spider_idle触发是,信号管理器就会调用这个爬虫中的spider_idle(), Scrapy_redis 源码如下:
def spider_idle(self):
"""Schedules a request if available, otherwise waits."""
# XXX: Handle a sentinel to close the spider.
self.schedule_next_requests() # 这里调用
schedule_next_requests() 来从redis中生成新的请求
raise DontCloseSpider # 抛出不要关闭爬虫DontCloseSpider异常,保证爬虫活着
解决思路:
- 通过前面的了解,我们知道 爬虫关闭的关键是 spider_idle 信号。
- spider_idle信号只有在爬虫队列为空时才会被触发, 触发间隔为5s。
- 那么我们也可以使用同样的方式,在信号管理器上注册一个对应在spider_idle信号下的spider_idle()方法。
- 在 spider_idle() 方法中,编写结束条件来结束爬虫,这里以 判断redis 中关键key 是否为空,为条件
在settings.py 文件的目录下,创建一个名为 extensions.py 的文件,在其中写入以下代码
# -*- coding: utf-8 -*- # Define here the models for your scraped Extensions
import logging
import time
from scrapy import signals
from scrapy.exceptions import NotConfigured logger = logging.getLogger(__name__) class RedisSpiderSmartIdleClosedExensions(object): def __init__(self, idle_number, crawler):
self.crawler = crawler
self.idle_number = idle_number
self.idle_list = []
self.idle_count = 0 @classmethod
def from_crawler(cls, crawler):
# first check if the extension should be enabled and raise # NotConfigured otherwise if not crawler.settings.getbool('MYEXT_ENABLED'): raise NotConfigured # 配置仅仅支持RedisSpider
if not 'redis_key' in crawler.spidercls.__dict__.keys(): raise NotConfigured('Only supports RedisSpider') # get the number of items from settings idle_number = crawler.settings.getint('IDLE_NUMBER', 360) # instantiate the extension object ext = cls(idle_number, crawler) # connect the extension object to signals crawler.signals.connect(ext.spider_opened, signal=signals.spider_opened) crawler.signals.connect(ext.spider_closed, signal=signals.spider_closed) crawler.signals.connect(ext.spider_idle, signal=signals.spider_idle) # return the extension object return ext def spider_opened(self, spider):
logger.info("opened spider %s redis spider Idle, Continuous idle limit: %d", spider.name, self.idle_number) def spider_closed(self, spider):
logger.info("closed spider %s, idle count %d , Continuous idle count %d",
spider.name, self.idle_count, len(self.idle_list)) def spider_idle(self, spider):
self.idle_count += 1
self.idle_list.append(time.time())
idle_list_len = len(self.idle_list) # 判断 redis 中是否存在关键key, 如果key 被用完,则key就会不存在
if idle_list_len > 2 and spider.server.exists(spider.redis_key):
self.idle_list = [self.idle_list[-1]] elif idle_list_len > self.idle_number:
logger.info('\n continued idle number exceed {} Times'
'\n meet the idle shutdown conditions, will close the reptile operation'
'\n idle start time: {}, close spider time: {}'.format(self.idle_number,
self.idle_list[0], self.idle_list[0]))
# 执行关闭爬虫操作
self.crawler.engine.close_spider(spider, 'closespider_pagecount')
在settings.py 中添加以下配置, 请将 lianjia_ershoufang 替换为你的项目目录名。
MYEXT_ENABLED=True # 开启扩展
IDLE_NUMBER= # 配置空闲持续时间单位为 360个 ,一个时间单位为5s # 在 EXTENSIONS 配置,激活扩展
'EXTENSIONS'= {
'lianjia_ershoufang.extensions.RedisSpiderSmartIdleClosedExensions': ,
},
MYEXT_ENABLED: 是否启用扩展,启用扩展为 True, 不启用为 False
IDLE_NUMBER: 关闭爬虫的持续空闲次数,持续空闲次数超过IDLE_NUMBER,爬虫会被关闭。默认为 ,也就是30分钟,一分钟12个时间单位
Scrapy-Redis 空跑问题,redis_key链接跑完后,自动关闭爬虫的更多相关文章
- 解决 Scrapy-Redis 空跑问题,链接跑完后自动关闭爬虫
Scrapy-Redis 空跑问题,redis_key链接跑完后,自动关闭爬虫 问题:scrapy-redis框架中,reids存储的xxx:requests已经爬取完毕,但程序仍然一直运行,如何自动 ...
- 实现Redis Cluster并实现Python链接集群
目录 一.Redis Cluster简单介绍 二.背景 三.环境准备 3.1 主机环境 3.2 主机规划 四.部署Redis 4.1 安装Redis软件 4.2 编辑Redis配置文件 4.3 启动R ...
- ETL过程跑完后,使用python发送邮件
目标库中,如果有行数为0的表,使用python发送邮件 # -*- coding:utf-8 -*- # Author: zjc # Description:send monitor info to ...
- appium 链接真机后,运行代码,但是APP并没有启动
要淡定,链接真机后,问题一下多出来这么多,还没有启动程序,就碰到接二连三的问题. 爽到家了.慢慢解决吧. 具体问题是这样的: # coding=utf-8from appium import webd ...
- 【week6】约跑App视频链接
约跑视频链接发布在优酷,链接如下: http://v.youku.com/v_show/id_XMTc3NTcyNTcyNA==.html 秒拍视频连接: http://www.miaopai.com ...
- idea本地跑代码和链接开发机设置
- 基于Python,scrapy,redis的分布式爬虫实现框架
原文 http://www.xgezhang.com/python_scrapy_redis_crawler.html 爬虫技术,无论是在学术领域,还是在工程领域,都扮演者非常重要的角色.相比于其他 ...
- Scrapy+redis实现分布式爬虫
概述 什么是分布式爬虫 需要搭建一个由n台电脑组成的机群,然后在每一台电脑中执行同一组程序,让其对同一网络资源进行联合且分布的数据爬取. 原生Scrapy无法实现分布式的原因 原生Scrapy中调度器 ...
- 关于2440的裸跑程序中SD卡读后不能成功写入问题的讨论
问题描述: TQ2440的官方裸跑程序中,对SD卡先进行读操作,然后再写,发现不能程序卡死.倘若对SD卡先写后读,程序可以正常运行,奇哉怪哉? 写数据的关键代码--> while(i < ...
随机推荐
- course & time
- jQuery中index()方法用法实例
本文实例讲述了jQuery中index()方法用法.分享给大家供大家参考.具体分析如下: 此方法可以搜索匹配元素,并返回元素的索引值.索引值是从0开始的. 语法结构一: 当此方法没有参数的时候,返回值 ...
- Python学习---Django误删除sql表后,如何创建数据
误删除sql表后,怎么创建数据? 仅仅适合单表,多表因为涉及约束, python mangage.py makemigrations --> 生成migrations目录和根数据库对应的sql ...
- Connection to linux server with ORACLE SQL DEVELOPER
1.Link name is random 2.username and password is database account 3.host name is ip address ifconf ...
- 无线wifi
802.11n 802.11n是基于OFDM(正交频分复用Orthogonal Frequency Division Multiplexing)技术下的2.4G频段的协议,也可以工作在5G频段下. - ...
- 乘风破浪:LeetCode真题_008_String to Integer (atoi)
乘风破浪:LeetCode真题_008_String to Integer (atoi) 一.前言 将整型转换成字符串,或者将字符串转换成整型,是经常出现的,也是必要的,因此我们需要熟练的掌握,当然也 ...
- Asp.Net MVC Identity 2.2.1 使用技巧(二)
之前我们看到了新生成的项目中跟identity有关的有四个文件,这些文件是基础功能,并未开启identity的全部功能.现在我们先启用角色功能. 1.在App_Start文件夹中的IdentityCo ...
- Oracle密码过期the password has expired解决办法
oracle 出现the password has expired这个问题,今天突然发现项目访问不了,一查发现用不了,也登不进去, 这个问题由是Oracle11g密码过期的原因导致的 调试Web项目的 ...
- BZOJ 2440 完全平方数 莫比乌斯反演模板题
题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=2440 题目大意: 求第k个无平方因子的数 思路: 二分答案x,求1-x中有多少个平方因 ...
- BZOJ2223/3524:[POI2014] Couriers(主席树)
Description 给一个长度为n的序列a.1≤a[i]≤n. m组询问,每次询问一个区间[l,r],是否存在一个数在[l,r]中出现的次数大于(r-l+1)/2.如果存在,输出这个数,否则输出0 ...