Scrapy学习-22-扩展开发
EXTENSIONS = {
'scrapy.contrib.corestats.CoreStats': None,
}
from scrapy import signals
from scrapy.exceptions import NotConfigured class SpiderOpenCloseLogging(object): def __init__(self, item_count):
self.item_count = item_count self.items_scraped = 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 # get the number of items from settings item_count = crawler.settings.getint('MYEXT_ITEMCOUNT', 1000) # instantiate the extension object ext = cls(item_count) # 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.item_scraped, signal=signals.item_scraped) # return the extension object return ext def spider_opened(self, spider):
spider.log("opened spider %s" % spider.name) def spider_closed(self, spider):
spider.log("closed spider %s" % spider.name) def item_scraped(self, item, spider):
self.items_scraped += 1 if self.items_scraped % self.item_count == 0:
spider.log("scraped %d items" % self.items_scraped)
记录统计扩展(Log Stats extension) 记录基本的统计信息,比如爬取的页面和条目(items) 核心统计扩展(Core Stats extension) 如果统计收集器(stats collection)启用了,该扩展开启核心统计收集 Telnet console 扩展 提供一个telnet控制台,用于进入当前执行的Scrapy进程的Python解析器 内存使用扩展(Memory usage extension) 监控Scrapy进程内存使用量并且:如果使用内存量超过某个指定值,发送提醒邮件。如果超过某个指定值,关闭spider 内存调试扩展(Memory debugger extension) 该扩展用于调试内存使用量,它收集以下信息:没有被Python垃圾回收器收集的对象。应该被销毁却仍然存活的对象 关闭spider扩展 当某些状况发生,spider会自动关闭。每种情况使用指定的关闭原因 StatsMailer extension 这个简单的扩展可用来在一个域名爬取完毕时发送提醒邮件, 包含Scrapy收集的统计信息 Debugging extensions 当收到 SIGQUIT 或 SIGUSR2 信号,spider进程的信息将会被存储下来 调试扩展(Debugger extension) 当收到 SIGUSR2 信号,将会在Scrapy进程中调用 Python debugger。 debugger退出后,Scrapy进程继续正常运行
"""
Extension for collecting core stats like items scraped and start/finish times
"""
import datetime from scrapy import signals class CoreStats(object): def __init__(self, stats):
self.stats = stats @classmethod
def from_crawler(cls, crawler):
o = cls(crawler.stats)
crawler.signals.connect(o.spider_opened, signal=signals.spider_opened)
crawler.signals.connect(o.spider_closed, signal=signals.spider_closed)
crawler.signals.connect(o.item_scraped, signal=signals.item_scraped)
crawler.signals.connect(o.item_dropped, signal=signals.item_dropped)
crawler.signals.connect(o.response_received, signal=signals.response_received)
return o def spider_opened(self, spider):
self.stats.set_value('start_time', datetime.datetime.utcnow(), spider=spider) def spider_closed(self, spider, reason):
self.stats.set_value('finish_time', datetime.datetime.utcnow(), spider=spider)
self.stats.set_value('finish_reason', reason, spider=spider) def item_scraped(self, item, spider):
self.stats.inc_value('item_scraped_count', spider=spider) def response_received(self, spider):
self.stats.inc_value('response_received_count', spider=spider) def item_dropped(self, item, spider, exception):
reason = exception.__class__.__name__
self.stats.inc_value('item_dropped_count', spider=spider)
self.stats.inc_value('item_dropped_reasons_count/%s' % reason, spider=spider)
"""
MemoryUsage extension See documentation in docs/topics/extensions.rst
"""
import sys
import socket
import logging
from pprint import pformat
from importlib import import_module from twisted.internet import task from scrapy import signals
from scrapy.exceptions import NotConfigured
from scrapy.mail import MailSender
from scrapy.utils.engine import get_engine_status logger = logging.getLogger(__name__) class MemoryUsage(object): def __init__(self, crawler):
if not crawler.settings.getbool('MEMUSAGE_ENABLED'):
raise NotConfigured
try:
# stdlib's resource module is only available on unix platforms.
self.resource = import_module('resource')
except ImportError:
raise NotConfigured self.crawler = crawler
self.warned = False
self.notify_mails = crawler.settings.getlist('MEMUSAGE_NOTIFY_MAIL')
self.limit = crawler.settings.getint('MEMUSAGE_LIMIT_MB')*1024*1024
self.warning = crawler.settings.getint('MEMUSAGE_WARNING_MB')*1024*1024
self.check_interval = crawler.settings.getfloat('MEMUSAGE_CHECK_INTERVAL_SECONDS')
self.mail = MailSender.from_settings(crawler.settings)
crawler.signals.connect(self.engine_started, signal=signals.engine_started)
crawler.signals.connect(self.engine_stopped, signal=signals.engine_stopped) @classmethod
def from_crawler(cls, crawler):
return cls(crawler) def get_virtual_size(self):
size = self.resource.getrusage(self.resource.RUSAGE_SELF).ru_maxrss
if sys.platform != 'darwin':
# on Mac OS X ru_maxrss is in bytes, on Linux it is in KB
size *= 1024
return size def engine_started(self):
self.crawler.stats.set_value('memusage/startup', self.get_virtual_size())
self.tasks = []
tsk = task.LoopingCall(self.update)
self.tasks.append(tsk)
tsk.start(self.check_interval, now=True)
if self.limit:
tsk = task.LoopingCall(self._check_limit)
self.tasks.append(tsk)
tsk.start(self.check_interval, now=True)
if self.warning:
tsk = task.LoopingCall(self._check_warning)
self.tasks.append(tsk)
tsk.start(self.check_interval, now=True) def engine_stopped(self):
for tsk in self.tasks:
if tsk.running:
tsk.stop() def update(self):
self.crawler.stats.max_value('memusage/max', self.get_virtual_size()) def _check_limit(self):
if self.get_virtual_size() > self.limit:
self.crawler.stats.set_value('memusage/limit_reached', 1)
mem = self.limit/1024/1024
logger.error("Memory usage exceeded %(memusage)dM. Shutting down Scrapy...",
{'memusage': mem}, extra={'crawler': self.crawler})
if self.notify_mails:
subj = "%s terminated: memory usage exceeded %dM at %s" % \
(self.crawler.settings['BOT_NAME'], mem, socket.gethostname())
self._send_report(self.notify_mails, subj)
self.crawler.stats.set_value('memusage/limit_notified', 1) open_spiders = self.crawler.engine.open_spiders
if open_spiders:
for spider in open_spiders:
self.crawler.engine.close_spider(spider, 'memusage_exceeded')
else:
self.crawler.stop() def _check_warning(self):
if self.warned: # warn only once
return
if self.get_virtual_size() > self.warning:
self.crawler.stats.set_value('memusage/warning_reached', 1)
mem = self.warning/1024/1024
logger.warning("Memory usage reached %(memusage)dM",
{'memusage': mem}, extra={'crawler': self.crawler})
if self.notify_mails:
subj = "%s warning: memory usage reached %dM at %s" % \
(self.crawler.settings['BOT_NAME'], mem, socket.gethostname())
self._send_report(self.notify_mails, subj)
self.crawler.stats.set_value('memusage/warning_notified', 1)
self.warned = True def _send_report(self, rcpts, subject):
"""send notification mail with some additional useful info"""
stats = self.crawler.stats
s = "Memory usage at engine startup : %dM\r\n" % (stats.get_value('memusage/startup')/1024/1024)
s += "Maximum memory usage : %dM\r\n" % (stats.get_value('memusage/max')/1024/1024)
s += "Current memory usage : %dM\r\n" % (self.get_virtual_size()/1024/1024) s += "ENGINE STATUS ------------------------------------------------------- \r\n"
s += "\r\n"
s += pformat(get_engine_status(self.crawler.engine))
s += "\r\n"
self.mail.send(rcpts, subject, s)
Scrapy学习-22-扩展开发的更多相关文章
- 以shareExtension为例学习iOS扩展开发
整体介绍 phone Extension 用法基础详解 share Extension 用法基础详解 demo链接 密码: i72z
- 【转发】NPAPI学习(Firefox和Chrome扩展开发 )
NPAPI学习(Firefox和Chrome扩展开发 ) 2011-11-08 14:41:02 by [6yang], 1172 visits, 收藏 | 返回 Firefox和Chrome扩展开发 ...
- FireFox 浏览器插件/扩展开发学习
2014-11-08 内容存档在evernote,笔记名"FireFox 浏览器插件/扩展开发学习"
- python爬虫scrapy学习之篇二
继上篇<python之urllib2简单解析HTML页面>之后学习使用Python比较有名的爬虫scrapy.网上搜到两篇相应的文档,一篇是较早版本的中文文档Scrapy 0.24 文档, ...
- scrapy学习(完全版)
scrapy1.6中文文档 scrapy1.6中文文档 scrapy中文文档 Scrapy框架 下载页面 解析页面 并发 深度 安装 scrapy学习教程 如果安装了anconda,可以在anacon ...
- python爬虫之Scrapy学习
在爬虫的路上,学习scrapy是一个必不可少的环节.也许有好多朋友此时此刻也正在接触并学习scrapy,那么很好,我们一起学习.开始接触scrapy的朋友可能会有些疑惑,毕竟是一个框架,上来不知从何学 ...
- 关于PHP扩展开发(收藏)
一.Linux shell命令: ls –lh 查看文件大小 du –a 查看文件及文件夹大小 -------------------------- nginx ------------- ...
- PHP扩展开发相关总结
1.线程安全宏定义 在TSRM/TSRM.h文件中有如下定义 #define TSRMLS_FETCH() void ***tsrm_ls = (void ***) ts_resource_ex(0, ...
- Firefox扩展开发
Firefox扩展开发 (插件开发) Extension开发 入门教程 5步走 五步走 首先需要知道什么是"Firefox插件".这里说的"插件"只是一个通 ...
随机推荐
- Flow Problem HDU - 3549
Flow Problem HDU - 3549 Network flow is a well-known difficult problem for ACMers. Given a graph, yo ...
- A1042 Shuffling Machine (20)
1042 Shuffling Machine (20)(20 分) Shuffling is a procedure used to randomize a deck of playing cards ...
- DFS:POJ1190-生日蛋糕(基础搜索)
生日蛋糕 Time Limit: 1000MS Memory Limit: 10000K 描述 7月17日是Mr.W的生日,ACM-THU为此要制作一个体积为Nπ的M层生日蛋糕,每层都是一个圆柱体. ...
- TCP/IP网络编程之套接字的多种可选项
套接字可选项进而I/O缓冲大小 我们进行套接字编程时往往只关注数据通信,而忽略了套接字具有的不同特性.但是,理解这些特性并根据实际需要进行更改也十分重要.之前我们写的程序在创建好套接字后都是未经特别操 ...
- kettle Spoon.bat闪退解决办法!
1.Java环境配置问题: java_home:D:\Program Files\Java\jdk1.7.0_25(安装jdk路径) classpath:.;%java_home%\lib\dt.ja ...
- Linux基本命令运行
文件基本操作: 增删查改: 创建文件:touch(创建文件和修改文件或者目录的时间戳),vim.vi(编辑/创建文件),mkdir(创建文件目录) 移动和修改文件名:mv 删除文件:rm –rf(强制 ...
- Nodejs-模块化结构
1.模块(一个文件就是一个模块) 获取当前脚本所在的路径 _ _dirname 文件路径 _ _filename (1)创建模块(module1.js) const fs=require('fs'); ...
- Excel动画教程50例(二)
Excel动画教程50例(二) 16.用好Excel的“搜索函数” 17.在Excel中插入超级链接 18.在Excel中打印指定页面 19.在Excel中直接编辑“宏” 20.用窗体调用“宏” 21 ...
- 使用 Region,RegionManager 在 XNA 中创建特殊区域(十八)
平方已经开发了一些 Windows Phone 上的一些游戏,算不上什么技术大牛.在这里分享一下经验,仅为了和各位朋友交流经验.平方会逐步将自己编写的类上传到托管项目中,没有什么好名字,就叫 WPXN ...
- Detect Vertical&Horizontal Segments By OpenCV
Detect Vertical&Horizontal Segments By OpenCV,and Save the data to csv. Steps: Using adaptiveThr ...