亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

關于Python3爬蟲中Selector的用法

發布時間:2020-08-03 09:34:22 來源:億速云 閱讀:175 作者:清晨 欄目:編程語言

小編給大家分享一下關于Python3爬蟲中Selector的用法,相信大部分人都還不怎么了解,因此分享這篇文章給大家學習,希望大家閱讀完這篇文章后大所收獲,下面讓我們一起去學習方法吧!

Selector 的用法

我們之前介紹了利用 Beautiful Soup、pyquery 以及正則表達式來提取網頁數據,這確實非常方便。而 Scrapy 還提供了自己的數據提取方法,即 Selector(選擇器)。Selector 是基于 lxml 來構建的,支持 XPath 選擇器、CSS 選擇器以及正則表達式,功能全面,解析速度和準確度非常高。

本節將介紹 Selector 的用法。

1. 直接使用

Selector 是一個可以獨立使用的模塊。我們可以直接利用 Selector 這個類來構建一個選擇器對象,然后調用它的相關方法如 xpath()、css() 等來提取數據。

例如,針對一段 HTML 代碼,我們可以用如下方式構建 Selector 對象來提取數據:

from scrapy import Selector
body = '<html><head><title>Hello World</title></head><body></body></html>'
selector = Selector(text=body)
title = selector.xpath('//title/text()').extract_first()
print(title)

運行結果:

Hello World

我們在這里沒有在 Scrapy 框架中運行,而是把 Scrapy 中的 Selector 單獨拿出來使用了,構建的時候傳入 text 參數,就生成了一個 Selector 選擇器對象,然后就可以像前面我們所用的 Scrapy 中的解析方式一樣,調用 xpath()、css() 等方法來提取了。

在這里我們查找的是源代碼中的 title 中的文本,在 XPath 選擇器最后加 text() 方法就可以實現文本的提取了。

以上內容就是 Selector 的直接使用方式。同 Beautiful Soup 等庫類似,Selector 其實也是強大的網頁解析庫。如果方便的話,我們也可以在其他項目中直接使用 Selector 來提取數據。

接下來,我們用實例來詳細講解 Selector 的用法。

2. Scrapy Shell

由于 Selector 主要是與 Scrapy 結合使用,如 Scrapy 的回調函數中的參數 response 直接調用 xpath() 或者 css() 方法來提取數據,所以在這里我們借助 Scrapy shell 來模擬 Scrapy 請求的過程,來講解相關的提取方法。

我們用官方文檔的一個樣例頁面來做演示:http://doc.scrapy.org/en/latest/_static/selectors-sample1.html。

開啟 Scrapy shell,在命令行輸入如下命令:

scrapy shell http://doc.scrapy.org/en/latest/_static/selectors-sample1.html

我們就進入到 Scrapy shell 模式。這個過程其實是,Scrapy 發起了一次請求,請求的 URL 就是剛才命令行下輸入的 URL,然后把一些可操作的變量傳遞給我們,如 request、response 等,如圖 13-5 所示。

關于Python3爬蟲中Selector的用法

圖 13-5 Scrapy Shell

我們可以在命令行模式下輸入命令調用對象的一些操作方法,回車之后實時顯示結果。這與 Python 的命令行交互模式是類似的。

接下來,演示的實例都將頁面的源碼作為分析目標,頁面源碼如下所示:

<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>

3. XPath 選擇器

進入 Scrapy shell 之后,我們將主要操作 response 這個變量來進行解析。因為我們解析的是 HTML 代碼,Selector 將自動使用 HTML 語法來分析。

response 有一個屬性 selector,我們調用 response.selector 返回的內容就相當于用 response 的 text 構造了一個 Selector 對象。通過這個 Selector 對象我們可以調用解析方法如 xpath()、css() 等,通過向方法傳入 XPath 或 CSS 選擇器參數就可以實現信息的提取。

我們用一個實例感受一下,如下所示:

>>> result = response.selector.xpath('//a')
>>> result
[<Selector xpath='//a' data='<a href="image1.html">Name: My image 1 <'>,
 <Selector xpath='//a' data='<a href="image2.html">Name: My image 2 <'>,
 <Selector xpath='//a' data='<a href="image3.html">Name: My image 3 <'>,
 <Selector xpath='//a' data='<a href="image4.html">Name: My image 4 <'>,
 <Selector xpath='//a' data='<a href="image5.html">Name: My image 5 <'>]
>>> type(result)
scrapy.selector.unified.SelectorList

