關(guān)于Python3爬蟲中Selector的用法-創(chuàng)新互聯(lián)

創(chuàng)新互聯(lián)www.cdcxhl.cn八線動(dòng)態(tài)BGP香港云服務(wù)器提供商,新人活動(dòng)買多久送多久,劃算不套路!

創(chuàng)新互聯(lián)專注于富錦企業(yè)網(wǎng)站建設(shè),成都響應(yīng)式網(wǎng)站建設(shè)公司,成都做商城網(wǎng)站。富錦網(wǎng)站建設(shè)公司,為富錦等地區(qū)提供建站服務(wù)。全流程按需開發(fā),專業(yè)設(shè)計(jì),全程項(xiàng)目跟蹤,創(chuàng)新互聯(lián)專業(yè)和態(tài)度為您提供的服務(wù)

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

Selector 的用法

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

本節(jié)將介紹 Selector 的用法。

1. 直接使用

Selector 是一個(gè)可以獨(dú)立使用的模塊。我們可以直接利用 Selector 這個(gè)類來構(gòu)建一個(gè)選擇器對(duì)象,然后調(diào)用它的相關(guān)方法如 xpath()、css() 等來提取數(shù)據(jù)。

例如,針對(duì)一段 HTML 代碼,我們可以用如下方式構(gòu)建 Selector 對(duì)象來提取數(shù)據(jù):

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)

運(yùn)行結(jié)果:

Hello World

我們?cè)谶@里沒有在 Scrapy 框架中運(yùn)行,而是把 Scrapy 中的 Selector 單獨(dú)拿出來使用了,構(gòu)建的時(shí)候傳入 text 參數(shù),就生成了一個(gè) Selector 選擇器對(duì)象,然后就可以像前面我們所用的 Scrapy 中的解析方式一樣,調(diào)用 xpath()、css() 等方法來提取了。

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

以上內(nèi)容就是 Selector 的直接使用方式。同 Beautiful Soup 等庫(kù)類似,Selector 其實(shí)也是強(qiáng)大的網(wǎng)頁(yè)解析庫(kù)。如果方便的話,我們也可以在其他項(xiàng)目中直接使用 Selector 來提取數(shù)據(jù)。

接下來,我們用實(shí)例來詳細(xì)講解 Selector 的用法。

2. Scrapy Shell

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

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

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

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

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

關(guān)于Python3爬蟲中Selector的用法

圖 13-5 Scrapy Shell

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

接下來,演示的實(shí)例都將頁(yè)面的源碼作為分析目標(biāo),頁(yè)面源碼如下所示:

<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 選擇器

進(jìn)入 Scrapy shell 之后,我們將主要操作 response 這個(gè)變量來進(jìn)行解析。因?yàn)槲覀兘馕龅氖?HTML 代碼,Selector 將自動(dòng)使用 HTML 語(yǔ)法來分析。

response 有一個(gè)屬性 selector,我們調(diào)用 response.selector 返回的內(nèi)容就相當(dāng)于用 response 的 text 構(gòu)造了一個(gè) Selector 對(duì)象。通過這個(gè) Selector 對(duì)象我們可以調(diào)用解析方法如 xpath()、css() 等,通過向方法傳入 XPath 或 CSS 選擇器參數(shù)就可以實(shí)現(xiàn)信息的提取。

我們用一個(gè)實(shí)例感受一下,如下所示:

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

打印結(jié)果的形式是 Selector 組成的列表,其實(shí)它是 SelectorList 類型,SelectorList 和 Selector 都可以繼續(xù)調(diào)用 xpath() 和 css() 等方法來進(jìn)一步提取數(shù)據(jù)。

在上面的例子中,我們提取了 a 節(jié)點(diǎn)。接下來,我們嘗試?yán)^續(xù)調(diào)用 xpath() 方法來提取 a 節(jié)點(diǎn)內(nèi)包含的 img 節(jié)點(diǎn),如下所示:

>>> 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 節(jié)點(diǎn)里面的所有 img 節(jié)點(diǎn),結(jié)果為 5。

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

我們剛才使用了 response.selector.xpath() 方法對(duì)數(shù)據(jù)進(jìn)行了提取。Scrapy 提供了兩個(gè)實(shí)用的快捷方法,response.xpath() 和 response.css(),它們二者的功能完全等同于 response.selector.xpath() 和 response.selector.css()。方便起見,后面我們統(tǒng)一直接調(diào)用 response 的 xpath() 和 css() 方法進(jìn)行選擇。

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

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

我們可以像操作列表一樣操作這個(gè) SelectorList。

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

比如我們現(xiàn)在想提取出 a 節(jié)點(diǎn)元素,就可以利用 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() 方法,我們就可以把真實(shí)需要的內(nèi)容獲取下來。

