2016-07-23 106 views
0

我正在使用scrapy進行刮擦項目。我打算通過使用某些項目屬性(取決於某些條件)來實現正在刮取的項目的緩存(字典),並且該緩存最終將作爲文件存儲在磁盤上。當scrapy啓動時,我可以使用pipelines.py中的spider_closed函數從文件加載緩存,並在scrapy關閉時使用spider_closed函數將修改後的緩存轉儲迴文件。在項目被刮取時,緩存將被修改。如果項目是唯一的,則將項目添加到緩存中。在pipelines.py,我可以創建一個變量mycache從緩存文件加載緩存:Scrapy從管道傳遞對象到Spider

mycache = load_from(cache_file) 

但我不知道如何從mycache傳遞pipelines.py到mySpider.py使它們共用一個mycache的副本。

有什麼建議嗎?

回答

3
class CustomPipeline(object): 

    def __init__(self, spider): 
     # the spider now contains a cache object 
     spider.mycache = TheCacheObject() 

    @classmethod 
    def from_crawler(cls, crawler): 
     return cls(crawler.spider) 

    def process_item(self, item, spider): 
     spider.mycache = do_your_thing 
2

你說的是可能的,但它是壞的設計。根據這個緩存我不知道你要採取什麼行動,但不管它是什麼,都應該在特定的管道內完成。管道的一個概念是,每個管道步驟都可能依賴於先前的步驟,但不是從它之後的任何步驟。這有點像在我知道未來之後纔會決定。不好!另外,這是一個很好的設計實踐,可以禁用流水線階段,並讓系統的其他部分工作。特別是在你的情況下,你所做的就是緩存......好吧......緩存應該始終是性能優化而不會影響功能。如何在不破壞可憐的蜘蛛的情況下禁用緩存管道?

反正 - 我明白,管道只處理Item S和一個可能的原因可能讓你想養活Item緩存回你的蜘蛛是因爲你要採取的行動或影響Request秒。這就是Spider Middleware。他們可以處理同時放棄Item s和Request s。我期望如果你的緩存不能完全用蜘蛛實現,它將能夠完全用Spider Middleware實現。

class MyMiddleware(object): 
    def process_spider_output(self, response, result, spider): 
     for x in result: 
      if not isinstance(x, Request): 
       # Pass-throug all items 
       yield x 
      else: 
       if x.url not in self.urls_cache: 
        yield x 

SPIDER_MIDDLEWARES = { 
    'project.middlewares.MyMiddleware: 100, 
}