1. 程式人生 > >小白學 Python 爬蟲(35):爬蟲框架 Scrapy 入門基礎(三) Selector 選擇器

小白學 Python 爬蟲(35):爬蟲框架 Scrapy 入門基礎(三) Selector 選擇器

人生苦短,我用 Python

前文傳送門:

小白學 Python 爬蟲(1):開篇

小白學 Python 爬蟲(2):前置準備(一)基本類庫的安裝

小白學 Python 爬蟲(3):前置準備(二)Linux基礎入門

小白學 Python 爬蟲(4):前置準備(三)Docker基礎入門

小白學 Python 爬蟲(5):前置準備(四)資料庫基礎

小白學 Python 爬蟲(6):前置準備(五)爬蟲框架的安裝

小白學 Python 爬蟲(7):HTTP 基礎

小白學 Python 爬蟲(8):網頁基礎

小白學 Python 爬蟲(9):爬蟲基礎

小白學 Python 爬蟲(10):Session 和 Cookies

小白學 Python 爬蟲(11):urllib 基礎使用(一)

小白學 Python 爬蟲(12):urllib 基礎使用(二)

小白學 Python 爬蟲(13):urllib 基礎使用(三)

小白學 Python 爬蟲(14):urllib 基礎使用(四)

小白學 Python 爬蟲(15):urllib 基礎使用(五)

小白學 Python 爬蟲(16):urllib 實戰之爬取妹子圖

小白學 Python 爬蟲(17):Requests 基礎使用

小白學 Python 爬蟲(18):Requests 進階操作

小白學 Python 爬蟲(19):Xpath 基操

小白學 Python 爬蟲(20):Xpath 進階

小白學 Python 爬蟲(21):解析庫 Beautiful Soup(上)

小白學 Python 爬蟲(22):解析庫 Beautiful Soup(下)

小白學 Python 爬蟲(23):解析庫 pyquery 入門

小白學 Python 爬蟲(24):2019 豆瓣電影排行

小白學 Python 爬蟲(25):爬取股票資訊

小白學 Python 爬蟲(26):為啥買不起上海二手房你都買不起

小白學 Python 爬蟲(27):自動化測試框架 Selenium 從入門到放棄(上)

小白學 Python 爬蟲(28):自動化測試框架 Selenium 從入門到放棄(下)

小白學 Python 爬蟲(29):Selenium 獲取某大型電商網站商品資訊

小白學 Python 爬蟲(30):代理基礎

小白學 Python 爬蟲(31):自己構建一個簡單的代理池

小白學 Python 爬蟲(32):非同步請求庫 AIOHTTP 基礎入門

小白學 Python 爬蟲(33):爬蟲框架 Scrapy 入門基礎(一)

小白學 Python 爬蟲(34):爬蟲框架 Scrapy 入門基礎(二)

引言

我們之前有介紹過通過 pyquery 、 Beautiful Soup 、 lxml 來提取網頁資料。

但是在 Scrapy 中,同樣也提供了自己獨有的資料提取方式,即 Selector(選擇器)。Selector 是基於 lxml 來構建的,支援 XPath 選擇器、CSS 選擇器以及正則表示式,功能全面,解析速度和準確度非常高。

獨立使用

Scrapy Selectors 是 Parsel 庫的包裝。包裝的目的是提供與 Scrapy Response 物件的更好的整合。

Parsel 是一個獨立的 Web 抓取庫,無需 Scrapy 即可使用。它在後臺使用 lxml 庫,並在 lxml API 之上實現了一個簡單的 API 。這意味著 Scrapy 選擇器的速度和解析精度與 lxml 非常相似。

我們可以寫一個簡單的示例程式碼來測試一下 Selectors 的單獨使用。

from scrapy import Selector

body = '<html><head><title>Hello Python</title></head></html>'
selector = Selector(text=body)
title = selector.xpath('//title/text()').extract_first()
print(title)

執行結果如下:

Hello Python

這個簡單的示例我們並沒有在 Scrapy 框架中執行,而是把 Scrapy 中的 Selector 單獨拿出來使用了。

