有些情況下,例如爬取大的站點,我們希望能暫停爬取,之后再恢復運行。
Scrapy通過如下工具支持這個功能:
一個把調度請求保存在磁盤的調度器
一個把訪問請求保存在磁盤的副本過濾器[duplicates filter]
一個能持續保持爬蟲狀態(鍵/值對)的擴展
Job 路徑:
要啟用持久化支持,你只需要通過 JOBDIR 設置 job directory 選項。
這個路徑將會存儲 所有的請求數據來保持一個單獨任務的狀態(例如:一次
spider爬取(a spider run))。必須要注意的是,這個目錄不允許被不同的
spider 共享,甚至是同一個spider的不同jobs/runs也不行。也就是說,
這個目錄就是存儲一個 單獨 job的狀態信息。
怎么使用??? 要啟用一個爬蟲的持久化,運行以下命令:
scrapy crawl 爬蟲名稱 -s JOBDIR=crawls/爬蟲名稱
然后,你就能在任何時候安全地停止爬蟲(按Ctrl-C或者發送一個信號,這時候會看到crawls文件夾下保存了一些文件)。恢復這個爬蟲也是同樣的命令:
scrapy crawl 爬蟲名稱 -s JOBDIR=crawls/爬蟲名稱
持久化的一些坑 如果你想要使用 Scrapy 的持久化支持,還有一些東西您需要了解:
注意Cookies 的有效期 Cookies 是有有效期的(可能過期)。所以如果你沒有把你的爬蟲及時恢復,那么他可能在被調度回去的時候 就不能工作了。當然如果你的爬蟲不依賴 cookies 就不會有這個問題了。
請求序列化 請求是由 pickle 進行序列化的,所以你需要確保你的請求是可被 pickle 序列化的。 這里最常見的問題是在在 request 回調函數中使用 lambda 方法,導致無法序列化。
例如,這樣就會有問題:
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},
callback=self.other_callback
)
def other_callback(self, response):
somearg = response.meta['somearg']
print("the argument passed is:", somearg)
也可以使用scrapy-redis的相關組件來實現暫停和恢復的操作,我們爬取的相關數據會被存放在redis的數據庫中