打印結果的形式是 Selector 組成的列表,其實它是 SelectorList 類型,SelectorList 和 Selector 都可以繼續調用 xpath() 和 css() 等方法來進一步提取數據。

在上面的例子中,我們提取了 a 節點。接下來,我們嘗試繼續調用 xpath() 方法來提取 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 節點,結果為 5。

值得注意的是,選擇器的最前方加 .(點),這代表提取元素內部的數據,如果沒有加點,則代表從根節點開始提取。此處我們用了./img 的提取方式,則代表從 a 節點里進行提取。如果此處我們用 //img,則還是從 html 節點里進行提取。

我們剛才使用了 response.selector.xpath() 方法對數據進行了提取。Scrapy 提供了兩個實用的快捷方法,response.xpath() 和 response.css(),它們二者的功能完全等同于 response.selector.xpath() 和 response.selector.css()。方便起見,后面我們統一直接調用 response 的 xpath() 和 css() 方法進行選擇。

現在我們得到的是 SelectorList 類型的變量,該變量是由 Selector 對象組成的列表。我們可以用索引單獨取出其中某個 Selector 元素,如下所示:

>>> result[0]
<Selector xpath='//a' data='<a href="image1.html">Name: My image 1 <'>

我們可以像操作列表一樣操作這個 SelectorList。

但是現在獲取的內容是 Selector 或者 SelectorList 類型,并不是真正的文本內容。那么具體的內容怎么提取呢?

比如我們現在想提取出 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>']

這里使用了 extract() 方法,我們就可以把真實需要的內容獲取下來。

我們還可以改寫 XPath 表達式,來選取節點的內部文本和屬性,如下所示:

>>> response.xpath('//a/text()').extract()
['Name: My image 1 ', 'Name: My image 2 ', 'Name: My image 3 ', 'Name: My image 4 ', 'Name: My image 5 ']
>>> response.xpath('//a/@href').extract()
['image1.html', 'image2.html', 'image3.html', 'image4.html', 'image5.html']

我們只需要再加一層 /text() 就可以獲取節點的內部文本,或者加一層 /@href 就可以獲取節點的 href 屬性。其中,@符號后面內容就是要獲取的屬性名稱。

現在我們可以用一個規則把所有符合要求的節點都獲取下來,返回的類型是列表類型。

但是這里有一個問題:如果符合要求的節點只有一個,那么返回的結果會是什么呢?我們再用一個實例來感受一下,如下所示:

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

我們用屬性限制了匹配的范圍,使 XPath 只可以匹配到一個元素。然后用 extract() 方法提取結果,其結果還是一個列表形式,其文本是列表的第一個元素。但很多情況下,我們其實想要的數據就是第一個元素內容,這里我們通過加一個索引來獲取,如下所示:

python>>> response.xpath('//a[@href="image1.html"]/text()').extract()[0]
'Name: My image 1 '
但是,這個寫法很明顯是有風險的。一旦 XPath 有問題,那么 extract() 后的結果可能是一個空列表。如果我們再用索引來獲取,
那不就會可能導致數組越界嗎?
所以,另外一個方法可以專門提取單個元素,它叫作 extract_first()。我們可以改寫上面的例子如下所示:
```python
>>> response.xpath('//a[@href="image1.html"]/text()').extract_first()
'Name: My image 1 '

這樣,我們直接利用 extract_first() 方法將匹配的第一個結果提取出來,同時我們也不用擔心數組越界的問題。

另外我們也可以為 extract_first() 方法設置一個默認值參數,這樣當 XPath 規則提取不到內容時會直接使用默認值。例如將 XPath 改成一個不存在的規則,重新執行代碼,如下所示:

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

這里,如果 XPath 匹配不到任何元素,調用 extract_first() 會返回空,也不會報錯。

在第二行代碼中,我們還傳遞了一個參數當作默認值,如 Default Image。這樣如果 XPath 匹配不到結果的話,返回值會使用這個參數來代替,可以看到輸出正是如此。

現在為止,我們了解了 Scrapy 中的 XPath 的相關用法,包括嵌套查詢、提取內容、提取單個內容、獲取文本和屬性等。

4. CSS 選擇器

接下來,我們看看 CSS 選擇器的用法。

Scrapy 的選擇器同時還對接了 CSS 選擇器,使用 response.css() 方法可以使用 CSS 選擇器來選擇對應的元素。

例如在上文我們選取了所有的 a 節點,那么 CSS 選擇器同樣可以做到,如下所示:

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

同樣,調用 extract() 方法就可以提取出節點,如下所示:

python>>> response.css(‘a’).extract()
[‘Name: My image 1
‘, ‘Name: My image 2
‘, ‘Name: My image 3
‘, ‘Name: My image 4
‘, ‘Name: My image 5
‘]
用法和 XPath 選擇是完全一樣的。
另外,我們也可以進行屬性選擇和嵌套選擇,如下所示:
```python
>>> 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">']
```這里用 [href="image.html"] 限定了 href 屬性,可以看到匹配結果就只有一個了。另外如果想查找 a 節點內的 img 節點,
只需要再加一個空格和 img 即可。選擇器的寫法和標準 CSS 選擇器寫法如出一轍。
我們也可以使用 extract_first() 方法提取列表的第一個元素,如下所示:
```python
>>> response.css('a[href="image1.html"] img').extract_first()
'<img src="image1_thumb.jpg">'