Selector 的使用同其他解析庫類似,如果方便的話,我們也可以在其他專案中直接使用 Selector 來提取資料。

Scrapy Shell

由於 Selector 主要是與 Scrapy 結合使用,如 Scrapy 的回撥函式中的引數 response 直接呼叫 xpath() 或者 css() 方法來提取資料,所以在這裡我們藉助 Scrapy shell 來模擬 Scrapy 請求的過程,來講解相關的提取方法。

這裡我們藉助官方文件的示例進行演示。

https://docs.scrapy.org/en/latest/_static/selectors-sample1.html

為了完整起見,以下是其完整的HTML程式碼:

<html>
 <head>
  <base href='http://example.com/' />
  <title>Example website</title>
 </head>
 <body>
  <div id='images'>
   <a href='image1.html'>Name: My image 1 <br /><img src='image1_thumb.jpg' /></a>
   <a href='image2.html'>Name: My image 2 <br /><img src='image2_thumb.jpg' /></a>
   <a href='image3.html'>Name: My image 3 <br /><img src='image3_thumb.jpg' /></a>
   <a href='image4.html'>Name: My image 4 <br /><img src='image4_thumb.jpg' /></a>
   <a href='image5.html'>Name: My image 5 <br /><img src='image5_thumb.jpg' /></a>
  </div>
 </body>
</html>

首先,讓我們開啟 Scrapy shell,在命令列輸入如下命令:

scrapy shell https://docs.scrapy.org/en/latest/_static/selectors-sample1.html

這時,我們進入了 Scrapy Shell 模式,其實就是 Scrapy 發起了一次請求,然後把一些可操作的變數傳遞給我們:

Xpath 選擇器

目前我們在 Scrapy shell 之中,這裡我們主要操作的物件是 response 。

response 有一個屬性是 selector ,我們可以通過呼叫 response.selector.xpath 對資料進行獲取,同時, Scrapy 為我們提供了兩個更加簡潔的方法, response.xpath() 和 response.css() ,這兩個方法完全等同於 response.selector.xpath() 和 response.selector.css() 。

出於寫法上的簡便考慮,小編後續的程式碼將全部使用 response.xpath() 和 response.css() 。

首先,我們簡單的獲取一下 a 標籤:

>>> result = response.xpath('//a')
>>> result
[<Selector xpath='//a' data='<a href="image1.html">Name: My image ...'>, 
<Selector xpath='//a' data='<a href="image2.html">Name: My image ...'>, 
<Selector xpath='//a' data='<a href="image3.html">Name: My image ...'>, 
<Selector xpath='//a' data='<a href="image4.html">Name: My image ...'>, 
<Selector xpath='//a' data='<a href="image5.html">Name: My image ...'>]

>>> type(result)
<class 'scrapy.selector.unified.SelectorList'>

這裡我們獲取到的結果是由 Selector 組成的列表: SelectorList 。

它的型別是 scrapy.selector.unified.SelectorList

SelectorList 和 Selector 都可以繼續呼叫 xpath() 和 css() 等方法來進一步提取資料。

接著上面的例子,我們繼續嘗試獲取 a 標籤中的 img 標籤:

>>> result.xpath('./img')
[<Selector xpath='./img' data='<img src="image1_thumb.jpg">'>, 
<Selector xpath='./img' data='<img src="image2_thumb.jpg">'>, 
<Selector xpath='./img' data='<img src="image3_thumb.jpg">'>, 
<Selector xpath='./img' data='<img src="image4_thumb.jpg">'>, 
<Selector xpath='./img' data='<img src="image5_thumb.jpg">'>]

這裡我們獲取到了所有的 a 標籤中的 img 標籤。

注意: 選擇器的最前方加 .,這代表提取元素內部的資料,如果沒有加點,則代表從根節點開始提取。

此處我們用了./img 的提取方式,則代表從 a 節點裡進行提取。如果此處我們用 //img ,則還是從 html 節點裡進行提取。

