Scrapy shell

Scrapy Shell是一个交互式Shell,您可以在其中运行非常快速的调试爬虫代码,而不必运行Spider. 它打算用于测试数据提取代码,但是您实际上可以将其用于测试任何类型的代码,因为它也是常规的Python shell.

该外壳用于测试XPath或CSS表达式,并查看它们的工作方式以及从您要抓取的网页中提取的数据. 它使您可以在编写蜘蛛时以交互方式测试表达式,而不必运行蜘蛛来测试每个更改.

Once you get familiarized with the Scrapy shell, you’ll see that it’s an invaluable tool for developing and debugging your spiders.

Configuring the shell

如果您安装了IPython ,则Scrapy shell将使用它(而不是标准的Python控制台). IPython控制台功能强大得多,除其他功能外,还提供智能的自动完成功能和彩色输出.

我们强烈建议您安装IPython ,特别是如果您在Unix系统( IPython擅长的系统)上工作时. 有关更多信息,请参见IPython安装指南 .

Scrapy还支持bpython ,并将在IPython不可用的地方尝试使用它.

通过scrapy的设置,您可以将其配置为使用ipythonbpython或标准python shell中的任何一个,而不管安装了哪个. 这是通过设置SCRAPY_PYTHON_SHELL环境变量来完成的. 或在scrapy.cfg中定义它:

[settings]
shell = bpython

Launch the shell

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

scrapy shell <url>

其中<url>是您要抓取的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

Note

使用相对文件路径时,应明确使用./ (或在相关时使用../ ). scrapy shell index.html将无法正常运行(这是设计scrapy shell index.html ,而不是错误).

由于shell优先使用HTTP URL而非File 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.

如果当前目录中存在一个名为index.html的文件,则shell不会预先测试. 同样,要明确.

Using the shell

Scrapy shell只是一个常规的Python控制台(如果可用,则为IPython控制台),为方便起见,它提供了一些其他快捷方式功能.

Available Shortcuts

  • shelp() -显示可用对象和快捷方式列表的帮助
  • fetch(url[, redirect=True]) -从给定的URL获取新的响应,并相应地更新所有相关对象. 您可以选择不要求HTTP 3xx重定向,然后再传递redirect=False
  • fetch(request) -从给定的请求中获取新的响应,并相应地更新所有相关对象.
  • view(response) -在本地Web浏览器中打开给定的响应,以进行检查. 这会将<base>标记添加到响应主体,以使外部链接(例如图像和样式表)正确显示. 但是请注意,这将在您的计算机中创建一个临时文件,该文件不会自动删除.

Available Scrapy objects

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

这些对象是:

  • crawler - the current Crawler object.
  • spider已知可以处理URL的Spider如果当前URL没有找到Spider,则为Spider对象.
  • request -一个Request的最后抓取网页对象. 您可以使用replace()修改此请求,也可以使用fetch快捷方式获取新请求(不离开外壳).
  • response包含最后获取的页面的Response对象
  • settings -当前的Scrapy设置

Example of shell session

这是一个典型的shell会话的示例,我们首先抓取https://scrapy.org页面,然后再抓取https://reddit.com页面. 最后,我们将(Reddit)请求方法修改为POST,然后重新获取它,从而得到错误. 我们通过在Windows中键入Ctrl-D(在Unix系统中)或Ctrl-Z来结束会话.

请记住,此处尝试提取的数据可能会有所不同,因为这些页面不是静态的,并且在您测试时可能已更改. 该示例的唯一目的是使您熟悉Scrapy Shell的工作方式.

首先,我们启动shell:

scrapy shell 'https://scrapy.org' --nolog

然后,外壳程序获取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']}
>>>

Invoking the shell from spiders to inspect responses

有时,您仅想检查您期望到达的响应,便想检查在蜘蛛的某个点上正在处理的响应.

这可以通过使用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):
        # 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)退出外壳程序并继续爬网:

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

请注意,由于Scrapy引擎已被外壳阻止,因此您无法在此处使用fetch快捷方式. 但是,离开外壳后,蜘蛛将继续爬网,直到停止为止,如上所示.