Scrapy1.5基本概念(六)——Scrapy shell

本文为译文,原文见地址:https://docs.scrapy.org/en/latest/topics/shell.html

Scrapy shell

Scrapy shell是一个交互式的shell,你可以在其中非常快速地尝试和调试你的抓取代码,而不必运行爬虫。它本来是用来测试数据提取代码的,但实际上你可以用它来测试任何类型的代码,因为它也是一个常规的Python shell。

这个shell用来测试XPath和CSS表达式,并查看它们是如何工作的,以及它们从你试图获取的web页面中提取什么数据。它允许你在编写爬虫时交互式地测试表达式,而不必运行爬虫来测试每个测试。

一旦你对Scrapy shell熟悉了,你会发现它是开发和调试爬虫的一个非常宝贵的工具。

配置shell

如果已经安装了IPython,那么Scrapy shell将使用它(而不是标准的Python控制台)。IPython控制台更加强大,它提供了智能自动补全和彩色输出等功能。

我们强烈推荐你安装IPython,特别是使用Unix系统(IPython更加优秀的平台)。详情查看IPython installation guid获取更多信息。

Scrapy也支持bpython,并且会在IPython不可用时尝试使用它。

通过Scrapy的设置,你可以将其配置为使用ipython、bpython或者其他的标准python shell的任意一种,而不管安装的是哪种。这是通过设置SCRAPY_PYTHON_SHELL环境变量完成的,或者在你的scrapy.cfg文件中定义它:

[settings]
shell = bpython

登录shell

为了登录Scrapy shell,你可以使用shell命令:

scrapy shell <url>

是你希望爬取的URL地址。

shell也可以同本地文件一起工作。如果你想要处理web页面的本地副本,这可能非常方便。shell理解本地文件的以下语法:

# UNIX-style
scrapy shell ./path/to/file.html
scrapy shell ../other/path/to/file.html
scrapy shell /absolute/path/to/file.html

# File URI
scrapy shell file:///absolute/path/to/file.html

当使用相对文件路径时,要显式地使用./来指定。scrapy shell index.html不会像人们期望的那样工作(这是设计如此,不是bug)。

因为shell更喜欢HTTP URL而不是文件URI,index.html在语法上与example.com相似,shell将视index.html为域名,并触发DNS查找错误:

$ scrapy shell index.html
[ ... scrapy shell starts ... ]
[ ... traceback ... ]
twisted.internet.error.DNSLookupError: DNS lookup failed:
address 'index.html' not found: [Errno -5] No address associated with hostname.

shell不会预先测试index.html文件是否存在于当前路径。所以再次提醒,需要显示使用./来指定相对文件路径。

使用shell

Scrapy shell只是一个常规的Python控制台(如果使用IPython则是IPython控制台),它提供了一些便利的附加快捷方式。

可用的快捷方式

  • shelp() - 打印可用对象和快捷方式的列表。
  • fetch(url[, redirect=True]) - 从给定的URL获取一个新的响应,并且依次更新所有相关对象。你可以通过传递redirect=False来选择请求不遵从HTTP 3xx的重定向。
  • fetch(request) - 从给定的请求中获取一个新的响应,并且依次更新所有相关对象。
  • view(response) - 在你本地web浏览器中打开给定的响应,以供检查。这将向响应正文添加一个标签,以便正确显示外部链接(比如图片和样式表)。但需要注意的是,这样做会在你的计算机中创建一个临时文件,并且并不会自动删除这个文件。

可用的Scrapy对象

Scrapy shell会从下载的页面中自动创建一些方便的对象,比如Response对象和Selector对象(用于HTML和XML内容)。

这些对象是:

  • crawler - 当前的Crawler对象。
  • spider - 已知的处理URL的爬虫,或者如果当前URL并没有对应的爬虫则返回一个Spider对象。
  • request - 最后获取的页面的Request对象。你可以通过replace()修改这个请求,或者使用fetch快捷方式来获取一个新的request(不用离开当前shell)。
  • response - 一个Response对象,包含了最后获取的页面。
  • settings - 当前Scrapy的设置项

shell会话的示例

