鍍金池/ 教程/ Python/ Jobs:暫停,恢復(fù)爬蟲
Benchmarking
命令行工具(Command line tools)
下載器中間件(Downloader Middleware)
信號(Signals)
Telnet 終端(Telnet Console)
初窺 Scrapy
數(shù)據(jù)收集(Stats Collection)
Scrapyd
通用爬蟲(Broad Crawls)
Item Loaders
試驗階段特性
Scrapy 入門教程
自動限速(AutoThrottle)擴展
Settings
Scrapy 終端(Scrapy shell)
下載項目圖片
DjangoItem
調(diào)試(Debugging)Spiders
選擇器(Selectors)
Feed exports
Spiders Contracts
借助 Firefox 來爬取
Logging
Spiders
Ubuntu 軟件包
實踐經(jīng)驗(Common Practices)
安裝指南
Item Exporters
擴展(Extensions)
Items
Spider 中間件(Middleware)
異常(Exceptions)
例子
發(fā)送 email
架構(gòu)概覽
常見問題(FAQ)
Jobs:暫停,恢復(fù)爬蟲
核心 API
使用 Firebug 進行爬取
Item Pipeline
Link Extractors
Web Service
調(diào)試內(nèi)存溢出

Jobs:暫停,恢復(fù)爬蟲

有些情況下,例如爬取大的站點,我們希望能暫停爬取,之后再恢復(fù)運行。

Scrapy 通過如下工具支持這個功能:

  • 一個把調(diào)度請求保存在磁盤的調(diào)度器
  • 一個把訪問請求保存在磁盤的副本過濾器[duplicates filter]
  • 一個能持續(xù)保持爬蟲狀態(tài)(鍵/值對)的擴展

Job 路徑

要啟用持久化支持,你只需要通過 JOBDIR 設(shè)置 job directory 選項。這個路徑將會存儲 所有的請求數(shù)據(jù)來保持一個單獨任務(wù)的狀態(tài)(例如:一次 spider 爬取(a spider run))。必須要注意的是,這個目錄不允許被不同的 spider 共享,甚至是同一個 spider 的不同 jobs/runs 也不行。也就是說,這個目錄就是存儲一個 單獨 job 的狀態(tài)信息。

怎么使用

要啟用一個爬蟲的持久化,運行以下命令:

scrapy crawl somespider -s JOBDIR=crawls/somespider-1

然后,你就能在任何時候安全地停止爬蟲(按 Ctrl-C 或者發(fā)送一個信號)?;謴?fù)這個爬蟲也是同樣的命令:

scrapy crawl somespider -s JOBDIR=crawls/somespider-1

保持狀態(tài)

有的時候,你希望持續(xù)保持一些運行長時間的蜘蛛的狀態(tài)。這時您可以使用 spider.state 屬性,該屬性的類型必須是 dict。scrapy 提供了內(nèi)置擴展負(fù)責(zé)在 spider 啟動或結(jié)束時,從工作路徑(job directory)中序列化、存儲、加載屬性。

下面這個例子展示了使用 spider state 的回調(diào)函數(shù)(callback)(簡潔起見,省略了其他的代碼):

def parse_item(self, response):
    # parse item here
    self.state['items_count'] = self.state.get('items_count', 0) + 1

持久化的一些坑

如果你想要使用 Scrapy 的持久化支持,還有一些東西您需要了解:

Cookies 的有效期

Cookies 是有有效期的(可能過期)。所以如果你沒有把你的爬蟲及時恢復(fù),那么他可能在被調(diào)度回去的時候 就不能工作了。當(dāng)然如果你的爬蟲不依賴 cookies 就不會有這個問題了。

請求序列化

請求是由 pickle 進行序列化的,所以你需要確保你的請求是可被 pickle 序列化的。 這里最常見的問題是在在 request 回調(diào)函數(shù)中使用 lambda 方法,導(dǎo)致無法序列化。

例如,這樣就會有問題:

def some_callback(self, response):
    somearg = 'test'
    return scrapy.Request('http://www.example.com', callback=lambda r: self.other_callback(r, somearg))

def other_callback(self, response, somearg):
    print "the argument passed is:", somearg

這樣才對:

def some_callback(self, response):
    somearg = 'test'
    return scrapy.Request('http://www.example.com', meta={'somearg': somearg})

#這里的實例代碼有錯,應(yīng)該是(譯者注)
#   return scrapy.Request('http://www.example.com', meta={'somearg': somearg}, callback=self.other_callback)

def other_callback(self, response):
    somearg = response.meta['somearg']
    print "the argument passed is:", somearg
上一篇:Item Exporters下一篇:試驗階段特性