信号¶
Scrapy 广泛使用信号来通知何时发生某些事件。您可以在您的 Scrapy 项目中捕获一些这些信号(例如,使用扩展),以执行其他任务或扩展 Scrapy 以添加开箱即用时未提供的功能。
即使信号提供多个参数,捕获它们的处理程序也不需要接受所有参数 - 信号分派机制只会传递处理程序接收到的参数。
您可以通过信号 API连接到信号(或发送您自己的信号)。
以下是一个简单的示例,展示了如何捕获信号并执行某些操作
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
延迟信号处理器¶
某些信号支持从其处理程序返回Deferred
或可等待对象,允许您运行不会阻塞 Scrapy 的异步代码。如果信号处理程序返回这些对象之一,Scrapy 会等待该异步操作完成。
让我们使用协程举个例子
import scrapy
class SignalSpider(scrapy.Spider):
name = "signals"
start_urls = ["https://quotes.toscrape.com/page/1/"]
@classmethod
def from_crawler(cls, crawler, *args, **kwargs):
spider = super(SignalSpider, cls).from_crawler(crawler, *args, **kwargs)
crawler.signals.connect(spider.item_scraped, signal=signals.item_scraped)
return spider
async def item_scraped(self, item):
# Send the scraped item to the server
response = await treq.post(
"http://example.com/post",
json.dumps(item).encode("ascii"),
headers={b"Content-Type": [b"application/json"]},
)
return response
def parse(self, response):
for quote in response.css("div.quote"):
yield {
"text": quote.css("span.text::text").get(),
"author": quote.css("small.author::text").get(),
"tags": quote.css("div.tags a.tag::text").getall(),
}
内置信号参考¶
以下是 Scrapy 内置信号及其含义的列表。
引擎信号¶
engine_started¶
- scrapy.signals.engine_started()¶
当 Scrapy 引擎开始爬取时发送。
此信号支持从其处理程序返回延迟。
注意
此信号可能会在spider_opened
信号之后触发,具体取决于爬虫的启动方式。因此,**不要**依赖于此信号在spider_opened
之前触发。
engine_stopped¶
- scrapy.signals.engine_stopped()¶
当 Scrapy 引擎停止时发送(例如,当爬取过程完成时)。
此信号支持从其处理程序返回延迟。
数据项信号¶
注意
由于最多有CONCURRENT_ITEMS
个数据项并行处理,因此许多延迟使用DeferredList
一起触发。因此,下一批等待DeferredList
触发,然后为下一批抓取的数据项运行相应的数据项信号处理程序。
item_scraped¶
item_dropped¶
item_error¶
- scrapy.signals.item_error(item, response, spider, failure)¶
当数据项管道 生成错误(即引发异常)时发送,除了
DropItem
异常。此信号支持从其处理程序返回延迟。
- 参数:
response (
Response
|None
) – 发生异常时正在处理的响应,或如果它是从start_requests()
生成的,则为None
。spider (
Spider
对象) – 引发异常的爬虫failure (twisted.python.failure.Failure) – 引发的异常
爬虫信号¶
spider_closed¶
- scrapy.signals.spider_closed(spider, reason)¶
在蜘蛛关闭后发送。这可以用于释放在
spider_opened
中预留的每个蜘蛛的资源。此信号支持从其处理程序返回延迟。
spider_opened¶
spider_idle¶
- scrapy.signals.spider_idle(spider)¶
当蜘蛛处于空闲状态时发送,这意味着蜘蛛没有进一步的
等待下载的请求
已安排的请求
正在项目管道中处理的项目
如果在该信号的所有处理程序完成之后,空闲状态仍然存在,则引擎开始关闭蜘蛛。在蜘蛛完成关闭后,将发送
spider_closed
信号。您可以引发
DontCloseSpider
异常以防止蜘蛛关闭。或者,您可以引发
CloseSpider
异常以提供自定义蜘蛛关闭原因。空闲处理程序是放置一些代码以评估最终蜘蛛结果并相应地更新最终关闭原因(例如,将其设置为“too_few_results”而不是“finished”)的理想位置。此信号不支持从其处理程序返回延迟。
- 参数:
spider (
Spider
对象) – 处于空闲状态的蜘蛛
注意
在您的spider_idle
处理程序中安排一些请求**不能**保证它可以防止蜘蛛关闭,尽管有时可以。这是因为如果所有计划的请求都被调度程序拒绝(例如,由于重复而被过滤),蜘蛛可能仍然保持空闲状态。
spider_error¶
- scrapy.signals.spider_error(failure, response, spider)¶
当蜘蛛回调生成错误(即引发异常)时发送。
此信号不支持从其处理程序返回延迟。
- 参数:
failure (twisted.python.failure.Failure) – 引发的异常
response (
Response
对象) – 引发异常时正在处理的响应spider (
Spider
对象) – 引发异常的爬虫
feed_slot_closed¶
feed_exporter_closed¶
- scrapy.signals.feed_exporter_closed()¶
当feed 导出扩展关闭时发送,在扩展处理
spider_closed
信号期间,在所有feed导出都已处理之后。此信号支持从其处理程序返回延迟。
请求信号¶
request_scheduled¶
- scrapy.signals.request_scheduled(request, spider)¶
当引擎被要求安排一个
Request
以便稍后下载时发送,在请求到达调度程序之前。引发
IgnoreRequest
以在请求到达调度程序之前将其丢弃。此信号不支持从其处理程序返回延迟。
版本 2.11.2 中的新功能: 允许使用
IgnoreRequest
丢弃请求。- 参数:
request (
Request
对象) – 已到达调度程序的请求spider (
Spider
对象) – 产生请求的蜘蛛
request_dropped¶
request_reached_downloader¶
request_left_downloader¶
bytes_received¶
版本 2.2 中的新功能。
- scrapy.signals.bytes_received(data, request, spider)¶
当为特定请求接收一组字节时,由 HTTP 1.1 和 S3 下载处理程序发送。此信号可能会为同一个请求触发多次,每次都包含部分数据。例如,对于 25 kb 响应,一个可能的场景是触发两个带有 10 kb 数据的信号,以及一个带有 5 kb 数据的最终信号。
此信号的处理程序可以在响应正在下载过程中停止下载,方法是引发
StopDownload
异常。有关其他信息和示例,请参阅停止下载响应主题。此信号不支持从其处理程序返回延迟。
headers_received¶
2.5 版本新增。
- scrapy.signals.headers_received(headers, body_length, request, spider)¶
当给定请求的响应头可用时,在下载任何其他内容之前,由 HTTP 1.1 和 S3 下载处理器发送。
此信号的处理程序可以在响应正在下载过程中停止下载,方法是引发
StopDownload
异常。有关其他信息和示例,请参阅停止下载响应主题。此信号不支持从其处理程序返回延迟。
- 参数:
headers (
scrapy.http.headers.Headers
对象) – 下载处理器接收到的头信息body_length (int) – 响应体预计大小(字节)
request (
Request
对象) – 生成下载的请求spider (
Spider
对象) – 与响应关联的蜘蛛