Extensions

扩展框架提供了一种将自己的自定义功能插入Scrapy的机制.

扩展只是在初始化扩展时在Scrapy启动时实例化的常规类.

Extension settings

扩展程序使用Scrapy设置来管理其设置,就像其他任何Scrapy代码一样.

扩展名通常会在其设置前添加自己的名称,以避免与现有(和将来)扩展名冲突. 例如,用于处理Google Sitemaps的假设扩展将使用GOOGLESITEMAP_ENABLEDGOOGLESITEMAP_DEPTH等设置.

Loading & activating extensions

通过实例化扩展类的单个实例,可以在启动时加载和激活扩展. 因此,所有扩展初始化代码都必须在类构造函数( __init__方法)中执行.

要使扩展名可用,请将其添加到Scrapy设置中的EXTENSIONS设置中. 在EXTENSIONS ,每个扩展都由一个字符串表示:扩展类名的完整Python路径. 例如:

EXTENSIONS = {
    'scrapy.extensions.corestats.CoreStats': 500,
    'scrapy.extensions.telnet.TelnetConsole': 500,
}

如您所见, EXTENSIONS设置是一个字典,其中键是扩展路径,其值是顺序,这些顺序定义了扩展的加载顺序. 该EXTENSIONS设置合并到EXTENSIONS_BASE在Scrapy定义的设置(而不是必须被覆盖),然后通过排序才能得到启用的扩展的最终排序列表.

由于扩展通常不相互依赖,因此在大多数情况下它们的加载顺序无关紧要. 这就是为什么EXTENSIONS_BASE设置以相同的顺序( 0 )定义所有扩展名的原因. 但是,如果您需要添加依赖于已加载的其他扩展的扩展,则可以利用此功能.

Available, enabled and disabled extensions

并非所有可用的扩展名都会启用. 其中一些通常取决于特定的设置. 例如,默认情况下,HTTP缓存扩展名是可用的,但是除非设置了HTTPCACHE_ENABLED设置,否则它是禁用的.

Disabling an extension

为了禁用默认启用的扩展名(即EXTENSIONS_BASE设置中包含的EXTENSIONS_BASE ),您必须将其顺序设置为None . 例如:

EXTENSIONS = {
    'scrapy.extensions.corestats.CoreStats': None,
}

Writing your own extension

每个扩展都是一个Python类. Scrapy扩展(也包括中间件和管道)的主要入口点是from_crawler类方法,该方法接收Crawler实例. 通过Crawler对象,您可以访问设置,信号,统计信息,还可以控制爬网行为.

通常,分机连接到信号并执行由它们触发的任务.

最后,如果from_crawler方法引发NotConfigured异常,则将禁用扩展名. 否则,将启用该扩展名.

Sample extension

在这里,我们将实现一个简单的扩展,以说明上一部分中描述的概念. 该扩展程序每次都会记录一条消息:

  • 蜘蛛被打开
  • 蜘蛛是封闭的
  • 刮下特定数量的物品

该扩展名将通过MYEXT_ENABLED设置启用,而项数将通过MYEXT_ITEMCOUNT设置指定.

这是这种扩展的代码:

import logging
from scrapy import signals
from scrapy.exceptions import NotConfigured

logger = logging.getLogger(__name__)

class SpiderOpenCloseLogging(object):

    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)

Built-in extensions reference

General purpose extensions

Log Stats extension

class scrapy.extensions.logstats.LogStats

记录基本统计信息,例如抓取的页面和已抓取的项目.

Core Stats extension

class scrapy.extensions.corestats.CoreStats

如果启用了统计信息收集,请启用核心统计信息的收集(请参阅统计信息收集 ).

Telnet console extension

class scrapy.extensions.telnet.TelnetConsole

提供一个telnet控制台,以进入当前正在运行的Scrapy进程内的Python解释器,这对于调试非常有用.

必须通过TELNETCONSOLE_ENABLED设置启用telnet控制台,并且服务器将侦听TELNETCONSOLE_PORT指定的端口.

Memory usage extension

