Debugging Spiders (调试爬虫)
本文档解释了调试爬虫最常用的技术。请看下面的 Scrapy 爬虫:
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):
# <未显示的处理代码>
# 收集 `item_urls`
for item_url in item_urls:
yield scrapy.Request(item_url, self.parse_item)
def parse_item(self, response):
# <未显示的处理代码>
item = MyItem()
# 填充 `item` 字段
# 并提取 item_details_url
yield scrapy.Request(
item_details_url, self.parse_details, cb_kwargs={"item": item}
)
def parse_details(self, response, item):
# 填充更多 `item` 字段
return item
基本上,这是一个简单的爬虫,它解析两个项目页面(start_urls)。项目还有一个包含附加信息的详细信息页面,因此我们使用 Request 的 cb_kwargs 功能来传递一个部分填充的项目。
Parse Command (parse 命令)
检查爬虫输出最基本的方法是使用 parse 命令。它允许在方法级别检查爬虫不同部分的行为。它的优点是灵活且易于使用,但不允许调试方法内部的代码。
为了查看从特定 URL 抓取的项目:
$ 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 选项,我们可以看到每个深度级别的状态:
$ 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 抓取的项目,也可以使用以下命令轻松实现:
$ scrapy parse --spider=myspider -d 3 'http://example.com/page1'
Scrapy Shell
虽然 parse 命令对于检查爬虫的行为非常有用,但除了显示接收到的响应和输出之外,它对检查回调内部发生的情况几乎没有帮助。当 parse_details 有时没有收到项目时,如何调试这种情况?
幸运的是,在这种情况下,shell 是您的法宝(请参阅从爬虫调用 shell 以检查响应):
from scrapy.shell import inspect_response
def parse_details(self, response, item=None):
if item:
# 填充更多 `item` 字段
return item
else:
inspect_response(response, self)
另请参阅:从爬虫调用 shell 以检查响应。
Open in browser (在浏览器中打开)
有时您只想看看某个响应在浏览器中是什么样子,您可以使用 open_in_browser() 函数来实现:
scrapy.utils.response.open_in_browser(response: TextResponse, _openfunc: Callable[[str], Any] = <function open>) -> Any[source]
在本地 Web 浏览器中打开 response,调整base 标签以使外部链接正常工作,例如,以便显示图像和样式。
例如:
from scrapy.utils.response import open_in_browser
def parse_details(self, response):
if "item name" not in response.body:
open_in_browser(response)
Logging (日志记录)
日志记录是获取有关爬虫运行信息的另一个有用选项。虽然不那么方便,但它的优点是日志将在所有未来的运行中可用,如果再次需要它们:
def parse_details(self, response, item=None):
if item:
# 填充更多 `item` 字段
return item
else:
self.logger.warning("No item received for %s", response.url)
有关更多信息,请查看日志记录部分。
Visual Studio Code
要使用 Visual Studio Code 调试爬虫,您可以使用以下 launch.json:
{
"version": "0.1.0",
"configurations": [
{
"name": "Python: Launch Scrapy Spider",
"type": "python",
"request": "launch",
"module": "scrapy",
"args": [
"runspider",
"${file}"
],
"console": "integratedTerminal"
}
]
}
此外,请确保启用“用户未捕获异常”以捕获 Scrapy 爬虫中的异常。