• 二十三、Scrapy的extensions


    Scrapy提供扩展(扩展是正常的python类,它们会在Scrapy启动时被实例化、初始化)机制,让人能将自定义功能绑定到Scrapy中。

    1、Scrapy中的内置扩展设置EXTENSIONS_BASE

      扩展在扩展类被实例化时加载和激活,实例化代码必须在类的构造函数(__init__)中执行。

      (1)'scrapy.extensions.corestats.CoreStats':0

        名称:核心统计扩展

        说明:如果统计收集器(stats collection)启用了,该扩展开启核心统计收集

      (2)'scrapy.telnet.TelnetConsole':0

        名称:Telnet控制台扩展

        说明:提供了一个telnet控制台,telnet控制台通过TELNETCONSOLE_ENABLED配置项开启,服务器会监听TELNETCONSOLE_PORT指定的端口

      (3)'scrapy.extensions.memusage.MemoryUsage':0

        名称:内存使用扩展

        说明:监听Scrapy进程内存使用量,如果使用内存量超过某个指定值,发送提醒邮件,如果超过某个指定值,关闭spider

      (4)'scrapy.extensions.memdebug.MemoryDebugger':0

        名称:内存调试扩展

        说明:该扩展用于调试内存使用量,开启该扩展,需要打开MEMDEBUG_ENABLED配置项

      (5)'scrapy.extensions.closespider.CloseSpider':0

        名称:当某些状况发生,spider会自动关闭,用来为状况指定关闭方式

      (6)'scrapy.extensions.feedexport.FeedExporter':0

      (7)'scrapy.extensions.logstats.LogStats':0

        名称:记录统计扩展

        说明:记录基本的统计信息,比如爬取的页面和条目(items)

      (8)‘scrapy.extensions.spiderstate.SpiderState’:0

      (9)‘scrapy.extensions.throttle.AutoThrottle’:0

      (10)‘scrapy.extensions.statsmailer.StatsMailer’:0

        名称:StatsMailer扩展

        说明:这个简单的扩展可用来在一个域名爬取完毕时发送提醒邮件,包含Scrapy收集的统计信息。邮件会发送给通过STATSMAILER_RCPTS指定的所有接收人

      扩展一般分为三种状态:可用的(Available)、开启的(enabled)和禁用的(disabled)。一些扩展经常需要依赖一些特别的配置,比如HTTP Cache扩展是可用的但默认是禁用的,除非设置了HTTPCACHE_ENABLED配置项。通过将其顺序设置为None,即可禁用。

    2、定制扩展

      扩展类是一个Python类,如果想操作Scrapy的功能,需要一个入口:from_crawler类方法,它接收一个Crawler类的实例,通过这个对象可以访问settings(设置)、signals(信号)、stats(状态),以便控制爬虫的行为。

      2.1 Scrapy提供的异常及其用法

      (1)DropItem异常

        原型:scrapy.exceptions.DropItem

        说明:该异常由item pipeline抛出,用于停止处理item

      (2)CloseSpider异常

        原型:scrapy.exceptions.CloseSpider(reason='cancelled')

        说明:该异常由spider的回调函数(callback)抛出,来停止/暂停spider。支持的参数:reason(str):关闭的原因

      (3)IgnoreRequest异常

        原型:scrapy.exceptions.IgnoreRequest

        说明:该异常由调度器(scheduler)或其他下载器中间件抛出,声明忽略该request

      (4)NotConfigured异常

        原型:scrapy.exceptions.NotConfigured

        说明:该异常由某些组件抛出,申明其仍然保持关闭。这些组件包括:Extensions、Item pipelines、Downloader middlwares、Spider middlewares。该异常必须由组件的构造器(constructor)抛出。

      (5)NotSupported异常

        原型:scrapy.exceptions.NotSupported

        说明:该异常申明一个不支持的特性

      2.2 Scrapy内置的信号

      (1)engine_started

        原型:scrapy.signals.engine_started()

        说明:当Scrapy引擎启动爬取时发送该信号,该信号支持返回deferreds

      (2)engine_stopped

        原型:scrapy.signals.engine_stopped()

        说明:当Scrapy引擎停止时发送该信号,例如爬取结束,该信号支持返回deferreds

      (3)item_scraped

        原型:scrapy.signals.item_scraped(item,response,spider)

        参数:item(dict或Item对象):爬取到的item

           spider(Spider对象):爬取item的spider

           response(Response对象):提取item的response

        说明:当item被爬取,并通过所有Item Pipeline后(没有被丢弃dropped),发送该信号。该信号支持返回deferreds

      (4)item_dropped

        原型:scrapy.signals.item_dropped(item,exception,spider)

        参数:item(dict或Item对象):Item Pipeline丢弃的item

           spider(Spider对象):爬取item的spider

           exception(DropItem异常):导致item被丢弃的异常

        说明:当item通过Item Pipeline,有些pipeline抛出DropItem异常,丢弃Item时,该信号被发送。该信号支持返回deferreds

      (5) spider_closed

        原型:scrapy.signals.spider_closed(spider,reason)

        参数:spider(Spider对象):关闭的spider

           reason(str):描述Spider被关闭的原因的字符串。如果Spider是由于完成爬取而被关闭,则其为”finished“。否则,如果Spider是被引擎的close_spider方法所关闭,则其为调用该方法时传入的reason参数(默认为”cancelled“)。如果引擎被关闭(如输入ctrl+c),则其为shutdown

        说明:当某个Spider被关闭时,该信号被发送,该信号可以用来释放每个Spider在spider_opened时占用的资源。该信号支持返回deferreds

      (6)spider_opened

        原型:scrapy.signals.spider_opened(spider)

        参数:spider(Spider对象):开启的spider

        说明:当spider开始爬取时发送该信号,该信号一般用来分配Spider的资源,不过它也能做任何事情。该信号支持返回deferreds

      (7)spider_idle

        原型:scrapy.signals.spider_idle(spider)

        参数:spider(Spider对象):空闲的Spider

        说明:当Spider进入空闲(idle)状态时该信号被发送。空闲说明:1)Requests正在等待被下载。2)Request被调度。3)Items正在Item Pipeline中被处理

           当该信号的所有处理器(handler)被调用后,如果spider仍然保持空闲状态,引擎将会关闭该spider。当spider被关闭后,spider_closed信号将被发送,可以在spider_idle处理器中调度某些请求来避免spider被关闭。

           该信号不支持返回deferreds

      (8)spider_error

        原型:scrapy.signals.spider_error(failure,response,spider)

        参数:failure(Failure对象):以Twisted Failure对象抛出的异常

           response(Response对象):当异常被抛出时被处理的response

           spider(Spider对象):抛出异常的Spider

        说明:当Spider的回调函数产生错误时,例如抛出异常,该信号被发送

      (9)request_scheduled

        原型:scrapy.signals.request_scheduled(request,spider)

        参数:request(Request对象):到达调度器的Request

           spider(Spider对象):产生该Request的Spider

        说明:当引擎调度一个Request对象用于下载时,该信号被发送,该信号不支持返回deferreds

      (10)response_received

        原型:scrapy.signals.response_received(response,request,spider)

        参数:response(Request对象):接收到的resposne

           request(Request对象):生成response的request

           spider(Spider对象):response所对应的spider

        说明:当引擎从downloader获取到一个新的Response时发送该信号,该信号不支持返回deferreds

      (11)response_downloaded

        原型:scrapy.signals.response_downloaded(response,request,spider)

        参数:response(Response对象):下载的response

           request(Request对象):生成的response的request

           spider(Spider对象):response所对应的 spider

        说明:当一个HTTPResponse被下载时,由downloader发送该信号,该信号不支持返回deferreds

      2.3 扩展代码

          代码来自:《Python爬虫开发与项目实战》范传辉著

          扩展需要关联到signals并执行它们触发的任务,如果from_crawler()方法抛出NotConfigured异常,扩展会被禁用,否则,扩展会被开启。

    import logging
    from scrapy import signals
    from scrapy import crawler
    from scrapy.exceptions import NotConfigured
    
    logger = logging.getLogger(__name__)
    
    class SpiderOpenCloseLogging(object):
        """当出现(spider被打开,spider被关闭,爬取了特定数量的Item)事件时,记录一条日志"""
        def __init__(self,item_count):
            self.item_count = item_count
            self.items_scraped = 0
    
        @classmethod
        def from_crawler(cls, crawler):
            # 首先检查一下是否存在响应的配置,如果不存在则抛出NotConfigured异常
            if not crawler.settings.getbool("MYEXT_ENABLED"):
                raise NotConfigured
            # 从setting中获取MYEXT_ITEMCOUNT的值
            item_count = crawler.settings.getint("MYEXT_ITEMCOUNT",1000)
            # 初始化扩展实例
            ext = cls(item_count)
            # 将扩展中的spider_opened、spider_closed和item_scraped连接到相应信号处,进行触发
            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 ext
    
        def spider_opened(self,spider):
            logger.info("opened spiders %s",spider.name)
    
        def spider_closed(self,spider):
            logger.info("closed spiders %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)
  • 相关阅读:
    (转) 理解Angular中的$apply()以及$digest()
    Gulp 有用的地址
    AngularJS中Directive指令系列
    让博客园博客中的图片支持fancybox浏览
    Drupal7 实现like(点赞)功能
    Drupal7 针对特定条件才显示区块
    Windows server 2008 tomcat间歇性掉线关闭
    关于tomcat8在windows2008下高并发下有关问题的解决方案
    combotree 的简单使用2
    @responseBody 返回更多数据
  • 原文地址:https://www.cnblogs.com/nuochengze/p/13154672.html
Copyright © 2020-2023  润新知