scrapy-redis(六):scrapy中如何定時的運行一個任務

相信開發過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.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章