Skip to content
This repository was archived by the owner on May 6, 2021. It is now read-only.

Files

Latest commit

027097f · Jul 6, 2019

History

History
238 lines (161 loc) · 9.8 KB

13.md

File metadata and controls

238 lines (161 loc) · 9.8 KB

Scrapy shell

译者:OSGeo 中国

scrappyshell是一个交互式shell,您可以在其中快速调试 scrape 代码,而不必运行spider。它本来是用来测试数据提取代码的,但实际上您可以使用它来测试任何类型的代码,因为它也是一个常规的PythonShell。

shell用于测试xpath或css表达式,并查看它们是如何工作的,以及它们从您试图抓取的网页中提取的数据。它允许您在编写spider时交互地测试表达式,而不必运行spider来测试每个更改。

一旦你熟悉了 Scrapy Shell,你就会发现它是开发和调试 Spider 的宝贵工具。

配置shell

如果你有 IPython 安装后,scrapy shell将使用它(而不是标准的python控制台)。这个 IPython 控制台功能更强大,提供智能自动完成和彩色输出等功能。

我们强烈建议您安装 IPython ,特别是在使用Unix系统时(其中 IPython 擅长)。见 IPython installation guide 更多信息。

Scrapy还支持 bpython ,并将尝试在 IPython 不可用。

通过Scrapy的设置,您可以将其配置为使用 ipythonbpython 或标准 python Shell,无论安装了什么。这是通过设置 SCRAPY_PYTHON_SHELL 环境变量;或通过在 scrapy.cfg ::

[settings]
shell = bpython

启动Shell

要启动 Scrapy shell,可以使用 shell 命令如下:

scrapy shell <url>

何处 &lt;url&gt; 是要抓取的URL。

shell 也适用于本地文件。如果你想玩一个网页的本地副本,这很方便。 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 不会像人们预期的那样工作(这是设计上的,而不是错误)。

因为 shell 喜欢HTTP URL而不是文件URI,以及 index.html 在句法上类似于 example.comshell 会治疗 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

scrappyshell只是一个普通的python控制台(或者 IPython 控制台,如果你有它的话),它提供一些额外的快捷功能,以方便。

可用快捷方式

  • shelp() -打印有关可用对象和快捷方式列表的帮助
  • fetch(url[, redirect=True]) - fetch a new response from the given URL and update all related objects accordingly. You can optionaly ask for HTTP 3xx redirections to not be followed by passing redirect=False
  • fetch(request) -从给定的请求中获取新的响应,并相应地更新所有相关对象。
  • view(response) -在本地Web浏览器中打开给定的响应以进行检查。这将增加一个 <base> tag 到响应主体,以便外部链接(如图像和样式表)正确显示。但是请注意,这将在您的计算机中创建一个临时文件,该文件不会自动删除。

可用的 Scrapy 对象

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

这些对象是:

  • crawler -电流 Crawler 对象。
  • spider -已知用于处理URL的 Spider ,或 Spider 如果没有为当前URL找到spider,则为。
  • request -A Request 上次提取的页的对象。您可以使用修改此请求 replace() 或者使用 fetch 捷径。
  • response -A Response 包含上次提取的页的对象
  • settings - the current Scrapy settings

Shell会话示例

下面是一个典型的shell会话的例子,我们从抓取https://scrappy.org页面开始,然后继续抓取https://reddit.com页面。最后,我们修改(reddit)请求方法来发布和重新获取它,得到一个错误。我们通过在Windows中键入ctrl-d(在UNIX系统中)或ctrl-z来结束会话。

请记住,在这里提取的数据在您尝试时可能不相同,因为这些页面不是静态的,在您测试时可能已经更改了。这个例子的唯一目的是让您熟悉下脚料Shell的工作原理。

首先,我们发射炮弹:

scrapy shell 'https://scrapy.org' --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 0x7f07395dd690>
[s]   item       {}
[s]   request    <GET https://scrapy.org>
[s]   response   <200 https://scrapy.org/>
[s]   settings   <scrapy.settings.Settings object at 0x7f07395dd710>
[s]   spider     <DefaultSpider 'default' at 0x7f0735891690>
[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()').get()
'Scrapy | A Fast and Powerful Scraping and Web Crawling Framework'

>>> fetch("https://reddit.com")

>>> response.xpath('//title/text()').get()
'reddit: the front page of the internet'

>>> request = request.replace(method="POST")

>>> fetch(request)

>>> response.status
404

>>> from pprint import pprint

>>> pprint(response.headers)
{'Accept-Ranges': ['bytes'],
 'Cache-Control': ['max-age=0, must-revalidate'],
 'Content-Type': ['text/html; charset=UTF-8'],
 'Date': ['Thu, 08 Dec 2016 16:21:19 GMT'],
 'Server': ['snooserv'],
 'Set-Cookie': ['loid=KqNLou0V9SKMX4qb4n; Domain=reddit.com; Max-Age=63071999; Path=/; expires=Sat, 08-Dec-2018 16:21:19 GMT; secure',
 'loidcreated=2016-12-08T16%3A21%3A19.445Z; Domain=reddit.com; Max-Age=63071999; Path=/; expires=Sat, 08-Dec-2018 16:21:19 GMT; secure',
 'loid=vi0ZVe4NkxNWdlH7r7; Domain=reddit.com; Max-Age=63071999; Path=/; expires=Sat, 08-Dec-2018 16:21:19 GMT; secure',
 'loidcreated=2016-12-08T16%3A21%3A19.459Z; Domain=reddit.com; Max-Age=63071999; Path=/; expires=Sat, 08-Dec-2018 16:21:19 GMT; secure'],
 'Vary': ['accept-encoding'],
 'Via': ['1.1 varnish'],
 'X-Cache': ['MISS'],
 'X-Cache-Hits': ['0'],
 'X-Content-Type-Options': ['nosniff'],
 'X-Frame-Options': ['SAMEORIGIN'],
 'X-Moose': ['majestic'],
 'X-Served-By': ['cache-cdg8730-CDG'],
 'X-Timer': ['S1481214079.394283,VS0,VE159'],
 'X-Ua-Compatible': ['IE=edge'],
 'X-Xss-Protection': ['1; mode=block']}
>>>

从spiders调用shell来检查响应

有时,您希望检查在您的 Spider 的某个点上正在处理的响应,如果只是检查您期望的响应是否到达那里的话。

这可以通过使用 scrapy.shell.inspect_response 功能。

下面是一个例子,说明如何从您的 Spider 中命名它:

import scrapy

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

    def parse(self, response):
        # We want to inspect one specific response.
        if ".org" in response.url:
            from scrapy.shell import inspect_response
            inspect_response(response, self)

        # Rest of parsing code.

当你运行 Spider 时,你会得到类似的东西:

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"]')
[]

不,不是这样的。所以您可以在Web浏览器中打开响应,看看它是否是您期望的响应:

>>> view(response)
True

最后,单击ctrl-d(或在Windows中单击ctrl-z)退出shell并继续爬网:

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

请注意,您不能使用 fetch 这里的快捷方式,因为 Scrapy 的引擎被Shell挡住了。然而,当你离开Shell后, Spider 会继续在它停止的地方爬行,如上图所示。