这里是一个典型的shell会话示例,我们先爬取https://docs.scrapy.org/en/latest/topics/shell.html#available-shortcuts页面,然后继续爬取https://itchat.readthedocs.io/zh/latest/页面。最后,我们修改(Reddit)请求函数来POST它,并且重新获得它,结果得到一个错误。我们使用Ctrl-D(在Unix系统中)或者Ctrl-Z(在Windows系统中)来结束会话。

请记住,当你尝试的时候,提取的数据可能与这里不一致,这是因为这些页面不是静态的,可能会随着时间的推移而有些变化。这些示例的唯一目的是为了让你熟悉Scrapy shell的工作方式。

首先,我们登录shell:

scrapy shell https://docs.scrapy.org/en/latest/topics/shell.html#available-shortcuts --nolog

然后,shell会获取URL(使用Scrapy的下载器)并且打印一组可用的对象和有用的快捷方式(你可以注意到每一行都由[s]开始):

[s] Available Scrapy objects:
[s]   scrapy     scrapy module (contains scrapy.Request, scrapy.Selector, etc)
[s]   crawler    <scrapy.crawler.Crawler object at 0x0000022D1B00FA90>
[s]   item       {}
[s]   request    <GET https://docs.scrapy.org/en/latest/topics/shell.html#available-shortcuts>
[s]   response   <200 https://docs.scrapy.org/en/latest/topics/shell.html>
[s]   settings   <scrapy.settings.Settings object at 0x0000022D1B00F8D0>
[s]   spider     <DefaultSpider 'default' at 0x22d1b2bb7b8>
[s] Useful shortcuts:
[s]   fetch(url[, redirect=True]) Fetch URL and update local objects (by default, redirects are followed)
[s]   fetch(req)                  Fetch a scrapy.Request and update local objects
[s]   shelp()           Shell help (print this help)
[s]   view(response)    View response in a browser
>>>

在这之后,我们可以开始使用这些对象:

>>> response.xpath('//title/text()').extract_first()
'Scrapy shell — Scrapy 1.5.1 documentation'
>>> fetch('https://itchat.readthedocs.io/zh/latest/')
>>> response.xpath('//title/text()').extract()
['项目简介 - itchat']
>>> request = request.replace(method='POST')
>>> fetch(request)
>>> response.status
405
>>> from pprint import pprint
>>> pprint(response.headers)
{b'Content-Type': [b'text/html'],
 b'Date': [b'Sat, 29 Dec 2018 09:21:45 GMT'],
 b'Server': [b'nginx/1.14.0 (Ubuntu)']}
>>>

从爬虫调用shell来检查响应

有时候,你希望检查在爬虫的某个点上正在处理的响应,如果只是为了检查预期的响应是否达到该点。

通过scrapy.shell.inspect_response函数可以实现这个功能。

这里有一个示例,演示了如何在你的爬虫中调用它:

import scrapy


class MySpider(scrapy.Spider):
	name = 'myspider'
	start_urls = [
		'http://example.com',
		'http://example.org',
		'http://example.net',
	]

	def parse(self, response):
		# 我们希望检查一个特定的响应
		if '.org' in response.url:
			from scrapy.shell import inspect_response
			inspect_response(response, self)

		# 剩余的解析代码

当你运行这个爬虫,你将得到一些类似于下面的东西:

2014-01-23 17:48:31-0400 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://example.com> (referer: None)
2014-01-23 17:48:31-0400 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://example.org> (referer: None)
[s] Available Scrapy objects:
[s]   crawler    <scrapy.crawler.Crawler object at 0x1e16b50>
...

>>> response.url
'http://example.org'

然后,你就可以检查提取代码是否工作:

>>> response.xpath('//h1[@class="fn"]')
[]

你也可以在你的网页浏览器中打开响应,看看这是不是你希望的响应:

>>> ^D
2014-01-23 17:50:03-0400 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://example.net> (referer: None)
...

注意,这里不能使用fetch快捷方式,因为Scrapy引擎被shell阻塞了。但是,在你离开shell之后,爬虫将继续在它停止的地方爬行,如上所示。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值