接下來的兩個用法不太一樣。節點的內部文本和屬性的獲取是這樣實現的,如下所示:

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

獲取文本和屬性需要用::text 和::attr() 的寫法。而其他庫如 Beautiful Soup 或 pyquery 都有單獨的方法。

另外,CSS 選擇器和 XPath 選擇器一樣可以嵌套選擇。我們可以先用 XPath 選擇器選中所有 a 節點,再利用 CSS 選擇器選中 img 節點,再用 XPath 選擇器獲取屬性。我們用一個實例來感受一下,如下所示:

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

我們成功獲取了所有 img 節點的 src 屬性。

因此,我們可以隨意使用 xpath() 和 css() 方法二者自由組合實現嵌套查詢,二者是完全兼容的。

5. 正則匹配

Scrapy 的選擇器還支持正則匹配。比如,在示例的 a 節點中的文本類似于 Name: My image 1,現在我們只想把 Name: 后面的內容提取出來,這時就可以借助 re() 方法,實現如下:

>>> response.xpath('//a/text()').re('Name:s(.*)')
['My image 1 ', 'My image 2 ', 'My image 3 ', 'My image 4 ', 'My image 5 ']

我們給 re() 方法傳了一個正則表達式,其中 (.*) 就是要匹配的內容,輸出的結果就是正則表達式匹配的分組,結果會依次輸出。

如果同時存在兩個分組,那么結果依然會被按序輸出,如下所示:

>>> response.xpath('//a/text()').re('(.*?):s(.*)')
['Name', 'My image 1 ', 'Name', 'My image 2 ', 'Name', 'My image 3 ', 'Name', 'My image 4 ', 'Name', 'My image 5 ']

類似 extract_first() 方法,re_first() 方法可以選取列表的第一個元素,用法如下:

>>> response.xpath('//a/text()').re_first('(.*?):s(.*)')
'Name'
>>> response.xpath('//a/text()').re_first('Name:s(.*)')
'My image 1'

不論正則匹配了幾個分組,結果都會等于列表的第一個元素。

值得注意的是,response 對象不能直接調用 re() 和 re_first() 方法。如果想要對全文進行正則匹配,可以先調用 xpath() 方法再正則匹配,如下所示:

>>> response.re('Name:s(.*)')
Traceback (most recent call last):
  File "<console>", line 1, in <module>
AttributeError: 'HtmlResponse' object has no attribute 're'
>>> response.xpath('.').re('Name:s(.*)<br>')
['My image 1 ', 'My image 2 ', 'My image 3 ', 'My image 4 ', 'My image 5 ']
>>> response.xpath('.').re_first('Name:s(.*)<br>')
'My image 1'

通過上面的例子,我們可以看到,直接調用 re() 方法會提示沒有 re 屬性。但是這里首先調用了 xpath(‘.’) 選中全文,然后調用 re() 和 re_first() 方法,就可以進行正則匹配了。

以上是關于Python3爬蟲中Selector的用法的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

嘉兴市| 邻水| 平武县| 会同县| 当雄县| 额尔古纳市| 辽阳市| 新绛县| 隆安县| 玉溪市| 安溪县| 平原县| 都匀市| 长岭县| 平阴县| 漳州市| 通化市| 黄梅县| 卫辉市| 年辖:市辖区| 江门市| 大余县| 汾西县| 南华县| 建始县| 二手房| 阿克苏市| 晋江市| 竹山县| 闵行区| 孝昌县| 保靖县| 义乌市| 邻水| 许昌市| 靖边县| 开原市| 连云港市| 桃园县| 新乡县| 台南县|