現在我們已經獲得了 Selector 型別的節點 a ,如果我們想要將 a 節點元素提取出來,可以使用 extract() 方法,如下:

>>> result.extract()
['<a href="image1.html">Name: My image 1 <br><img src="image1_thumb.jpg"></a>', 
'<a href="image2.html">Name: My image 2 <br><img src="image2_thumb.jpg"></a>', 
'<a href="image3.html">Name: My image 3 <br><img src="image3_thumb.jpg"></a>', 
'<a href="image4.html">Name: My image 4 <br><img src="image4_thumb.jpg"></a>', 
'<a href="image5.html">Name: My image 5 <br><img src="image5_thumb.jpg"></a>']

這裡我們如果想要獲得內容的文字內容,可以使用 /text() ,如果想要獲取 href 屬性的內容可以使用 /@href

我們來看一個完整的示例:

>>> response.xpath('//a[@href="image1.html"]/text()').extract()
['Name: My image 1 ']

這裡我們限制的結果,只查到的一條資料,很多情況下我們都會獲得多條資料,這時如果想獲取第一個元素的內容,可以使用索引的方式,如下:

>>> response.xpath('//a/text()').extract()[0]
'Name: My image 1 '

這樣其實有一點點的小問題,如果當前我們需要的列表為空,這裡直接會產生陣列越界的異常。

Scrapy 為我們提供了另一個方法 extract_first() ,專門用來解決這個問題,上面的示例可以改寫成下面的樣子:

>>> response.xpath('//a/text()').extract_first()
'Name: My image 1 '

同時我們也可以為 extract_first() 方法設定一個預設值引數,這樣當 XPath 規則提取不到內容時會直接使用預設值。

>>> response.xpath('//a[@href="image1"]/text()').extract_first('Default')
'Default'

CSS 選擇器

我們接著看 CSS 選擇器,還是上面的示例,小編這裡就不多 BB 了,直接上示例:

>>> response.css('a')
[<Selector xpath='descendant-or-self::a' data='<a href="image1.html">Name: My image ...'>, 
<Selector xpath='descendant-or-self::a' data='<a href="image2.html">Name: My image ...'>, 
<Selector xpath='descendant-or-self::a' data='<a href="image3.html">Name: My image ...'>, 
<Selector xpath='descendant-or-self::a' data='<a href="image4.html">Name: My image ...'>, 
<Selector xpath='descendant-or-self::a' data='<a href="image5.html">Name: My image ...'>]

我們同樣可以進行屬性選擇和巢狀選擇:

>>> response.css('a[href="image1.html"]').extract()
['<a href="image1.html">Name: My image 1 <br><img src="image1_thumb.jpg"></a>']
>>> response.css('a[href="image1.html"] img').extract()
['<img src="image1_thumb.jpg">']

接下來獲取文字值和屬性值的方法稍有區別:

>>> response.css('a[href="image1.html"]::text').extract()
['Name: My image 1 ']
>>> response.css('a[href="image1.html"] img::attr(src)').extract()
['image1_thumb.jpg']

獲取文字和屬性需要用 ::text::attr() 的寫法。

當然,我們的 CSS 選擇器和 Xpath 選擇器一樣可以巢狀選擇,一個簡單的小示例感受下:

>>> response.xpath('//a').css('img').xpath('@src').extract()
['image1_thumb.jpg', 'image2_thumb.jpg', 'image3_thumb.jpg', 'image4_thumb.jpg', 'image5_thumb.jpg']

Selector 選擇器就先介紹到這裡了,更多的內容和用法可以參考官方文件:https://docs.scrapy.org/en/latest/topics/selectors.html

本文沒什麼程式碼,所以示例程式碼就不放了。

相關推薦

Python 爬蟲35爬蟲框架 Scrapy 入門基礎 Selector 選擇

人生苦短,我用 Python 前文傳送門: 小白學 Python 爬蟲(1):開篇 小白學 Python 爬蟲(2):前置準備(一)基本類庫的安裝 小白學 Python 爬蟲(3):前置準備(二)Linux基礎入門 小白學 Python 爬蟲(4):前置準備(三)Docker基礎入門 小白學 Pyth

