本篇介紹了調(diào)試 spider 的常用技術(shù)。 考慮下面的 spider:
import scrapy
from myproject.items import MyItem
class MySpider(scrapy.Spider):
name = 'myspider'
start_urls = (
'http://example.com/page1',
'http://example.com/page2',
)
def parse(self, response):
# collect `item_urls`
for item_url in item_urls:
yield scrapy.Request(item_url, self.parse_item)
def parse_item(self, response):
item = MyItem()
# populate `item` fields
# and extract item_details_url
yield scrapy.Request(item_details_url, self.parse_details, meta={'item': item})
def parse_details(self, response):
item = response.meta['item']
# populate more `item` fields
return item
簡(jiǎn)單地說(shuō),該 spider 分析了兩個(gè)包含 item 的頁(yè)面(start_urls)。Item 有詳情頁(yè)面,所以我們使用 Request 的 meta 功能來(lái)傳遞已經(jīng)部分獲取的 item。
檢查 spier 輸出的最基本方法是使用 parse 命令。這能讓你在函數(shù)層(method level)上檢查 spider 各個(gè)部分的效果。其十分靈活并且易用,不過(guò)不能在代碼中調(diào)試。
查看特定 url 爬取到的 item:
$ scrapy parse --spider=myspider -c parse_item -d 2 <item_url>
[ ... scrapy log lines crawling example.com spider ... ]
>>> STATUS DEPTH LEVEL 2 <<<
# Scraped Items ------------------------------------------------------------
[{'url': <item_url>}]
# Requests -----------------------------------------------------------------
[]
使用--verbose 或-v 選項(xiàng),查看各個(gè)層次的狀態(tài):
$ scrapy parse --spider=myspider -c parse_item -d 2 -v <item_url>
[ ... scrapy log lines crawling example.com spider ... ]
>>> DEPTH LEVEL: 1 <<<
# Scraped Items ------------------------------------------------------------
[]
# Requests -----------------------------------------------------------------
[<GET item_details_url>]
>>> DEPTH LEVEL: 2 <<<
# Scraped Items ------------------------------------------------------------
[{'url': <item_url>}]
# Requests -----------------------------------------------------------------
[]
檢查從單個(gè) start_url 爬取到的 item 也是很簡(jiǎn)單的:
$ scrapy parse --spider=myspider -d 3 'http://example.com/page1'
Scrapy終端(Shell)
盡管 parse 命令對(duì)檢查 spider 的效果十分有用,但除了顯示收到的 response 及輸出外,其對(duì)檢查回調(diào)函數(shù)內(nèi)部的過(guò)程并沒(méi)有提供什么便利。如何調(diào)試 parse_detail 沒(méi)有收到 item 的情況呢?
幸運(yùn)的是,救世主 shell 出現(xiàn)了(參考在 spide r中啟動(dòng) shell 來(lái)查看 response):
from scrapy.shell import inspect_response
def parse_details(self, response):
item = response.meta.get('item', None)
if item:
# populate more `item` fields
return item
else:
inspect_response(response, self)
參考在spider中啟動(dòng)shell來(lái)查看response。
有時(shí)候您想查看某個(gè) response 在瀏覽器中顯示的效果,這是可以使用 open_in_browser 功能。下面是使用的例子:
from scrapy.utils.response import open_in_browser
def parse_details(self, response):
if "item name" not in response.body:
open_in_browser(response)
open_in_browser 將會(huì)使用 Scrapy 獲取到的 response 來(lái)打開(kāi)瀏覽器,并且調(diào)整 base tag 使得圖片及樣式(style)能正常顯示。
記錄(logging)是另一個(gè)獲取到 spider 運(yùn)行信息的方法。雖然不是那么方便,但好處是 log 的內(nèi)容在以后的運(yùn)行中也可以看到:
from scrapy import log
def parse_details(self, response):
item = response.meta.get('item', None)
if item:
# populate more `item` fields
return item
else:
self.log('No item received for %s' % response.url,
level=log.WARNING)
更多內(nèi)容請(qǐng)參見(jiàn) Logging 部分。