有些情況下,例如爬取大的站點,我們希望能暫停爬取,之后再恢復(fù)運行。
Scrapy 通過如下工具支持這個功能:
要啟用持久化支持,你只需要通過 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
有的時候,你希望持續(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 是有有效期的(可能過期)。所以如果你沒有把你的爬蟲及時恢復(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