# 信号
> 译者:[OSGeo 中国](https://www.osgeo.cn/)
Scrapy广泛使用信号来通知某些事件何时发生。你可以在你的垃圾项目中捕捉到这些信号(使用 [extension](extensions.html#topics-extensions) 例如)执行其他任务或扩展scrapy以添加框外未提供的功能。
即使信号提供了几个参数,捕获它们的处理程序也不需要接受所有参数——信号调度机制只传递处理程序接收的参数。
您可以通过 [信号API](api.html#topics-api-signals) .
下面是一个简单的示例,演示如何捕获信号并执行某些操作:::
```py
from scrapy import signals
from scrapy import Spider
class DmozSpider(Spider):
name = "dmoz"
allowed_domains = ["dmoz.org"]
start_urls = [
"http://www.dmoz.org/Computers/Programming/Languages/Python/Books/",
"http://www.dmoz.org/Computers/Programming/Languages/Python/Resources/",
]
@classmethod
def from_crawler(cls, crawler, *args, **kwargs):
spider = super(DmozSpider, cls).from_crawler(crawler, *args, **kwargs)
crawler.signals.connect(spider.spider_closed, signal=signals.spider_closed)
return spider
def spider_closed(self, spider):
spider.logger.info('Spider closed: %s', spider.name)
def parse(self, response):
pass
```
## 延迟信号处理程序
一些信号支持返回 [Twisted deferreds](https://twistedmatrix.com/documents/current/core/howto/defer.html) from their handlers, see the [内置信号参考](#topics-signals-ref) 下面是要知道哪些。
## 内置信号参考
这是一个零碎的内置信号列表及其含义。
### engine_started
```py
scrapy.signals.engine_started()
```
当废引擎开始爬行时发送。
此信号支持从其处理程序返回延迟。
注解
此信号可能被触发 _after_ 这个 [`spider_opened`](#std:signal-spider_opened) 信号,取决于 Spider 是如何启动的。所以 **don't** 依靠这个信号 [`spider_opened`](#std:signal-spider_opened) .
### engine_stopped
```py
scrapy.signals.engine_stopped()
```
在 Scrapy 引擎停止时发送(例如,当爬行过程完成时)。
此信号支持从其处理程序返回延迟。
### item_scraped
```py
scrapy.signals.item_scraped(item, response, spider)
```
当一个项目被刮掉时发送,当它通过所有 [项目管道](item-pipeline.html#topics-item-pipeline) 阶段(不下降)。
此信号支持从其处理程序返回延迟。
| 参数: |
* **item** (dict or [`Item`](items.html#scrapy.item.Item "scrapy.item.Item") object) -- 物品被刮掉了
* **spider** ([`Spider`](spiders.html#scrapy.spiders.Spider "scrapy.spiders.Spider") object) -- 刮掉物品的 Spider
* **response** ([`Response`](request-response.html#scrapy.http.Response "scrapy.http.Response") object) -- 从项目被刮掉的地方得到的响应
|
| --- | --- |
### item_dropped
```py
scrapy.signals.item_dropped(item, response, exception, spider)
```
从中删除项目后发送 [项目管道](item-pipeline.html#topics-item-pipeline) 当某个阶段 [`DropItem`](exceptions.html#scrapy.exceptions.DropItem "scrapy.exceptions.DropItem") 例外。
此信号支持从其处理程序返回延迟。
| 参数: |
* **item** (dict or [`Item`](items.html#scrapy.item.Item "scrapy.item.Item") object) -- 从中删除的项 [项目管道](item-pipeline.html#topics-item-pipeline)
* **spider** ([`Spider`](spiders.html#scrapy.spiders.Spider "scrapy.spiders.Spider") object) -- 刮掉物品的 Spider
* **response** ([`Response`](request-response.html#scrapy.http.Response "scrapy.http.Response") object) -- 从中删除项的响应
* **exception** ([`DropItem`](exceptions.html#scrapy.exceptions.DropItem "scrapy.exceptions.DropItem") exception) -- 例外情况(必须是 [`DropItem`](exceptions.html#scrapy.exceptions.DropItem "scrapy.exceptions.DropItem") 子类)导致该项被删除
|
| --- | --- |
### item_error
```py
scrapy.signals.item_error(item, response, spider, failure)
```
发送时 [项目管道](item-pipeline.html#topics-item-pipeline) 生成错误(即引发异常),除非 [`DropItem`](exceptions.html#scrapy.exceptions.DropItem "scrapy.exceptions.DropItem") 例外。
此信号支持从其处理程序返回延迟。
| 参数: |
* **item** (dict or [`Item`](items.html#scrapy.item.Item "scrapy.item.Item") object) -- 从中删除的项 [项目管道](item-pipeline.html#topics-item-pipeline)
* **response** ([`Response`](request-response.html#scrapy.http.Response "scrapy.http.Response") object) -- 引发异常时正在处理的响应
* **spider** ([`Spider`](spiders.html#scrapy.spiders.Spider "scrapy.spiders.Spider") object) -- 引发异常的 Spider
* **failure** ([Failure](https://twistedmatrix.com/documents/current/api/twisted.python.failure.Failure.html) object) -- 以扭曲方式引发的异常 [Failure](https://twistedmatrix.com/documents/current/api/twisted.python.failure.Failure.html) 对象
|
| --- | --- |
### spider_closed
```py
scrapy.signals.spider_closed(spider, reason)
```
在 Spider 关闭后发送。这可用于释放在上保留的每个 Spider 资源 [`spider_opened`](#std:signal-spider_opened) .
此信号支持从其处理程序返回延迟。
| 参数: |
* **spider** ([`Spider`](spiders.html#scrapy.spiders.Spider "scrapy.spiders.Spider") object) -- 已关闭的 Spider
* **reason** (_str_) -- 描述 Spider 关闭原因的字符串。如果它是因为 Spider 完成了抓取而关闭的,原因是 `'finished'` . 否则,如果通过调用 `close_spider` 引擎方法,则原因是 `reason` 该方法的参数(默认为 `'cancelled'` )如果发动机停机(例如,按ctrl-c停止发动机),原因将是 `'shutdown'` .
|
| --- | --- |
### spider_opened
```py
scrapy.signals.spider_opened(spider)
```
在 Spider 被打开爬行后发送。这通常用于为每个 Spider 保留资源,但可用于打开 Spider 时需要执行的任何任务。
此信号支持从其处理程序返回延迟。
| 参数: | **spider** ([`Spider`](spiders.html#scrapy.spiders.Spider "scrapy.spiders.Spider") object) -- 已经打开的 Spider |
| --- | --- |
### spider_idle
```py
scrapy.signals.spider_idle(spider)
```
当 Spider 空闲时发送,这意味着 Spider 没有更多:
> * 等待下载的请求
> * 计划的请求
> * 正在项管道中处理的项
如果此信号的所有处理程序完成后空闲状态仍然存在,则引擎将开始关闭 Spider 。 Spider 完成闭合后, [`spider_closed`](#std:signal-spider_closed) 发送信号。
你可以举起 [`DontCloseSpider`](exceptions.html#scrapy.exceptions.DontCloseSpider "scrapy.exceptions.DontCloseSpider") 防止 Spider 关闭的异常。
此信号不支持从其处理程序返回延迟。
| 参数: | **spider** ([`Spider`](spiders.html#scrapy.spiders.Spider "scrapy.spiders.Spider") object) -- 空转的 Spider |
| --- | --- |
注解
在您的 [`spider_idle`](#std:signal-spider_idle) 处理程序 **not** 确保它可以防止 Spider 被关闭,尽管有时可以。这是因为如果计划程序拒绝了所有计划的请求(例如,由于重复而被筛选),那么spider可能仍然处于空闲状态。
### spider_error
```py
scrapy.signals.spider_error(failure, response, spider)
```
在spider回调生成错误(即引发异常)时发送。
此信号不支持从其处理程序返回延迟。
| 参数: |
* **failure** ([Failure](https://twistedmatrix.com/documents/current/api/twisted.python.failure.Failure.html) object) -- 以扭曲方式引发的异常 [Failure](https://twistedmatrix.com/documents/current/api/twisted.python.failure.Failure.html) 对象
* **response** ([`Response`](request-response.html#scrapy.http.Response "scrapy.http.Response") object) -- 引发异常时正在处理的响应
* **spider** ([`Spider`](spiders.html#scrapy.spiders.Spider "scrapy.spiders.Spider") object) -- 引发异常的 Spider
|
| --- | --- |
### request_scheduled
```py
scrapy.signals.request_scheduled(request, spider)
```
在发动机排程A时发送 [`Request`](request-response.html#scrapy.http.Request "scrapy.http.Request") ,稍后下载。
该信号不支持从其处理程序返回延迟。
| 参数: |
* **request** ([`Request`](request-response.html#scrapy.http.Request "scrapy.http.Request") object) -- 到达调度程序的请求
* **spider** ([`Spider`](spiders.html#scrapy.spiders.Spider "scrapy.spiders.Spider") object) -- 发出请求的 Spider
|
| --- | --- |
### request_dropped
```py
scrapy.signals.request_dropped(request, spider)
```
发送时 [`Request`](request-response.html#scrapy.http.Request "scrapy.http.Request") 由引擎计划稍后下载的,被调度程序拒绝。
该信号不支持从其处理程序返回延迟。
| 参数: |
* **request** ([`Request`](request-response.html#scrapy.http.Request "scrapy.http.Request") object) -- 到达调度程序的请求
* **spider** ([`Spider`](spiders.html#scrapy.spiders.Spider "scrapy.spiders.Spider") object) -- 发出请求的 Spider
|
| --- | --- |
### request_reached_downloader
```py
scrapy.signals.request_reached_downloader(request, spider)
```
发送时 [`Request`](request-response.html#scrapy.http.Request "scrapy.http.Request") 已到达下载程序。
该信号不支持从其处理程序返回延迟。
| 参数: |
* **request** ([`Request`](request-response.html#scrapy.http.Request "scrapy.http.Request") object) -- 到达下载程序的请求
* **spider** ([`Spider`](spiders.html#scrapy.spiders.Spider "scrapy.spiders.Spider") object) -- 发出请求的 Spider
|
| --- | --- |
### response_received
```py
scrapy.signals.response_received(response, request, spider)
```
当发动机接收到新的 [`Response`](request-response.html#scrapy.http.Response "scrapy.http.Response") 从下载程序。
此信号不支持从其处理程序返回延迟。
| 参数: |
* **response** ([`Response`](request-response.html#scrapy.http.Response "scrapy.http.Response") object) -- 收到的响应
* **request** ([`Request`](request-response.html#scrapy.http.Request "scrapy.http.Request") object) -- 生成响应的请求
* **spider** ([`Spider`](spiders.html#scrapy.spiders.Spider "scrapy.spiders.Spider") object) -- 响应所针对的 Spider
|
| --- | --- |
### response_downloaded
```py
scrapy.signals.response_downloaded(response, request, spider)
```
由下载者在 `HTTPResponse` 是下载的。
此信号不支持从其处理程序返回延迟。
| 参数: |
* **response** ([`Response`](request-response.html#scrapy.http.Response "scrapy.http.Response") object) -- 已下载响应
* **request** ([`Request`](request-response.html#scrapy.http.Request "scrapy.http.Request") object) -- 生成响应的请求
* **spider** ([`Spider`](spiders.html#scrapy.spiders.Spider "scrapy.spiders.Spider") object) -- 响应所针对的 Spider
|
| --- | --- |
- 简介
- 第一步
- Scrapy at a glance
- 安装指南
- Scrapy 教程
- 实例
- 基本概念
- 命令行工具
- Spider
- 选择器
- 项目
- 项目加载器
- Scrapy shell
- 项目管道
- Feed 导出
- 请求和响应
- 链接提取器
- 设置
- 例外情况
- 内置服务
- Logging
- 统计数据集合
- 发送电子邮件
- 远程登录控制台
- Web服务
- 解决具体问题
- 常见问题
- 调试spiders
- Spider 合约
- 常用做法
- 通用爬虫
- 使用浏览器的开发人员工具进行抓取
- 调试内存泄漏
- 下载和处理文件和图像
- 部署 Spider
- AutoThrottle 扩展
- Benchmarking
- 作业:暂停和恢复爬行
- 延伸 Scrapy
- 体系结构概述
- 下载器中间件
- Spider 中间件
- 扩展
- 核心API
- 信号
- 条目导出器
- 其余所有
- 发行说明
- 为 Scrapy 贡献
- 版本控制和API稳定性