人生苦短,我用 Pythoncss
前文傳送門:html
小白學 Python 爬蟲(2):前置準備(一)基本類庫的安裝正則表達式
小白學 Python 爬蟲(3):前置準備(二)Linux基礎入門shell
小白學 Python 爬蟲(4):前置準備(三)Docker基礎入門數據庫
小白學 Python 爬蟲(5):前置準備(四)數據庫基礎數組
小白學 Python 爬蟲(6):前置準備(五)爬蟲框架的安裝框架
小白學 Python 爬蟲(8):網頁基礎scrapy
小白學 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 爬蟲(21):解析庫 Beautiful Soup(上)
小白學 Python 爬蟲(22):解析庫 Beautiful Soup(下)
小白學 Python 爬蟲(23):解析庫 pyquery 入門
小白學 Python 爬蟲(26):爲啥買不起上海二手房你都買不起
小白學 Python 爬蟲(27):自動化測試框架 Selenium 從入門到放棄(上)
小白學 Python 爬蟲(28):自動化測試框架 Selenium 從入門到放棄(下)
小白學 Python 爬蟲(29):Selenium 獲取某大型電商網站商品信息
小白學 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 來提取數據。
因爲 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 發起了一次請求,而後把一些可操做的變量傳遞給咱們:
目前咱們在 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 選擇器,仍是上面的示例,小編這裏就很少 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
本文沒什麼代碼,因此示例代碼就不放了。