class scrapy.extensions.memusage.MemoryUsage

Note

此扩展名在Windows中不起作用.

监视运行spider的Scrapy进程使用的内存,并:

  1. 超过一定值时发送通知电子邮件
  2. 超过一定值时关闭蜘蛛网

的通知电子邮件可以当达到(一定警告值来触发MEMUSAGE_WARNING_MB )并在达到最大值时( MEMUSAGE_LIMIT_MB ),这也将导致蜘蛛被关闭和Scrapy过程将被终止.

此扩展由MEMUSAGE_ENABLED设置启用,并且可以使用以下设置进行配置:

Memory debugger extension

class scrapy.extensions.memdebug.MemoryDebugger

用于调试内存使用情况的扩展. 它收集有关以下信息:

要启用此扩展,请打开MEMDEBUG_ENABLED设置. 该信息将存储在统计信息中.

Close spider extension

class scrapy.extensions.closespider.CloseSpider

当满足某些条件时,使用每种条件的特定关闭原因自动关闭蜘蛛.

可以通过以下设置配置关闭蜘蛛网的条件:

CLOSESPIDER_TIMEOUT

Default: 0

一个整数,指定秒数. 如果蜘蛛网保持打开状态超过该closespider_timeout ,它将以closespider_timeout原因自动关闭. 如果为零(或未设置),则蜘蛛不会因超时而关闭.

CLOSESPIDER_ITEMCOUNT

Default: 0

一个整数,指定多个项目. 如果蜘蛛抓取的数量超过该数量,并且这些物品已通过物品管道传递,则蜘蛛将以closespider_itemcount原因closespider_itemcount . 当前在下载器队列中的请求(最多CONCURRENT_REQUESTS请求)仍会被处理. 如果为零(或未设置),则蜘蛛将不会按传递的项目数关闭.

CLOSESPIDER_PAGECOUNT

版本0.11中的新功能.

Default: 0

一个整数,指定要爬网的最大响应数. 如果抓取工具爬行的次数超过此closespider_pagecount ,则将以closespider_pagecount原因关闭抓取closespider_pagecount . 如果为零(或未设置),则抓取的响应数不会关闭蜘蛛.

CLOSESPIDER_ERRORCOUNT

New in version 0.11.

Default: 0

一个整数,指定在关闭蜘蛛网之前要接收的最大错误数. 如果蜘蛛产生的错误数量超过该数目,则将使用closespider_errorcount原因将其关闭. 如果为零(或未设置),则蜘蛛不会因错误数量而关闭.

StatsMailer extension

class scrapy.extensions.statsmailer.StatsMailer

这个简单的扩展名可用于在域完成每次爬网(包括收集的Scrapy统计信息)后发送通知电子邮件. 该电子邮件将发送给STATSMAILER_RCPTS设置中指定的所有收件人.

Debugging extensions

Stack trace dump extension

class scrapy.extensions.debug.StackTraceDump

当收到SIGQUITSIGUSR2信号时,转储有关正在运行的进程的信息. 转储的信息如下:

  1. 引擎状态(使用scrapy.utils.engine.get_engine_status()
  2. 实时引用(请参阅使用trackref调试内存泄漏
  3. 所有线程的堆栈跟踪

转储堆栈跟踪和引擎状态后,Scrapy进程将继续正常运行.

由于SIGQUITSIGUSR2信号在Windows上不可用,因此该扩展名仅在兼容POSIX的平台(即Windows)上工作.

至少有两种方法可以向Scrapy发送SIGQUIT信号:

  1. 在Scrapy进程运行时按Ctrl键(仅Linux?)

  2. 通过运行以下命令(假设<pid>是Scrapy进程的进程ID):

    kill -QUIT <pid>
    

Debugger extension

class scrapy.extensions.debug.Debugger

收到SIGUSR2信号时,在正在运行的Scrapy进程中调用Python调试器 . 退出调试器后,Scrapy进程将继续正常运行.

有关更多信息,请参见使用Python进行调试 .

该扩展名仅在POSIX兼容平台上有效(即,不适用于Windows).