# 使用瀏覽器的開發人員工具進行抓取
> 譯者:[OSGeo 中國](https://www.osgeo.cn/)
下面是關于如何使用瀏覽器的開發人員工具來簡化抓取過程的一般指南。現在幾乎所有瀏覽器都內置了 [Developer Tools](https://en.wikipedia.org/wiki/Web_development_tools) 盡管我們將在本指南中使用firefox,但這些概念適用于任何其他瀏覽器。
在本指南中,我們將介紹通過抓取從瀏覽器的開發人員工具中使用的基本工具 [quotes.toscrape.com](http://quotes.toscrape.com) .
## 檢查實時瀏覽器DOM時的注意事項
由于開發人員工具在一個活動的瀏覽器DOM上運行,所以在檢查頁面源代碼時,您實際上看到的不是原始的HTML,而是應用了一些瀏覽器清理和執行javascript代碼后修改的HTML。尤其是火狐,以添加 `<tbody>` 元素到表。另一方面,scrapy不修改原始頁面html,因此如果使用 `<tbody>` 在xpath表達式中。
因此,您應該記住以下幾點:
* 檢查DOM以查找要在Scrapy中使用的xpaths時禁用javascript(在“開發人員工具”設置中,單擊 <cite>Disable JavaScript</cite>)
* 不要使用完整的xpath路徑,使用基于屬性的相對路徑和智能路徑(例如 `id` , `class` , `width` 或任何識別特征,如 `contains(@href, 'image')` .
* 從不包括 `<tbody>` xpath表達式中的元素,除非您真正知道自己在做什么
## 查看網站
到目前為止,開發人員工具最方便的特性是 <cite>Inspector</cite> 功能,允許您檢查任何網頁的基本HTML代碼。為了演示檢查員,讓我們看看 [quotes.toscrape.com](http://quotes.toscrape.com) 現場。
在這個網站上,我們總共有來自不同作者的十個引用,其中有特定的標簽,還有前十個標簽。假設我們想要提取這個頁面上的所有引用,而不需要任何關于作者、標簽等的元信息。
我們不必查看頁面的整個源代碼,只需右鍵單擊一個報價并選擇 `Inspect Element (Q)` 打開了 <cite>Inspector</cite>. 在里面你應該看到這樣的東西:
[](../_images/inspector_01.png)
我們感興趣的是:
```py
<div class="quote" itemscope="" itemtype="http://schema.org/CreativeWork">
<span class="text" itemprop="text">(...)</span>
<span>(...)</span>
<div class="tags">(...)</div>
</div>
```
如果你在第一個上面徘徊 `div` 正上方 `span` 在屏幕截圖中突出顯示的標簽,您將看到網頁的相應部分也會突出顯示。現在我們有了一個部分,但是我們在任何地方都找不到報價文本。
的優勢 <cite>Inspector</cite> 它自動展開和折疊網頁的部分和標簽,大大提高了可讀性。您可以通過單擊標簽前面的箭頭或直接雙擊標簽來展開和折疊標簽。如果我們擴大 `span` 帶標簽 `class= "text"` 我們將看到我們單擊的報價文本。這個 <cite>Inspector</cite> 允許將xpaths復制到選定元素。讓我們試試看:右鍵單擊 `span` 選擇標記 `Copy > XPath` 然后像這樣把它貼在破殼里:
```py
$ scrapy shell "http://quotes.toscrape.com/"
(...)
>>> response.xpath('/html/body/div/div[2]/div[1]/div[1]/span[1]/text()').getall()
['"The world as we have created it is a process of our thinking. It cannot be changed without changing our thinking.”]
```
添加 `text()` 最后,我們可以用這個基本選擇器提取第一個報價。但這個xpath并沒有那么聰明。它所做的就是在源代碼中沿著所需的路徑從 `html` . 那么讓我們看看我們是否可以改進一下xpath:
如果我們檢查 <cite>Inspector</cite> 我們將再次看到,在我們的 `div` 標簽我們有九個相同的 `div` 標簽,每個標簽都具有與第一個相同的屬性。如果我們擴展其中任何一個,我們將看到與第一個報價相同的結構:兩個 `span` 標簽和一個 `div` 標簽。我們可以擴大每個 `span` 帶標簽 `class="text"` 在我們內部 `div` 標記并查看每個引用:
```py
<div class="quote" itemscope="" itemtype="http://schema.org/CreativeWork">
<span class="text" itemprop="text">
“The world as we have created it is a process of our thinking. It cannot be changed without changing our thinking.”
</span>
<span>(...)</span>
<div class="tags">(...)</div>
</div>
```
有了這些知識,我們可以改進我們的xpath:我們只需選擇 `span` 標簽與 `class="text"` 通過使用 [has-class-extension](https://parsel.readthedocs.io/en/latest/usage.html#other-xpath-extensions) ::
```py
>>> response.xpath('//span[has-class("text")]/text()').getall()
['"The world as we have created it is a process of our thinking. It cannot be changed without changing our thinking.”,
'“It is our choices, Harry, that show what we truly are, far more than our abilities.”',
'“There are only two ways to live your life. One is as though nothing is a miracle. The other is as though everything is a miracle.”',
(...)]
```
通過一個簡單、更聰明的xpath,我們能夠從頁面中提取所有的引號。我們可以在第一個xpath上構建一個循環,以增加最后一個xpath的數量。 `div` ,但這將不必要地復雜,只需使用 `has-class("text")` 我們能夠在一行中提取所有報價。
這個 <cite>Inspector</cite> 還有很多其他有用的功能,比如在源代碼中搜索或者直接滾動到您選擇的元素。讓我們演示一個用例:
說你想找到 `Next` 頁面上的按鈕。類型 `Next` 在搜索欄的右上角 <cite>Inspector</cite>. 你應該得到兩個結果。第一個是 `li` 帶標簽 `class="text"` ,第二個是 `a` 標簽。右鍵單擊 `a` 標記與選擇 `Scroll into View` . 如果您將鼠標懸停在標簽上,您將看到突出顯示的按鈕。從這里我們可以很容易地創建一個 [Link Extractor](link-extractors.html#topics-link-extractors) 跟隨分頁。在這樣一個簡單的站點上,可能不需要從視覺上查找元素,而是 `Scroll into View` 函數在復雜的站點上非常有用。
請注意,搜索欄也可用于搜索和測試CSS選擇器。例如,您可以搜索 `span.text` 查找所有報價文本。而不是全文搜索,這將搜索 `span` 帶標簽 `class="text"` 在頁面中。
## 網絡工具
在抓取過程中,您可能會遇到動態網頁,其中頁面的某些部分是通過多個請求動態加載的。雖然這很棘手,但是 <cite>Network</cite>- 開發人員工具中的工具大大簡化了這項任務。為了演示網絡工具,讓我們看一下頁面 [quotes.toscrape.com/scroll](quotes.toscrape.com/scroll/) .
頁面與基本頁面非常相似 [quotes.toscrape.com](http://quotes.toscrape.com) -第頁,但不是上面提到的 `Next` 按鈕,當您滾動到底部時,頁面會自動加載新的引號。我們可以繼續直接嘗試不同的xpaths,但是我們將檢查另一個非常有用的命令,來自scriby shell::
```py
$ scrapy shell "quotes.toscrape.com/scroll"
(...)
>>> view(response)
```
瀏覽器窗口應該和網頁一起打開,但有一個關鍵的區別:我們看到的不是引用,而是一個帶單詞的綠色條。 `Loading...` .
[](../_images/network_01.png)
這個 `view(response)` 命令讓我們查看shell或稍后 Spider 從服務器接收到的響應。這里我們看到加載了一些基本模板,其中包括標題、登錄按鈕和頁腳,但是缺少引號。這告訴我們報價是從不同的請求加載的,而不是 `quotes.toscrape/scroll` .
如果你點擊 `Network` 選項卡,您可能只能看到兩個條目。我們要做的第一件事是通過單擊 `Persist Logs` . 如果禁用此選項,則每次導航到不同的頁面時,日志都會自動清除。啟用這個選項是一個很好的默認設置,因為它可以讓我們控制何時清除日志。
如果我們現在重新加載頁面,您將看到日志中填充了六個新的請求。
[](../_images/network_02.png)
在這里,我們可以看到在重新加載頁面時發出的每個請求,并且可以檢查每個請求及其響應。因此,讓我們找出我們的報價來自哪里:
首先單擊帶有名稱的請求 `scroll` . 在右邊,您現在可以檢查請求。在 `Headers` 您將找到有關請求頭的詳細信息,例如URL、方法、IP地址等。我們將忽略其他選項卡并直接單擊 `Reponse` .
你應該在里面看到什么 `Preview` 窗格是呈現的HTML代碼,這正是我們調用 `view(response)` 在貝殼里。相應地 `type` 日志中的請求為 `html` . 其他請求的類型如下 `css` 或 `js` 但是我們感興趣的是一個要求 `quotes?page=1` 與類型 `json` .
如果我們點擊這個請求,我們會看到請求的URL是 `http://quotes.toscrape.com/api/quotes?page=1` 響應是一個包含我們的引號的JSON對象。我們也可以右鍵單擊請求并打開 `Open in new tab` 以獲得更好的概述。
[](../_images/network_03.png)
有了這個響應,我們現在可以輕松地解析JSON對象,并請求每個頁面獲取站點上的每個引用:
```py
import scrapy
import json
class QuoteSpider(scrapy.Spider):
name = 'quote'
allowed_domains = ['quotes.toscrape.com']
page = 1
start_urls = ['http://quotes.toscrape.com/api/quotes?page=1']
def parse(self, response):
data = json.loads(response.text)
for quote in data["quotes"]:
yield {"quote": quote["text"]}
if data["has_next"]:
self.page += 1
url = "http://quotes.toscrape.com/api/quotes?page={}".format(self.page)
yield scrapy.Request(url=url, callback=self.parse)
```
這個 Spider 程序從QuotesAPI的第一頁開始。對于每個響應,我們分析 `response.text` 并分配給 `data` . 這讓我們可以像在Python字典上一樣對JSON對象進行操作。我們迭代 `quotes` 打印出 `quote["text"]` . 如果方便的話 `has_next` 元素是 `true` (嘗試加載 [quotes.toscrape.com/api/quotes?page=10](http://quotes.toscrape.com/api/quotes?page=10) 在您的瀏覽器或大于10的頁碼中,我們增加 `page` 屬性與 `yield` 一個新的請求,將遞增的頁碼插入到 `url` .
你可以看到,在 <cite>Network</cite>- 工具我們能夠輕松地復制頁面滾動功能的動態請求。對動態頁面進行爬行可能非常困難,頁面也可能非常復雜,但是(主要)歸根結底就是識別正確的請求并在 Spider 中復制它。
- 簡介
- 第一步
- Scrapy at a glance
- 安裝指南
- Scrapy 教程
- 實例
- 基本概念
- 命令行工具
- Spider
- 選擇器
- 項目
- 項目加載器
- Scrapy shell
- 項目管道
- Feed 導出
- 請求和響應
- 鏈接提取器
- 設置
- 例外情況
- 內置服務
- Logging
- 統計數據集合
- 發送電子郵件
- 遠程登錄控制臺
- Web服務
- 解決具體問題
- 常見問題
- 調試spiders
- Spider 合約
- 常用做法
- 通用爬蟲
- 使用瀏覽器的開發人員工具進行抓取
- 調試內存泄漏
- 下載和處理文件和圖像
- 部署 Spider
- AutoThrottle 擴展
- Benchmarking
- 作業:暫停和恢復爬行
- 延伸 Scrapy
- 體系結構概述
- 下載器中間件
- Spider 中間件
- 擴展
- 核心API
- 信號
- 條目導出器
- 其余所有
- 發行說明
- 為 Scrapy 貢獻
- 版本控制和API穩定性