# 扩展
> 译者:[OSGeo 中国](https://www.osgeo.cn/)
扩展框架提供了一种将您自己的自定义功能插入到Scrapy中的机制。
扩展只是在初始化扩展时,在scrapy启动时实例化的常规类。
## 扩展设置
扩展使用 [Scrapy settings](settings.html#topics-settings) 管理他们的设置,就像任何其他零碎的代码一样。
扩展通常会在其设置前面加上自己的名称,以避免与现有(和将来)扩展冲突。例如,要处理的假设扩展 [Google Sitemaps](https://en.wikipedia.org/wiki/Sitemaps) 将使用如下设置 `GOOGLESITEMAP_ENABLED` , `GOOGLESITEMAP_DEPTH` 等等。
## 加载和激活扩展
通过实例化扩展类的单个实例,可以在启动时加载和激活扩展。因此,所有扩展初始化代码都必须在类构造函数中执行。( `__init__` 方法)。
若要使扩展名可用,请将其添加到 [`EXTENSIONS`](settings.html#std:setting-EXTENSIONS) 设置你的剪贴设置。在 [`EXTENSIONS`](settings.html#std:setting-EXTENSIONS) ,每个扩展都由一个字符串表示:扩展类名的完整python路径。例如::
```py
EXTENSIONS = {
'scrapy.extensions.corestats.CoreStats': 500,
'scrapy.extensions.telnet.TelnetConsole': 500,
}
```
如你所见, [`EXTENSIONS`](settings.html#std:setting-EXTENSIONS) 设置是一个dict,其中键是扩展路径,它们的值是定义扩展的顺序。 _loading_ 秩序。这个 [`EXTENSIONS`](settings.html#std:setting-EXTENSIONS) 设置与合并 [`EXTENSIONS_BASE`](settings.html#std:setting-EXTENSIONS_BASE) 在scrappy中定义的设置(不打算被重写),然后按顺序排序,以获得已启用扩展的最终排序列表。
由于扩展通常不相互依赖,因此在大多数情况下,它们的加载顺序是不相关的。这就是为什么 [`EXTENSIONS_BASE`](settings.html#std:setting-EXTENSIONS_BASE) 设置以相同的顺序定义所有扩展( `0` )但是,如果需要添加依赖于已加载的其他扩展的扩展,则可以利用此功能。
## 可用、启用和禁用扩展
并非所有可用的扩展都将启用。其中一些通常取决于特定的设置。例如,HTTP缓存扩展在默认情况下是可用的,但在 [`HTTPCACHE_ENABLED`](downloader-middleware.html#std:setting-HTTPCACHE_ENABLED) 设置设置。
## 禁用扩展
为了禁用默认启用的扩展(即包含在 [`EXTENSIONS_BASE`](settings.html#std:setting-EXTENSIONS_BASE) 设置)必须将其顺序设置为 `None` . 例如::
```py
EXTENSIONS = {
'scrapy.extensions.corestats.CoreStats': None,
}
```
## 编写自己的扩展名
每个扩展都是一个Python类。 Scrapy 扩展(也包括中间产品和管道)的主要入口点是 `from_crawler` 类方法,它接收 `Crawler` 实例。通过爬虫对象,您可以访问设置、信号、统计信息,还可以控制爬行行为。
通常,扩展连接到 [signals](signals.html#topics-signals) 并执行由它们触发的任务。
最后,如果 `from_crawler` 方法引发 [`NotConfigured`](exceptions.html#scrapy.exceptions.NotConfigured "scrapy.exceptions.NotConfigured") 异常,扩展将被禁用。否则,将启用扩展。
### 样本扩展
在这里,我们将实现一个简单的扩展来说明前一节中描述的概念。此扩展将每次记录一条消息:
* Spider 被打开了
* Spider 被关闭了
* 特定数量的物品被刮掉
扩展将通过 `MYEXT_ENABLED` 设置和项目数将通过 `MYEXT_ITEMCOUNT` 设置。
这是这种扩展的代码:
```py
import logging
from scrapy import signals
from scrapy.exceptions import NotConfigured
logger = logging.getLogger(__name__)
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):
logger.info("opened spider %s", spider.name)
def spider_closed(self, spider):
logger.info("closed spider %s", spider.name)
def item_scraped(self, item, spider):
self.items_scraped += 1
if self.items_scraped % self.item_count == 0:
logger.info("scraped %d items", self.items_scraped)
```
## 内置扩展引用
### 通用扩展
#### 日志统计扩展
```py
class scrapy.extensions.logstats.LogStats
```
记录基本的统计信息,如已爬网的页面和已擦除的项目。
#### 核心统计扩展
```py
class scrapy.extensions.corestats.CoreStats
```
启用核心统计信息集合,前提是已启用统计信息集合(请参见 [统计数据集合](stats.html#topics-stats) )
#### Telnet控制台扩展
```py
class scrapy.extensions.telnet.TelnetConsole
```
提供一个telnet控制台,用于进入当前运行的scrapy进程中的python解释器,这对于调试非常有用。
telnet控制台必须由 [`TELNETCONSOLE_ENABLED`](settings.html#std:setting-TELNETCONSOLE_ENABLED) 设置,服务器将侦听中指定的端口 [`TELNETCONSOLE_PORT`](telnetconsole.html#std:setting-TELNETCONSOLE_PORT) .
#### 内存使用扩展
```py
class scrapy.extensions.memusage.MemoryUsage
```
注解
此扩展在Windows中不起作用。
监视运行spider的scrapy进程使用的内存,并:
1. 超过某个值时发送通知电子邮件
2. 当 Spider 超过某个值时关闭 Spider
当达到某个警告值时,可以触发通知电子邮件。( [`MEMUSAGE_WARNING_MB`](settings.html#std:setting-MEMUSAGE_WARNING_MB) )当达到最大值时( [`MEMUSAGE_LIMIT_MB`](settings.html#std:setting-MEMUSAGE_LIMIT_MB) )这也会导致 Spider 被关闭, Scrapy 过程被终止。
此扩展由 [`MEMUSAGE_ENABLED`](settings.html#std:setting-MEMUSAGE_ENABLED) 设置,可以使用以下设置进行配置:
* [`MEMUSAGE_LIMIT_MB`](settings.html#std:setting-MEMUSAGE_LIMIT_MB)
* [`MEMUSAGE_WARNING_MB`](settings.html#std:setting-MEMUSAGE_WARNING_MB)
* [`MEMUSAGE_NOTIFY_MAIL`](settings.html#std:setting-MEMUSAGE_NOTIFY_MAIL)
* [`MEMUSAGE_CHECK_INTERVAL_SECONDS`](settings.html#std:setting-MEMUSAGE_CHECK_INTERVAL_SECONDS)
#### 内存调试器扩展
```py
class scrapy.extensions.memdebug.MemoryDebugger
```
调试内存使用情况的扩展。它收集以下信息:
* python垃圾收集器未收集的对象
* 不应该保留的对象。有关详细信息,请参阅 [使用调试内存泄漏 trackref](leaks.html#topics-leaks-trackrefs)
要启用此扩展,请打开 [`MEMDEBUG_ENABLED`](settings.html#std:setting-MEMDEBUG_ENABLED) 设置。信息将存储在统计信息中。
#### 关闭星形延长件
```py
class scrapy.extensions.closespider.CloseSpider
```
当满足某些条件时,使用每个条件的特定关闭原因自动关闭 Spider 。
关闭 Spider 的条件可以通过以下设置进行配置:
* [`CLOSESPIDER_TIMEOUT`](#std:setting-CLOSESPIDER_TIMEOUT)
* [`CLOSESPIDER_ITEMCOUNT`](#std:setting-CLOSESPIDER_ITEMCOUNT)
* [`CLOSESPIDER_PAGECOUNT`](#std:setting-CLOSESPIDER_PAGECOUNT)
* [`CLOSESPIDER_ERRORCOUNT`](#std:setting-CLOSESPIDER_ERRORCOUNT)
##### CLOSESPIDER_TIMEOUT
违约: `0`
指定秒数的整数。如果 Spider 保持打开超过该秒数,它将自动关闭,原因如下 `closespider_timeout` . 如果为零(或未设置), Spider 将不会在超时时关闭。
##### CLOSESPIDER_ITEMCOUNT
违约: `0`
指定若干项的整数。如果spider的抓取量超过该数量,并且这些项目通过项目管道,那么spider将关闭,原因是 `closespider_itemcount` . 当前在下载器队列中的请求(最多 [`CONCURRENT_REQUESTS`](settings.html#std:setting-CONCURRENT_REQUESTS) 请求)仍在处理中。如果为零(或未设置), Spider 将不会被通过的项目数关闭。
##### CLOSESPIDER_PAGECOUNT
0.11 新版功能.
违约: `0`
指定要爬网的最大响应数的整数。如果 Spider 爬得比这个还多, Spider 会被关闭的,原因是 `closespider_pagecount` . 如果为零(或未设置), Spider 将不会被爬行响应的数量关闭。
##### CLOSESPIDER_ERRORCOUNT
0.11 新版功能.
违约: `0`
一个整数,指定关闭 Spider 之前要接收的最大错误数。如果spider生成的错误数量超过该数量,则会关闭它并说明原因。 `closespider_errorcount` . 如果为零(或未设置), Spider 将不会被错误数关闭。
#### StatsMailer扩展
```py
class scrapy.extensions.statsmailer.StatsMailer
```
这个简单的扩展可用于在域完成抓取时发送通知电子邮件,包括收集到的残缺统计信息。电子邮件将发送给 [`STATSMAILER_RCPTS`](settings.html#std:setting-STATSMAILER_RCPTS) 设置。
### 调试扩展
#### 堆栈跟踪转储扩展
```py
class scrapy.extensions.debug.StackTraceDump
```
当 [SIGQUIT](https://en.wikipedia.org/wiki/SIGQUIT) 或 [SIGUSR2](https://en.wikipedia.org/wiki/SIGUSR1_and_SIGUSR2) 接收到信号。转储的信息如下:
1. 发动机状态(使用 `scrapy.utils.engine.get_engine_status()` )
2. 实时参考(请参见 [使用调试内存泄漏 trackref](leaks.html#topics-leaks-trackrefs) )
3. 所有线程的堆栈跟踪
在转储堆栈跟踪和引擎状态后,碎片进程继续正常运行。
此扩展仅在符合POSIX的平台(即,不是Windows)上工作,因为 [SIGQUIT](https://en.wikipedia.org/wiki/SIGQUIT) 和 [SIGUSR2](https://en.wikipedia.org/wiki/SIGUSR1_and_SIGUSR2) Windows上没有信号。
至少有两种方法可以将Scrapy [SIGQUIT](https://en.wikipedia.org/wiki/SIGQUIT) 信号:
1. 按ctrl-while a scrapy process is running(Linux only?)
2. 通过运行此命令(假设 `<pid>` 是 Scrapy 流程的流程ID)::
```py
kill -QUIT <pid>
```
#### 调试器扩展
```py
class scrapy.extensions.debug.Debugger
```
调用一个 [Python debugger](https://docs.python.org/2/library/pdb.html) 当 [SIGUSR2](https://en.wikipedia.org/wiki/SIGUSR1_and_SIGUSR2) 接收到信号。退出调试程序后,碎片处理程序继续正常运行。
有关详细信息,请参阅 [Debugging in Python](https://pythonconquerstheuniverse.wordpress.com/2009/09/10/debugging-in-python/) .
此扩展仅在符合POSIX的平台(即,不是Windows)上工作。
- 简介
- 第一步
- Scrapy at a glance
- 安装指南
- Scrapy 教程
- 实例
- 基本概念
- 命令行工具
- Spider
- 选择器
- 项目
- 项目加载器
- Scrapy shell
- 项目管道
- Feed 导出
- 请求和响应
- 链接提取器
- 设置
- 例外情况
- 内置服务
- Logging
- 统计数据集合
- 发送电子邮件
- 远程登录控制台
- Web服务
- 解决具体问题
- 常见问题
- 调试spiders
- Spider 合约
- 常用做法
- 通用爬虫
- 使用浏览器的开发人员工具进行抓取
- 调试内存泄漏
- 下载和处理文件和图像
- 部署 Spider
- AutoThrottle 扩展
- Benchmarking
- 作业:暂停和恢复爬行
- 延伸 Scrapy
- 体系结构概述
- 下载器中间件
- Spider 中间件
- 扩展
- 核心API
- 信号
- 条目导出器
- 其余所有
- 发行说明
- 为 Scrapy 贡献
- 版本控制和API稳定性