Scrapy中扩展(Extension)的定义

先看一个例子

class MyCustomStatsExtension(object):
    """
    这个extension专门用来定期搜集一次stats
    """
    def __init__(self, stats):
        self.stats = stats
        self.time = 60.0

    @classmethod
    def from_crawler(cls, crawler, *args, **kwargs):
        instance = cls(crawler.stats)
        crawler.signals.connect(instance.spider_opened, signal=signals.spider_opened)
        crawler.signals.connect(instance.spider_closed, signal=signals.spider_closed)
        return instance

    def spider_opened(self):
        self.tsk = task.LoopingCall(self.collect)
        self.tsk.start(self.time, now=True)

    def spider_closed(self):        
        if self.tsk.running:
            self.tsk.stop()

    def collect(self):
        #这里收集stats并写入相关的储存。
        #目前展示是输出到终端
        print u'将展示收集到的数据'
        print self.stats.get_stats()

解释

Scrapy API的主要入口是 Crawler 的实例对象, 通过类方法 from_crawler 将它传递给扩展(extensions),详细解释参见这里。

所以第一步通过from_crawler类方法获取到Crawler对象。

@classmethod
def from_crawler(cls, crawler, *args, **kwargs):
    instance = cls(crawler.stats)
    crawler.signals.connect(instance.spider_opened, signal=signals.spider_opened)
    crawler.signals.connect(instance.spider_closed, signal=signals.spider_closed)
    return instance
  • 我的理解是当项目启动后就开启了一个抓取的行为这个行为通过Crawler对象来管理,表现为对spider的控制和状态指示。

之后通过from_crawler类方法获取的crawler注册信号处理方法:

crawler.signals.connect(instance.spider_opened, signal=signals.spider_opened)
crawler.signals.connect(instance.spider_closed, signal=signals.spider_closed)

这里对应的信号spider_opened注册为instancespider_opened方法,信号spider_closed注册为instancespider_closed方法。

  • spider_opened 信号在爬虫开启时由spider发送。
  • spider_closed 信号在爬虫结束时由spider发送。

而 instance 是通过instance = cls(crawler.stats)实例化的本扩展的一个实例。作用在于将crawler.stats传递给本扩展,并暴露自己的方法用于crawler信号的注册。

这样启动项目后spider发送spider_opened信号,本扩展会接收到这个信号执行绑定的spider_opened方法:

def spider_opened(self):
    self.tsk = task.LoopingCall(self.collect)
    self.tsk.start(self.time, now=True)

通过这个方法打开一个定时任务,间隔60秒执行一次本扩展的collect方法打印spider的状态:

def collect(self):
    #这里收集stats并写入相关的储存。
    #目前展示是输出到终端
    print u'将展示收集到的数据'
    print self.stats.get_stats()

同理,spider关闭后,扩展接收到spider_closed信号,执行本扩展的spider_closed方法关闭这个定时任务。

def spider_closed(self):        
    if self.tsk.running:
        self.tsk.stop()

你可能感兴趣的:(爬虫)