Python版本管理:pyenv和pyenv-virtualenv
Scrapy爬蟲(chóng)入門教程一 安裝和基本使用
Scrapy爬蟲(chóng)入門教程二 官方提供Demo
Scrapy爬蟲(chóng)入門教程三 命令行工具介紹和示例
Scrapy爬蟲(chóng)入門教程四 Spider(爬蟲(chóng))
Scrapy爬蟲(chóng)入門教程五 Selectors(選擇器)
Scrapy爬蟲(chóng)入門教程六 Items(項(xiàng)目)
Scrapy爬蟲(chóng)入門教程七 Item Loaders(項(xiàng)目加載器)
Scrapy爬蟲(chóng)入門教程八 交互式 shell 方便調(diào)試
Scrapy爬蟲(chóng)入門教程九 Item Pipeline(項(xiàng)目管道)
Scrapy爬蟲(chóng)入門教程十 Feed exports(導(dǎo)出文件)
Scrapy爬蟲(chóng)入門教程十一 Request和Response(請(qǐng)求和響應(yīng))
Scrapy爬蟲(chóng)入門教程十二 Link Extractors(鏈接提取器)
開(kāi)發(fā)環(huán)境:
Python 3.6.0 版本 (當(dāng)前最新)
Scrapy 1.3.2 版本 (當(dāng)前最新)
Scrapy shell
Scrapy shell是一個(gè)交互式shell,您可以在此快速嘗試和調(diào)試您的抓取代碼,而無(wú)需運(yùn)行爬蟲(chóng)程序。它用于測(cè)試數(shù)據(jù)提取代碼,但實(shí)際上可以使用它來(lái)測(cè)試任何類型的代碼,因?yàn)樗彩且粋€(gè)常規(guī)的Python shell。
shell用于測(cè)試XPath或CSS表達(dá)式,并查看它們?nèi)绾喂ぷ?,以及他們從您要嘗試抓取的網(wǎng)頁(yè)中提取的數(shù)據(jù)。它允許您在編寫(xiě)爬蟲(chóng)時(shí)交互式測(cè)試表達(dá)式,而無(wú)需運(yùn)行爬蟲(chóng)來(lái)測(cè)試每個(gè)更改。
一旦你熟悉了Scrapy shell,你會(huì)發(fā)現(xiàn)它是開(kāi)發(fā)和調(diào)試你的爬蟲(chóng)的一個(gè)非常寶貴的工具。
配置shell
如果你安裝了IPython,Scrapy shell會(huì)使用它(而不是標(biāo)準(zhǔn)的Python控制臺(tái))。該IPython的控制臺(tái)功能更強(qiáng)大,并提供智能自動(dòng)完成和彩色輸出,等等。
我們強(qiáng)烈建議您安裝IPython,特別是如果你正在使用Unix系統(tǒng)(IPython擅長(zhǎng))。有關(guān) 詳細(xì)信息,請(qǐng)參閱IPython安裝指南。
Scrapy還支持bpython,并且將嘗試在IPython 不可用的地方使用它。
通過(guò)scrapy的設(shè)置,您可以配置為使用中的任何一個(gè) ipython,bpython或標(biāo)準(zhǔn)python外殼,安裝無(wú)論哪個(gè)。這是通過(guò)設(shè)置SCRAPY_PYTHON_SHELL環(huán)境變量來(lái)完成的; 或通過(guò)在scrapy.cfg中定義它:
[settings]
shell = bpython
啟動(dòng)shell
要啟動(dòng)Scrapy shell,可以使用如下shell命令:
scrapy shell <url>
其中,<url>是您要抓取的網(wǎng)址。
shell也適用于本地文件。如果你想玩一個(gè)網(wǎng)頁(yè)的本地副本,這可以很方便。shell了解本地文件的以下語(yǔ)法:
# 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
注意
當(dāng)使用相對(duì)文件路徑時(shí),是顯式的,并在它們前面./(或../相關(guān)時(shí))。 將不會(huì)像一個(gè)人所期望的那樣工作(這是設(shè)計(jì),而不是一個(gè)錯(cuò)誤)。scrapy shell index.html
因?yàn)閟hell喜歡文件URI上的HTTP URL,并且index.html在語(yǔ)法上類似example.com, shell會(huì)將其視為index.html域名并觸發(fā)DNS查找錯(cuò)誤:
$ 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將不會(huì)預(yù)先測(cè)試index.html 當(dāng)前目錄中是否存在調(diào)用的文件。再次,明確。
使用shell
Scrapy shell只是一個(gè)普通的Python控制臺(tái)(或IPython控制臺(tái),如果你有它),為方便起見(jiàn),它提供了一些額外的快捷方式功能。
可用快捷鍵
-
shelp()- 打印有可用對(duì)象和快捷方式列表的幫助
*fetch(url[, redirect=True])- 從給定的URL獲取新的響應(yīng),并相應(yīng)地更新所有相關(guān)對(duì)象。你可以選擇要求HTTP 3xx重定向,不要通過(guò)redirect=False -
fetch(request)- 從給定請(qǐng)求獲取新響應(yīng),并相應(yīng)地更新所有相關(guān)對(duì)象。 -
view(response)- 在本地Web瀏覽器中打開(kāi)給定的響應(yīng),以進(jìn)行檢查。這將向響應(yīng)正文添加一個(gè)<base>標(biāo)記,以便正確顯示外部鏈接(如圖片和樣式表)。但請(qǐng)注意,這將在您的計(jì)算機(jī)中創(chuàng)建一個(gè)臨時(shí)文件,不會(huì)自動(dòng)刪除。
可用Scrapy對(duì)象
Scrapy shell自動(dòng)從下載的頁(yè)面創(chuàng)建一些方便的對(duì)象,如Response對(duì)象和 Selector對(duì)象(對(duì)于HTML和XML內(nèi)容)。
這些對(duì)象是:
- crawler- 當(dāng)前Crawler對(duì)象。
- spider- 已知處理URL的Spider,或者Spider如果沒(méi)有為當(dāng)前URL找到的爬蟲(chóng),則為 對(duì)象
- request- Request最后一個(gè)抓取頁(yè)面的對(duì)象。您可以replace() 使用fetch 快捷方式或使用快捷方式獲取新請(qǐng)求(而不離開(kāi)shell)來(lái)修改此請(qǐng)求。
- response- 包含Response最后一個(gè)抓取頁(yè)面的對(duì)象
- settings- 當(dāng)前Scrapy設(shè)置
shell會(huì)話的示例
下面是一個(gè)典型的shell會(huì)話示例,我們首先抓取 http://scrapy.org頁(yè)面,然后繼續(xù)抓取https://reddit.com 頁(yè)面。最后,我們將(Reddit)請(qǐng)求方法修改為POST并重新獲取它獲取錯(cuò)誤。我們通過(guò)在Windows中鍵入Ctrl-D(在Unix系統(tǒng)中)或Ctrl-Z結(jié)束會(huì)話。
請(qǐng)記住,在這里提取的數(shù)據(jù)可能不一樣,當(dāng)你嘗試它,因?yàn)槟切┚W(wǎng)頁(yè)不是靜態(tài)的,可能已經(jīng)改變了你測(cè)試這個(gè)。這個(gè)例子的唯一目的是讓你熟悉Scrapy shell的工作原理。
首先,我們啟動(dòng)shell:
scrapy shell 'http://scrapy.org' --nolog
然后,shell獲取URL(使用Scrapy下載器)并打印可用對(duì)象和有用的快捷方式列表(您會(huì)注意到這些行都以[s]前綴開(kāi)頭):
[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 http://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
>>>
之后,我們可以開(kāi)始使用對(duì)象:
>>> response.xpath('//title/text()').extract_first()
'Scrapy | A Fast and Powerful Scraping and Web Crawling Framework'
>>> fetch("http://reddit.com")
>>> response.xpath('//title/text()').extract()
['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']}
>>>
從爬蟲(chóng)調(diào)用shell檢查響應(yīng)
有時(shí)候,你想檢查在爬蟲(chóng)的某一點(diǎn)被處理的響應(yīng),如果只檢查你期望的響應(yīng)到達(dá)那里。
這可以通過(guò)使用該scrapy.shell.inspect_response功能來(lái)實(shí)現(xiàn)。
下面是一個(gè)如何從爬蟲(chóng)調(diào)用它的例子:
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.
當(dāng)你運(yùn)行爬蟲(chóng),你會(huì)得到類似的東西:
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瀏覽器中打開(kāi)響應(yīng),看看它是否是您期望的響應(yīng):
>>> view(response)
True
最后,您按Ctrl-D(或Windows中的Ctrl-Z)退出外殼并繼續(xù)抓?。?/p>
>>> ^D
2014-01-23 17:50:03-0400 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://example.net> (referer: None)
...
請(qǐng)注意,您不能使用fetch此處的快捷方式,因?yàn)镾crapy引擎被shell阻止。然而,在你離開(kāi)shell之后,爬蟲(chóng)會(huì)繼續(xù)爬到它停止的地方,如上圖所示。