Сигналы¶
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. Если обработчик сигнала возвращает Deferred
, Scrapy ожидает срабатывания этого Deferred
.
Рассмотрим пример:
class SignalSpider(scrapy.Spider):
name = 'signals'
start_urls = ['http://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
def item_scraped(self, item):
# Send the scraped item to the server
d = treq.post(
'http://example.com/post',
json.dumps(item).encode('ascii'),
headers={b'Content-Type': [b'application/json']}
)
# The next item will be scraped only after
# deferred (d) is fired
return d
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(),
}
См. Справочник по встроенным сигналам ниже, чтобы узнать, какие сигналы поддерживают Deferred
.
Справочник по встроенным сигналам¶
Вот список встроенных сигналов 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¶
- scrapy.signals.item_scraped(item, response, spider)¶
Отправляется, когда элемент был очищен, после того, как он прошел все этапы Элемент конвейера (без отбрасывания).
Данный сигнал поддерживает возврат отложенных сообщений от своих обработчиков.
- Параметры
item (item object) – сканируемый элемент
spider (
Spider
object) – паук, сканирующий элементresponse (
Response
object) – ответ, откуда элемент был отсканирован
item_dropped¶
- scrapy.signals.item_dropped(item, response, exception, spider)¶
Отправляется после того, как элемент был удалён из Элемент конвейера, когда на каком-то этапе возникла исключительная ситуация
DropItem
.Данный сигнал поддерживает возврат отложенных сообщений от своих обработчиков.
- Параметры
item (item object) – сброшеный элемент с Элемент конвейера
spider (
Spider
object) – паук, сканирующий элементresponse (
Response
object) – ответ, откуда был сброшен элементexception (
DropItem
exception) – исключение (которое должно быть подклассомDropItem
), из-за которого элемент был отброшен
item_error¶
- scrapy.signals.item_error(item, response, spider, failure)¶
Отправляется, когда Элемент конвейера генерирует ошибку (т. е. Вызывает исключение), за исключением исключения
DropItem
.Данный сигнал поддерживает возврат отложенных сообщений от своих обработчиков.
- Параметры
item (item object) – элемент, вызвавший ошибку в Элемент конвейера
response (
Response
object) – ответ обрабатывается при возникновении исключенияspider (
Spider
object) – паук, вызвавший исключениеfailure (twisted.python.failure.Failure) – возникло исключение
Сигналы паука¶
spider_closed¶
- scrapy.signals.spider_closed(spider, reason)¶
Отправлено после закрытия паука. Это можно использовать для освобождения ресурсов каждого паука, зарезервированных на
spider_opened
.Данный сигнал поддерживает возврат отложенных сообщений от своих обработчиков.
- Параметры
spider (
Spider
object) – паук, который был закрытreason (str) – строка, описывающая причину закрытия паука. Если он был закрыт из-за того, что паук завершил сканирование, причина в
'finished'
. В противном случае, если паук был закрыт вручную путём вызова метода движкаclose_spider
, то причина заключается в том, что было передано в аргументеreason
этого метода (который по умолчанию имеет значение'cancelled'
). Если двигатель был выключен (например, нажатием Ctrl-C, чтобы остановить его), причиной будет'shutdown'
.
spider_opened¶
- scrapy.signals.spider_opened(spider)¶
Отправляется после того, как паук открыт для сканирования. Обычно это используется для резервирования ресурсов для каждого паука, но может использоваться для любой задачи, которая должна быть выполнена при открытии паука.
Данный сигнал поддерживает возврат отложенных сообщений от своих обработчиков.
- Параметры
spider (
Spider
object) – паук, который был открыт
spider_idle¶
- scrapy.signals.spider_idle(spider)¶
Отправляется, когда паук бездействует, что означает, что паук больше не работает:
запросы, ожидающие загрузки
запросы запланированы
элементы, обрабатываемые в конвейере элементов
Если состояние холостого хода сохраняется после того, как все обработчики этого сигнала завершили работу, двигатель начинает закрывать паука. После того, как паук завершил закрытие, отправляется сигнал
spider_closed
.Вы можете вызвать исключение
DontCloseSpider
, чтобы предотвратить закрытие паука.В качестве альтернативы вы можете вызвать исключение
CloseSpider
, чтобы указать причину закрытия паука. Обработчик простоя — идеальное место для размещения некоторого кода, который вычисляет окончательные результаты пауков и соответствующим образом обновляет окончательную причину закрытия (например, устанавливая для него значение too_few_results вместо „finished“).Данный сигнал не поддерживает возврат отложенных сообщений от его обработчиков.
- Параметры
spider (
Spider
object) – бездействующий паук
Примечание
Планирование некоторых запросов в обработчике spider_idle
не даёт гарантию того, что он может предотвратить закрытие паука, хотя иногда и может. Это связано с тем, что паук может по-прежнему оставаться в режиме ожидания, если все запланированные запросы отклоняются планировщиком (например, отфильтрованы из-за дублирования).
spider_error¶
- scrapy.signals.spider_error(failure, response, spider)¶
Отправляется, когда обратный вызов паука вызывает ошибку (т. е. вызывает исключение).
Данный сигнал не поддерживает возврат отложенных сообщений от его обработчиков.
- Параметры
failure (twisted.python.failure.Failure) – возникло исключение
response (
Response
object) – ответ обрабатывается при возникновении исключенияspider (
Spider
object) – паук, вызвавший исключение
Сигналы запроса¶
request_scheduled¶
- scrapy.signals.request_scheduled(request, spider)¶
Отправляется, когда двигатель планирует
Request
для загрузки позже.Данный сигнал не поддерживает возврат отложенных сообщений от его обработчиков.
- Параметры
request (
Request
object) – запрос, который дошёл до планировщикаspider (
Spider
object) – паук, выполнивший запрос
request_dropped¶
- scrapy.signals.request_dropped(request, spider)¶
Отправляется, когда
Request
, запланированный механизмом для загрузки позже, отклоняется планировщиком.Данный сигнал не поддерживает возврат отложенных сообщений от его обработчиков.
- Параметры
request (
Request
object) – запрос, который дошёл до планировщикаspider (
Spider
object) – паук, выполнивший запрос
request_reached_downloader¶
- scrapy.signals.request_reached_downloader(request, spider)¶
Отправляется, когда
Request
достигает загрузчика.Данный сигнал не поддерживает возврат отложенных сообщений от его обработчиков.
- Параметры
request (
Request
object) – запрос, который дошёл до загрузчикаspider (
Spider
object) – паук, выполнивший запрос
request_left_downloader¶
- scrapy.signals.request_left_downloader(request, spider)¶
Добавлено в версии 2.0.
Отправляется, когда
Request
покидает загрузчик, даже в случае сбоя.Данный сигнал не поддерживает возврат отложенных сообщений от его обработчиков.
- Параметры
request (
Request
object) – запрос, который дошел до загрузчикаspider (
Spider
object) – паук, выполнивший запрос
bytes_received¶
Добавлено в версии 2.2.
- scrapy.signals.bytes_received(data, request, spider)¶
Отправляется обработчиками загрузки HTTP 1.1 и S3 при получении группы байтов для определенного запроса. Данный сигнал может запускаться несколько раз для одного и того же запроса, каждый раз с частичными данными. Например, возможный сценарий для ответа размером 25 кбайт будет состоять из двух сигналов, запущенных с 10 кбайт данных, и последнего с 5 кбайт данных.
Обработчики этого сигнала могут остановить загрузку ответа во время его выполнения, вызвав исключение
StopDownload
. Пожалуйста, обратитесь к теме Остановка загрузки ответа за дополнительной информацией и примерами.Данный сигнал не поддерживает возврат отложенных сообщений от его обработчиков.
- Параметры
data (
bytes
object) – данные, полученные обработчиком загрузкиrequest (
Request
object) – запрос, сгенерировавший загрузкуspider (
Spider
object) – паук, связанный с ответом
headers_received¶
Добавлено в версии 2.5.
- scrapy.signals.headers_received(headers, body_length, request, spider)¶
Отправляется обработчиками загрузки HTTP 1.1 и S3, когда заголовки ответа доступны для данного запроса, перед загрузкой любого дополнительного содержимого.
Обработчики этого сигнала могут остановить загрузку ответа во время его выполнения, вызвав исключение
StopDownload
. Пожалуйста, обратитесь к теме Остановка загрузки ответа за дополнительной информацией и примерами.Данный сигнал не поддерживает возврат отложенных сообщений от его обработчиков.
- Параметры
headers (
scrapy.http.headers.Headers
object) – заголовки, полученные обработчиком загрузкиbody_length (int) – ожидаемый размер тела ответа в байтах
request (
Request
object) – запрос, сгенерировавший загрузкуspider (
Spider
object) – паук, связанный с ответом
Ответные сигналы¶
response_received¶
- scrapy.signals.response_received(response, request, spider)¶
Отправляется, когда двигатель получает новый
Response
от загрузчика.Данный сигнал не поддерживает возврат отложенных сообщений от его обработчиков.
- Параметры
response (
Response
object) – получен ответrequest (
Request
object) – запрос, на который был получен ответspider (
Spider
object) – паук, для которого предназначен ответ
Примечание
Аргумент request
может не содержать исходный запрос, который достиг загрузчика, если Промежуточное ПО загрузчика изменяет объект Response
и устанавливает определённый атрибут request
.
response_downloaded¶
- scrapy.signals.response_downloaded(response, request, spider)¶
Отправлено загрузчиком сразу после загрузки
HTTPResponse
.Данный сигнал не поддерживает возврат отложенных сообщений от его обработчиков.
- Параметры
response (
Response
object) – ответ загруженrequest (
Request
object) – запрос, на который был получен ответspider (
Spider
object) – паук, для которого предназначен ответ