扩展
扩展是 组件,允许您将自己的自定义功能插入到 Scrapy 中。
与其他组件不同,扩展在 Scrapy 中没有特定的角色。它们是“通配符”组件,可用于任何不适合其他类型组件角色的功能。
加载和激活扩展
扩展在启动时加载,方法是为每个正在运行的爬虫创建一个扩展类的单个实例。
要启用扩展,请将其添加到 EXTENSIONS
设置中。例如
EXTENSIONS = {
"scrapy.extensions.corestats.CoreStats": 500,
"scrapy.extensions.telnet.TelnetConsole": 500,
}
EXTENSIONS
与 EXTENSIONS_BASE
(不应被覆盖) 合并,结果值中的优先级决定了加载顺序。
由于扩展通常不相互依赖,因此在大多数情况下,它们的加载顺序并不重要。这就是为什么 EXTENSIONS_BASE
设置将所有扩展的顺序定义为相同 (0
)。但是,如果您添加的扩展依赖于其他已加载的扩展,则可能需要仔细使用优先级。
编写自己的扩展
每个扩展都是一个 组件。
通常,扩展连接到 信号 并执行由它们触发的任务。
示例扩展
这里我们将实现一个简单的扩展来阐述前一节中描述的概念。这个扩展将在每次发生以下情况时记录一条消息
爬虫被打开
爬虫被关闭
抓取了特定数量的项目
该扩展将通过 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)
内置扩展参考
通用扩展
日志统计扩展
记录抓取页面和抓取项目等基本统计数据。
核心统计扩展
启用核心统计数据的收集,前提是统计数据收集已启用 (参见 统计数据收集)。
Telnet 控制台扩展
提供一个 telnet 控制台,用于进入当前运行的 Scrapy 进程内的 Python 解释器,这对调试非常有用。
必须通过 TELNETCONSOLE_ENABLED
设置启用 telnet 控制台,服务器将在 TELNETCONSOLE_PORT
中指定的端口监听。
内存使用扩展
注意
此扩展在 Windows 中不起作用。
监视运行爬虫的 Scrapy 进程使用的内存,并在
超出特定值时发送通知电子邮件
超出特定值时关闭爬虫
当达到特定警告值 (MEMUSAGE_WARNING_MB
) 和达到最大值 (MEMUSAGE_LIMIT_MB
) 时,可以触发通知电子邮件,达到最大值时还会导致爬虫被关闭,Scrapy 进程被终止。
此扩展通过 MEMUSAGE_ENABLED
设置启用,可以使用以下设置进行配置
内存调试器扩展
用于调试内存使用的扩展。它收集关于以下信息
Python 垃圾回收器未收集的对象
不应继续存活的对象。更多信息请参见 使用 trackref 调试内存泄漏
要启用此扩展,请开启 MEMDEBUG_ENABLED
设置。信息将存储在统计数据中。
爬虫状态扩展
通过在爬取前加载并在爬取后保存来管理爬虫状态数据。
为 JOBDIR
设置赋值以启用此扩展。启用后,此扩展会管理您的 Spider
实例的 state
属性
当您的爬虫关闭时 (
spider_closed
),其state
属性的内容会被序列化到JOBDIR
文件夹中名为spider.state
的文件中。当您的爬虫打开时 (
spider_opened
),如果在JOBDIR
文件夹中存在先前生成的spider.state
文件,则会将其加载到state
属性中。
示例请参见 在批次之间保持持久状态。
关闭爬虫扩展
在满足某些条件时自动关闭爬虫,并为每个条件使用特定的关闭原因。
可以通过以下设置配置关闭爬虫的条件
注意
当满足特定关闭条件时,当前位于下载器队列中的请求 (最多 CONCURRENT_REQUESTS
个请求) 仍然会被处理。
CLOSESPIDER_TIMEOUT
默认值: 0
一个整数,指定秒数。如果爬虫打开时间超过此秒数,它将自动以原因 closespider_timeout
关闭。如果为零(或未设置),爬虫不会因超时而关闭。
CLOSESPIDER_TIMEOUT_NO_ITEM
默认值: 0
一个整数,指定秒数。如果爬虫在最后指定秒数内没有产生任何项目,它将以原因 closespider_timeout_no_item
关闭。如果为零(或未设置),爬虫不会因为没有产生任何项目而被关闭。
CLOSESPIDER_ITEMCOUNT
默认值: 0
一个整数,指定项目数量。如果爬虫抓取的项目数量超过此值且这些项目通过了项目管道,爬虫将以原因 closespider_itemcount
关闭。如果为零(或未设置),爬虫不会因为通过的项目数量而被关闭。
CLOSESPIDER_PAGECOUNT
默认值: 0
一个整数,指定要爬取的最大响应数量。如果爬虫爬取的响应数量超过此值,爬虫将以原因 closespider_pagecount
关闭。如果为零(或未设置),爬虫不会因爬取的响应数量而被关闭。
CLOSESPIDER_PAGECOUNT_NO_ITEM
默认值: 0
一个整数,指定在没有抓取项目的情况下连续爬取的最大响应数量。如果爬虫连续爬取的响应数量超过此值且在此期间没有抓取到项目,爬虫将以原因 closespider_pagecount_no_item
关闭。如果为零(或未设置),爬虫不会因没有抓取项目的爬取响应数量而被关闭。
CLOSESPIDER_ERRORCOUNT
默认值: 0
一个整数,指定在关闭爬虫前接收的最大错误数量。如果爬虫产生的错误数量超过此值,它将以原因 closespider_errorcount
关闭。如果为零(或未设置),爬虫不会因错误数量而被关闭。
统计邮件发送扩展
这个简单的扩展可以在每次一个域完成抓取时发送通知电子邮件,包括收集到的 Scrapy 统计数据。电子邮件将发送给 STATSMAILER_RCPTS
设置中指定的所有收件人。
可以使用 MailSender
类发送电子邮件。要查看完整的参数列表,包括如何实例化 MailSender
和使用邮件设置的示例,请参见 发送电子邮件。
周期性日志扩展
此扩展定期将丰富的统计数据以 JSON 对象形式记录到日志中
2023-08-04 02:30:57 [scrapy.extensions.logstats] INFO: Crawled 976 pages (at 162 pages/min), scraped 925 items (at 161 items/min)
2023-08-04 02:30:57 [scrapy.extensions.periodic_log] INFO: {
"delta": {
"downloader/request_bytes": 55582,
"downloader/request_count": 162,
"downloader/request_method_count/GET": 162,
"downloader/response_bytes": 618133,
"downloader/response_count": 162,
"downloader/response_status_count/200": 162,
"item_scraped_count": 161
},
"stats": {
"downloader/request_bytes": 338243,
"downloader/request_count": 992,
"downloader/request_method_count/GET": 992,
"downloader/response_bytes": 3836736,
"downloader/response_count": 976,
"downloader/response_status_count/200": 976,
"item_scraped_count": 925,
"log_count/INFO": 21,
"log_count/WARNING": 1,
"scheduler/dequeued": 992,
"scheduler/dequeued/memory": 992,
"scheduler/enqueued": 1050,
"scheduler/enqueued/memory": 1050
},
"time": {
"elapsed": 360.008903,
"log_interval": 60.0,
"log_interval_real": 60.006694,
"start_time": "2023-08-03 23:24:57",
"utcnow": "2023-08-03 23:30:57"
}
}
此扩展记录以下可配置的部分
"delta"
显示自上次统计日志消息以来一些数字统计数据如何变化。PERIODIC_LOG_DELTA
设置确定目标统计数据。它们必须是int
或float
值。"stats"
显示一些统计数据的当前值。PERIODIC_LOG_STATS
设置确定目标统计数据。"time"
显示详细的时间数据。PERIODIC_LOG_TIMING_ENABLED
设置确定是否显示此部分。
此扩展在开始时记录数据,然后按通过 LOGSTATS_INTERVAL
设置配置的固定时间间隔记录,最后在爬取结束前记录。
示例扩展配置
custom_settings = {
"LOG_LEVEL": "INFO",
"PERIODIC_LOG_STATS": {
"include": ["downloader/", "scheduler/", "log_count/", "item_scraped_count/"],
},
"PERIODIC_LOG_DELTA": {"include": ["downloader/"]},
"PERIODIC_LOG_TIMING_ENABLED": True,
"EXTENSIONS": {
"scrapy.extensions.periodic_log.PeriodicLog": 0,
},
}
PERIODIC_LOG_DELTA
默认值: None
"PERIODIC_LOG_DELTA": True
- 显示所有int
和float
统计值的变化量。"PERIODIC_LOG_DELTA": {"include": ["downloader/", "scheduler/"]}
- 显示名称包含任何配置子字符串的统计数据的变化量。"PERIODIC_LOG_DELTA": {"exclude": ["downloader/"]}
- 显示名称不包含任何配置子字符串的所有统计数据的变化量。
PERIODIC_LOG_STATS
默认值: None
"PERIODIC_LOG_STATS": True
- 显示所有统计数据的当前值。"PERIODIC_LOG_STATS": {"include": ["downloader/", "scheduler/"]}
- 显示名称包含任何配置子字符串的统计数据的当前值。"PERIODIC_LOG_STATS": {"exclude": ["downloader/"]}
- 显示名称不包含任何配置子字符串的所有统计数据的当前值。
PERIODIC_LOG_TIMING_ENABLED
默认值: False
True
启用时间数据记录 (即 "time"
部分)。
调试扩展
堆栈跟踪转储扩展
- class scrapy.extensions.periodic_log.StackTraceDump
当收到 SIGQUIT 或 SIGUSR2 信号时,转储有关运行进程的信息。转储的信息如下
引擎状态 (使用
scrapy.utils.engine.get_engine_status()
)活动引用 (参见 使用 trackref 调试内存泄漏)
所有线程的堆栈跟踪
转储堆栈跟踪和引擎状态后,Scrapy 进程继续正常运行。
此扩展仅适用于符合 POSIX 标准的平台 (即非 Windows),因为 SIGQUIT 和 SIGUSR2 信号在 Windows 上不可用。
至少有两种方法可以向 Scrapy 发送 SIGQUIT 信号
在 Scrapy 进程运行时按下 Ctrl-\ (仅限 Linux?)
通过运行此命令 (假设
<pid>
是 Scrapy 进程的进程 ID)kill -QUIT <pid>
调试器扩展
- class scrapy.extensions.periodic_log.Debugger
当收到 SIGUSR2 信号时,在一个运行中的 Scrapy 进程内调用 Python 调试器。退出调试器后,Scrapy 进程继续正常运行。
此扩展仅适用于符合 POSIX 标准的平台 (即非 Windows)。