Расширения
Платформа расширений предоставляет механизм для вставки ваших собственных пользовательских функций в Scrapy.
Расширения — это просто обычные классы.
Настройки расширения
Расширения используют Scrapy настройки для управления своими настройками, как и любой другой код Scrapy.
Для расширений принято указывать перед настройками свое собственное имя, чтобы избежать конфликтов с существующими (и будущими) расширениями. Например, гипотетическое расширение для обработки Google Sitemaps будет использовать такие параметры, как GOOGLESITEMAP_ENABLED
, GOOGLESITEMAP_DEPTH
и т. д.
Загрузка и активация расширений
Расширения загружаются и активируются при запуске путём создания одного экземпляра класса расширения для каждого запущенного паука. Весь код инициализации расширения должен выполняться в методе класса __init__
.
Чтобы сделать расширение доступным, добавить его в параметр EXTENSIONS
в настройках Scrapy. В EXTENSIONS
каждое расширение представлено строкой: полный путь Python к имени класса расширения. Например:
EXTENSIONS = {
'scrapy.extensions.corestats.CoreStats': 500,
'scrapy.extensions.telnet.TelnetConsole': 500,
}
Как видите, параметр EXTENSIONS
— это определение, где ключи — это пути расширения, а их значения — это порядки, которые определяют порядок загрузки расширения. Параметр EXTENSIONS
объединяется с параметром EXTENSIONS_BASE
, определенным в Scrapy (и не предназначен для переопределения), а затем сортируется по порядку, чтобы получить окончательный отсортированный список включённых расширений.
Поскольку расширения обычно не зависят друг от друга, порядок их загрузки в большинстве случаев не имеет значения. Вот почему параметр EXTENSIONS_BASE
определяет все расширения в одном порядке (0
). Однако эту функцию можно использовать, если вам нужно добавить расширение, которое зависит от уже загруженных других расширений.
Доступные, включенные и отключенные расширения
Не все доступные расширения будут включены. Некоторые из них обычно зависят от конкретной настройки. Например, расширение HTTP Cache доступно по умолчанию, но отключено, если не задан параметр HTTPCACHE_ENABLED
.
Отключение расширения
Чтобы отключить расширение, которое включено по умолчанию (т. е. те, которые включены в настройку EXTENSIONS_BASE
), вы должны установить его порядок на None
. Например:
EXTENSIONS = {
'scrapy.extensions.corestats.CoreStats': None,
}
Написание собственного расширения
Каждое расширение — это класс Python. Основной точкой входа для расширения Scrapy (сюда также входят промежуточное ПО и конвейеры) является метод класса from_crawler
, который получает экземпляр Crawler
. С помощью объекта Crawler вы можете получить доступ к настройкам, сигналам, статистике, а также контролировать поведение сканирования.
Обычно расширения подключаются к сигналам и выполняют задачи, инициированные ими.
Наконец, если метод from_crawler
вызывает исключение NotConfigured
, расширение будет отключено. В противном случае расширение будет включено.
Пример расширения
Здесь мы реализуем простое расширение, чтобы проиллюстрировать концепции, описанные в предыдущем разделе. Это расширение будет регистрировать сообщение каждый раз:
паук открыт
паук закрыт
сканирует определённое количество элементоа
Расширение будет включено с помощью параметра MYEXT_ENABLED
, а количество элементов будет указано с помощью параметра MYEXT_ITEMCOUNT
.
Вот код такого расширения:
import logging
from scrapy import signals
from scrapy.exceptions import NotConfigured
logger = logging.getLogger(__name__)
class SpiderOpenCloseLogging:
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)
Справочник по встроенным расширениям
Расширения общего назначения
Расширение Log Stats
- class scrapy.extensions.logstats.LogStats
Регистрировать базовую статистику, такую как просмотренные страницы и извлеченные элементы.
Расширение Статистика Ядра (Core Stats)
- class scrapy.extensions.corestats.CoreStats
Включает сбор основной статистики, если сбор статистики включён (см. Сбор статистики).
Расширение консоли Telnet
- class scrapy.extensions.telnet.TelnetConsole
Предоставляет консоль telnet для доступа к интерпретатору Python внутри текущего запущенного процесса Scrapy, что может быть очень полезно для отладки.
Консоль telnet должна быть включена параметром TELNETCONSOLE_ENABLED
, и сервер будет прослушивать порт, указанный в TELNETCONSOLE_PORT
.
Расширение использования памяти
- class scrapy.extensions.memusage.MemoryUsage
Примечание
Это расширение не работает в Windows.
Контролирует память, используемую процессом Scrapy, который запускает паук и:
отправляет уведомление по электронной почте, когда оно превышает определенное значение
закрывает паук, когда он превышает определенное значение
Уведомления по электронной почте могут запускаться при достижении определённого значения предупреждения (MEMUSAGE_WARNING_MB
) и при достижении максимального значения (MEMUSAGE_LIMIT_MB
), что также приведёт к закрытию паука и завершению процесса Scrapy.
Это расширение включено параметром MEMUSAGE_ENABLED
и может быть настроено со следующими параметрами:
Расширение отладчика памяти
- class scrapy.extensions.memdebug.MemoryDebugger
Расширение для отладки использования памяти. Оно собирает информацию о:
объекты, не собранные сборщиком мусора Python
оставленные в живых объекты, которых не должно быть. Для получения дополнительной информации см. Отладка утечек памяти с помощью trackref
Чтобы включить это расширение, включает параметр MEMDEBUG_ENABLED
. Информация будет храниться в статистике.
Закрыть расширение паука
- class scrapy.extensions.closespider.CloseSpider
Автоматически закрывает паук при выполнении некоторых условий, используя конкретную причину закрытия для каждого условия.
Условия закрытия паука можно настроить с помощью следующих настроек:
Примечание
Когда выполняется определенное условие закрытия, запросы, которые в настоящее время находятся в очереди загрузчика (до запросов CONCURRENT_REQUESTS
), все ещё обрабатываются.
CLOSESPIDER_TIMEOUT
По умолчанию: 0
Целое число, указывающее количество секунд. Если паук остаётся открытым дольше указанного количества секунд, он автоматически закрывается по причине closespider_timeout
. Если ноль (или не установлен), пауки не будут закрыты по таймауту.
CLOSESPIDER_ITEMCOUNT
По умолчанию: 0
Целое число, определяющее количество элементов. Если паук сканирует больше, чем это количество, и данные элементы будут переданы конвейером элементов, паук будет закрыт с причиной closespider_itemcount
. Если ноль (или не установлен), пауки не будут закрыты по количеству переданных элементов.
CLOSESPIDER_PAGECOUNT
По умолчанию: 0
Целое число, указывающее максимальное количество ответов на сканирование. Если паук проползет больше, паук закроется с причиной closespider_pagecount
. Если ноль (или не установлен), пауки не будут закрыты по количеству просканированных ответов.
CLOSESPIDER_ERRORCOUNT
По умолчанию: 0
Целое число, указывающее максимальное количество ошибок, которые необходимо получить перед закрытием паука. Если паук выдаст больше ошибок, он будет закрыт с причиной closespider_errorcount
. Если ноль (или не установлен), пауки не будут закрыты по количеству ошибок.
Расширение StatsMailer
- class scrapy.extensions.statsmailer.StatsMailer
Это простое расширение можно использовать для отправки уведомлений по электронной почте каждый раз, когда домен завершил парсинг, включая собранную статистику Scrapy. Электронное письмо будет отправлено всем получателям, указанным в настройке STATSMAILER_RCPTS
.
Электронные письма можно отправлять с использованием класса MailSender
. Чтобы увидеть полный список параметров, включая примеры создания экземпляра MailSender
и использования настроек почты, см. Отправка электронной почты.
Отладка расширений
Расширение дампов трассировки стека
- class scrapy.extensions.debug.StackTraceDump
Выводит информацию о запущенном процессе при получении сигнала SIGQUIT или SIGUSR2. Выгруженная информация следующая:
статус двигателя (с использованием
scrapy.utils.engine.get_engine_status()
)живые ссылки (см. Отладка утечек памяти с помощью trackref)
трассировка стека всех потоков
После того, как трассировка стека и состояние ядра сброшены, процесс Scrapy продолжает работать в обычном режиме.
Это расширение работает только на POSIX-совместимых платформах (т. е. не в Windows), поскольку сигналы SIGQUIT и SIGUSR2 недоступны в Windows.
Есть как минимум два способа отправить Scrapy сигнал SIGQUIT:
Нажав Ctrl- во время работы процесса Scrapy (только для Linux?)
Выполнив эту команду (при условии, что
<pid>
— это идентификатор процесса Scrapy):kill -QUIT <pid>
Расширение отладчика
- class scrapy.extensions.debug.Debugger
Вызывает отладчик Python внутри запущенного процесса Scrapy при получении сигнала SIGUSR2. После выхода из отладчика процесс Scrapy продолжает нормально работать.
Для получения дополнительной информации см. Отладку в Python.
Это расширение работает только на POSIX-совместимых платформах (т.е. не в Windows).