Python 爬蟲33爬蟲框架 Scrapy 入門基礎

人生苦短,我用 Python 前文傳送門: 小白學 Python 爬蟲(1):開篇 小白學 Python 爬蟲(2):前置準備(一)基本類庫的安裝 小白學 Python 爬蟲(3):前置準備(二)Linux基礎入門 小白學 Python 爬蟲(4):前置準備(三)Docker基礎入門 小白學 Pyth

Python 爬蟲34爬蟲框架 Scrapy 入門基礎

人生苦短,我用 Python 前文傳送門: 小白學 Python 爬蟲(1):開篇 小白學 Python 爬蟲(2):前置準備(一)基本類庫的安裝 小白學 Python 爬蟲(3):前置準備(二)Linux基礎入門 小白學 Python 爬蟲(4):前置準備(三)Docker基礎入門 小白學 Pyth

Python 爬蟲36爬蟲框架 Scrapy 入門基礎 Downloader Middleware

人生苦短,我用 Python 前文傳送門: 小白學 Python 爬蟲(1):開篇 小白學 Python 爬蟲(2):前置準備(一)基本類庫的安裝 小白學 Python 爬蟲(3):前置準備(二)Linux基礎入門 小白學 Python 爬蟲(4):前置準備(三)Docker基礎入門 小白學 Pyth

Python 爬蟲37爬蟲框架 Scrapy 入門基礎 Spider Middleware

人生苦短,我用 Python 前文傳送門: 小白學 Python 爬蟲(1):開篇 小白學 Python 爬蟲(2):前置準備(一)基本類庫的安裝 小白學 Python 爬蟲(3):前置準備(二)Linux基礎入門 小白學 Python 爬蟲(4):前置準備(三)Docker基礎入門 小白學 Pyth

Python 爬蟲40爬蟲框架 Scrapy 入門基礎對接 Selenium 實戰

人生苦短,我用 Python 前文傳送門: 小白學 Python 爬蟲(1):開篇 小白學 Python 爬蟲(2):前置準備(一)基本類庫的安裝 小白學 Python 爬蟲(3):前置準備(二)Linux基礎入門 小白學 Python 爬蟲(4):前置準備(三)Docker基礎入門 小白學 Pyth

Python 爬蟲41爬蟲框架 Scrapy 入門基礎對接 Splash 實戰

人生苦短,我用 Python 前文傳送門: 小白學 Python 爬蟲(1):開篇 小白學 Python 爬蟲(2):前置準備(一)基本類庫的安裝 小白學 Python 爬蟲(3):前置準備(二)Linux基礎入門 小白學 Python 爬蟲(4):前置準備(三)Docker基礎入門 小白學 Pyth

Python 爬蟲2前置準備基本類庫的安裝

人生苦短,我用 Python 前文傳送門: 小白學 Python 爬蟲(1):開篇 本篇內容較長,各位同學可以先收藏後再看~~ 在開始講爬蟲之前,還是先把環境搞搞好,工欲善其事必先利其器嘛~~~ 本篇文章主要介紹 Python 爬蟲所使用到的請求庫和解析庫,請求庫用來請求目標內容,解析庫用來解析請

Python 爬蟲3前置準備Linux基礎入門

人生苦短,我用 Python 前文傳送門: 小白學 Python 爬蟲(1):開篇 小白學 Python 爬蟲(2):前置準備(一)基本類庫的安裝 Linux 基礎 CentOS 官網: https://www.centos.org/ 。 CentOS 官方下載連結: https://www.cent

Python 爬蟲4前置準備Docker基礎入門

人生苦短,我用 Python 前文傳送門: 小白學 Python 爬蟲(1):開篇 小白學 Python 爬蟲(2):前置準備(一)基本類庫的安裝 小白學 Python 爬蟲(3):前置準備(二)Linux基礎入門 Docker 基礎 首先說一件事情,就在本文寫作前一天,Mirantis 這家公司宣佈

