先看一個(gè)例子
class MyCustomStatsExtension(object):
"""
這個(gè)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并寫入相關(guān)的儲(chǔ)存铣揉。
#目前展示是輸出到終端
print u'將展示收集到的數(shù)據(jù)'
print self.stats.get_stats()
解釋
Scrapy API的主要入口是 Crawler 的實(shí)例對(duì)象尚氛, 通過類方法 from_crawler 將它傳遞給擴(kuò)展(extensions)稀余,詳細(xì)解釋參見這里滤淳。
所以第一步通過from_crawler
類方法獲取到Crawler對(duì)象赏半。
@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
- 我的理解是當(dāng)項(xiàng)目啟動(dòng)后就開啟了一個(gè)抓取的行為這個(gè)行為通過Crawler對(duì)象來管理,表現(xiàn)為對(duì)spider的控制和狀態(tài)指示蔽挠。
之后通過from_crawler
類方法獲取的crawler注冊(cè)信號(hào)處理方法:
crawler.signals.connect(instance.spider_opened, signal=signals.spider_opened)
crawler.signals.connect(instance.spider_closed, signal=signals.spider_closed)
這里對(duì)應(yīng)的信號(hào)spider_opened
注冊(cè)為instance
的spider_opened
方法住闯,信號(hào)spider_closed
注冊(cè)為instance
的spider_closed
方法。
- spider_opened 信號(hào)在爬蟲開啟時(shí)由spider發(fā)送澳淑。
- spider_closed 信號(hào)在爬蟲結(jié)束時(shí)由spider發(fā)送比原。
而 instance 是通過instance = cls(crawler.stats)
實(shí)例化的本擴(kuò)展的一個(gè)實(shí)例。作用在于將crawler.stats
傳遞給本擴(kuò)展杠巡,并暴露自己的方法用于crawler信號(hào)的注冊(cè)量窘。
這樣啟動(dòng)項(xiàng)目后spider發(fā)送spider_opened
信號(hào),本擴(kuò)展會(huì)接收到這個(gè)信號(hào)執(zhí)行綁定的spider_opened
方法:
def spider_opened(self):
self.tsk = task.LoopingCall(self.collect)
self.tsk.start(self.time, now=True)
通過這個(gè)方法打開一個(gè)定時(shí)任務(wù)氢拥,間隔60秒執(zhí)行一次本擴(kuò)展的collect
方法打印spider的狀態(tài):
def collect(self):
#這里收集stats并寫入相關(guān)的儲(chǔ)存蚌铜。
#目前展示是輸出到終端
print u'將展示收集到的數(shù)據(jù)'
print self.stats.get_stats()
同理,spider關(guān)閉后嫩海,擴(kuò)展接收到spider_closed信號(hào)冬殃,執(zhí)行本擴(kuò)展的spider_closed方法關(guān)閉這個(gè)定時(shí)任務(wù)。
def spider_closed(self):
if self.tsk.running:
self.tsk.stop()