相信開發過scrapy的朋友對scrapy終端的日誌輸出非常熟悉,它會間隔一段時間輸出抓取的狀態,比如最近60秒內,抓取了幾個網頁,成功獲取到了幾個item。這些對於我們觀察spider的運行是非常有用的,我們可以觀測spider的抓取情況,速度是否在預期之中等等。
有時候,我們也需要自定義一個extension,用來定時的收集scrapy的stats,然後利用這些stats進行繪製圖形,這樣我們就可以圖形化的去監控爬蟲的狀態,而不是盯着log日誌。
比如,我們想自定義一個extension,每隔60秒就收集一次當前spider的stats,那我們該如何操作呢?原理其實非常的簡單,就是利用scrapy中的signals和twisted中的LoopingCall。代碼實現如下:
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()
上面的代碼中,我們利用類方法from_crawler定製了兩個信號,第一個信號是spider_opened,這個信號會在spider打開的時候,開始一個循環調用的任務,即collect()方法。第二個信號是spider_closed,它會在spider關閉的時候,關閉這個循環調用的任務。
那這個任務是如何建立的呢?twisted.internet中有一個LoopingCall()類,我們傳遞一個函數進去,就初始化了一個任務,然後調用其start()方法,並傳入調用的時間間隔,就可以開啓這個任務了。然後,在spider運行的期間,每隔一段時間,就會調用一次這個任務。在本例中,我們的任務就是收集spider的stats,用於統計繪製圖形。而對於我們需要收集哪些數據,我們也可以進行定製,核心入口就是from_crawler.