Python 爬蟲7HTTP 基礎

人生苦短,我用 Python 前文傳送門: 小白學 Python 爬蟲(1):開篇 小白學 Python 爬蟲(2):前置準備(一)基本類庫的安裝 小白學 Python 爬蟲(3):前置準備(二)Linux基礎入門 小白學 Python 爬蟲(4):前置準備(三)Docker基礎入門 小白學 Pyth

Python 爬蟲8網頁基礎

人生苦短,我用 Python 前文傳送門: 小白學 Python 爬蟲(1):開篇 小白學 Python 爬蟲(2):前置準備(一)基本類庫的安裝 小白學 Python 爬蟲(3):前置準備(二)Linux基礎入門 小白學 Python 爬蟲(4):前置準備(三)Docker基礎入門 小白學 Pyth

Python 爬蟲9爬蟲基礎

人生苦短,我用 Python 前文傳送門: 小白學 Python 爬蟲(1):開篇 小白學 Python 爬蟲(2):前置準備(一)基本類庫的安裝 小白學 Python 爬蟲(3):前置準備(二)Linux基礎入門 小白學 Python 爬蟲(4):前置準備(三)Docker基礎入門 小白學 Pyth

Python 爬蟲10Session 和 Cookies

人生苦短,我用 Python 前文傳送門: 小白學 Python 爬蟲(1):開篇 小白學 Python 爬蟲(2):前置準備(一)基本類庫的安裝 小白學 Python 爬蟲(3):前置準備(二)Linux基礎入門 小白學 Python 爬蟲(4):前置準備(三)Docker基礎入門 小白學 Pyth

Python 爬蟲11urllib 基礎使用

人生苦短,我用 Python 前文傳送門: 小白學 Python 爬蟲(1):開篇 小白學 Python 爬蟲(2):前置準備(一)基本類庫的安裝 小白學 Python 爬蟲(3):前置準備(二)Linux基礎入門 小白學 Python 爬蟲(4):前置準備(三)Docker基礎入門 小白學 Pyth

Python 爬蟲12urllib 基礎使用

人生苦短,我用 Python 前文傳送門: 小白學 Python 爬蟲(1):開篇 小白學 Python 爬蟲(2):前置準備(一)基本類庫的安裝 小白學 Python 爬蟲(3):前置準備(二)Linux基礎入門 小白學 Python 爬蟲(4):前置準備(三)Docker基礎入門 小白學 Pyth

Python 爬蟲13urllib 基礎使用

人生苦短,我用 Python 前文傳送門: 小白學 Python 爬蟲(1):開篇 小白學 Python 爬蟲(2):前置準備(一)基本類庫的安裝 小白學 Python 爬蟲(3):前置準備(二)Linux基礎入門 小白學 Python 爬蟲(4):前置準備(三)Docker基礎入門 小白學 Pyth

Python 爬蟲14urllib 基礎使用

人生苦短,我用 Python 前文傳送門: 小白學 Python 爬蟲(1):開篇 小白學 Python 爬蟲(2):前置準備(一)基本類庫的安裝 小白學 Python 爬蟲(3):前置準備(二)Linux基礎入門 小白學 Python 爬蟲(4):前置準備(三)Docker基礎入門 小白學 Pyth

Python 爬蟲15urllib 基礎使用

人生苦短,我用 Python 前文傳送門: 小白學 Python 爬蟲(1):開篇 小白學 Python 爬蟲(2):前置準備(一)基本類庫的安裝 小白學 Python 爬蟲(3):前置準備(二)Linux基礎入門 小白學 Python 爬蟲(4):前置準備(三)Docker基礎入門 小白學 Pyth

Python 爬蟲17Requests 基礎使用

人生苦短,我用 Python 前文傳送門: 小白學 Python 爬蟲(1):開篇 小白學 Python 爬蟲(2):前置準備(一)基本類庫的安裝 小白學 Python 爬蟲(3):前置準備(二)Linux基礎入門 小白學 Python 爬蟲(4):前置準備(三)Docker基礎入門 小白學 Pyth