我們還可以改寫 XPath 表達(dá)式,來選取節(jié)點(diǎn)的內(nèi)部文本和屬性,如下所示:

>>> 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() 就可以獲取節(jié)點(diǎn)的內(nèi)部文本,或者加一層 /@href 就可以獲取節(jié)點(diǎn)的 href 屬性。其中,@符號(hào)后面內(nèi)容就是要獲取的屬性名稱。

現(xiàn)在我們可以用一個(gè)規(guī)則把所有符合要求的節(jié)點(diǎn)都獲取下來,返回的類型是列表類型。

但是這里有一個(gè)問題:如果符合要求的節(jié)點(diǎn)只有一個(gè),那么返回的結(jié)果會(huì)是什么呢?我們?cè)儆靡粋€(gè)實(shí)例來感受一下,如下所示:

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

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

python>>> response.xpath('//a[@href="image1.html"]/text()').extract()[0]
'Name: My image 1 '
但是,這個(gè)寫法很明顯是有風(fēng)險(xiǎn)的。一旦 XPath 有問題,那么 extract() 后的結(jié)果可能是一個(gè)空列表。如果我們?cè)儆盟饕齺慝@取,
那不就會(huì)可能導(dǎo)致數(shù)組越界嗎?
所以,另外一個(gè)方法可以專門提取單個(gè)元素,它叫作 extract_first()。我們可以改寫上面的例子如下所示:
```python
>>> response.xpath('//a[@href="image1.html"]/text()').extract_first()
'Name: My image 1 '

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

另外我們也可以為 extract_first() 方法設(shè)置一個(gè)默認(rèn)值參數(shù),這樣當(dāng) XPath 規(guī)則提取不到內(nèi)容時(shí)會(huì)直接使用默認(rèn)值。例如將 XPath 改成一個(gè)不存在的規(guī)則,重新執(zhí)行代碼,如下所示:

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

這里,如果 XPath 匹配不到任何元素,調(diào)用 extract_first() 會(huì)返回空,也不會(huì)報(bào)錯(cuò)。

在第二行代碼中,我們還傳遞了一個(gè)參數(shù)當(dāng)作默認(rèn)值,如 Default Image。這樣如果 XPath 匹配不到結(jié)果的話,返回值會(huì)使用這個(gè)參數(shù)來代替,可以看到輸出正是如此。

現(xiàn)在為止,我們了解了 Scrapy 中的 XPath 的相關(guān)用法,包括嵌套查詢、提取內(nèi)容、提取單個(gè)內(nèi)容、獲取文本和屬性等。

4. CSS 選擇器

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

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

例如在上文我們選取了所有的 a 節(jié)點(diǎn),那么 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 <'>]

同樣,調(diào)用 extract() 方法就可以提取出節(jié)點(diǎn),如下所示:

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

接下來的兩個(gè)用法不太一樣。節(jié)點(diǎn)的內(nèi)部文本和屬性的獲取是這樣實(shí)現(xiàn)的,如下所示:

>>> 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() 的寫法。而其他庫(kù)如 Beautiful Soup 或 pyquery 都有單獨(dú)的方法。

另外,CSS 選擇器和 XPath 選擇器一樣可以嵌套選擇。我們可以先用 XPath 選擇器選中所有 a 節(jié)點(diǎn),再利用 CSS 選擇器選中 img 節(jié)點(diǎn),再用 XPath 選擇器獲取屬性。我們用一個(gè)實(shí)例來感受一下,如下所示:

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

我們成功獲取了所有 img 節(jié)點(diǎn)的 src 屬性。

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

5. 正則匹配

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

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

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

如果同時(shí)存在兩個(gè)分組,那么結(jié)果依然會(huì)被按序輸出,如下所示:

>>> 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() 方法可以選取列表的第一個(gè)元素,用法如下:

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

不論正則匹配了幾個(gè)分組,結(jié)果都會(huì)等于列表的第一個(gè)元素。

值得注意的是,response 對(duì)象不能直接調(diào)用 re() 和 re_first() 方法。如果想要對(duì)全文進(jìn)行正則匹配,可以先調(diào)用 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'

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

以上是關(guān)于Python3爬蟲中Selector的用法的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)-成都網(wǎng)站建設(shè)公司行業(yè)資訊頻道!

本文標(biāo)題:關(guān)于Python3爬蟲中Selector的用法-創(chuàng)新互聯(lián)
文章來源:http://muchs.cn/article48/dhehep.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供外貿(mào)網(wǎng)站建設(shè)網(wǎng)站導(dǎo)航、ChatGPT域名注冊(cè)、定制開發(fā)、網(wǎng)站策劃

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

成都網(wǎng)頁(yè)設(shè)計(jì)公司