本篇介紹了調(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
簡單地說,該 spider 分析了兩個包含 item 的頁面(start_urls)。Item 有詳情頁面,所以我們使用 Request 的 meta 功能來傳遞已經(jīng)部分獲取的 item。
檢查 spier 輸出的最基本方法是使用 parse 命令。這能讓你在函數(shù)層(method level)上檢查 spider 各個部分的效果。其十分靈活并且易用,不過不能在代碼中調(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 選項,查看各個層次的狀態(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 -----------------------------------------------------------------
[]
檢查從單個 start_url 爬取到的 item 也是很簡單的:
$ scrapy parse --spider=myspider -d 3 'http://example.com/page1'
Scrapy終端(Shell)
盡管 parse
命令對檢查 spider 的效果十分有用,但除了顯示收到的 response 及輸出外,其對檢查回調(diào)函數(shù)內(nèi)部的過程并沒有提供什么便利。如何調(diào)試 parse_detail 沒有收到 item 的情況呢?
幸運的是,救世主 shell 出現(xiàn)了(參考在 spide r中啟動 shell 來查看 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中啟動shell來查看response
。
有時候您想查看某個 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
將會使用 Scrapy 獲取到的 response 來打開瀏覽器,并且調(diào)整 base tag 使得圖片及樣式(style)能正常顯示。
記錄(logging)是另一個獲取到 spider 運行信息的方法。雖然不是那么方便,但好處是 log 的內(nèi)容在以后的運行中也可以看到:
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)容請參見 Logging
部分。