xpath beautiful pyquery三種解析庫

樑十安發表於2019-08-05

這兩天看了一下python常用的三種解析庫,寫篇隨筆,整理一下思路。太菜了,若有錯誤的地方,歡迎大家隨時指正。。。。。。。(conme on.......)

爬取網頁資料一般會經過 獲取資訊->提取資訊->儲存資訊 這三個步驟。而解析庫的使用,則可以幫助我們快速的提取出我們需要的那被部分資訊,免去了寫複雜的正規表示式的麻煩。在使用解析庫的時候,個人理解也會有三個步驟 建立文件樹->搜尋文件樹->獲取屬性和文字 。

建立文件樹:就是把我們獲取到的網頁原始碼利用解析庫進行解析,只有這樣,後面才能使用這個解析庫的方法。

搜尋文件樹:就是在已經建立的文件樹裡面,利用標籤的屬性,搜尋出我們需要的那部分資訊,比如一個包含一部分網頁內容的div標籤,一個ul標籤等。

獲取索性和文字:在上一步的基礎上,進一步獲取到具體某個標籤的文字或屬性,比如一個a標籤的href屬性,title屬性,或它的文字。

首先,定義一個html的字串,用它來模擬已經獲取到的網頁原始碼

html = '''
<div id="container">
    <ul class="list">
         <li class="item-0">first item</li>
         <li class="item-1"><a href="link2.html">second item</a></li>
         <li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
         <li class="item-1 active"><a href="link4.html">fourth item</a></li>
         <li class="item-0"><a href="link5.html">fifth item</a></li>
     </ul>
     <ul class="list">
         <li class="item-0">first item</li>
         <li class="item-1"><a href="link2.html">second item</a></li>
         <li class="item-0 active"><a href="link3.html"><span class="bold">third item</span></a></li>
         <li class="item-1 active"><a href="link4.html">fourth item</a></li>
         <li class="item-0"><a href="link5.html">fifth item</a></li>
     </ul>
 </div>
'''
View Code

 

xpath解析庫:XPath,全稱XML Path Language,即XML路徑語言,它是一門在XML文件中查詢資訊的語言。它最初是用來搜尋XML文件的,但是它同樣適用於HTML文件的搜尋。

1.建立文件樹:在獲取到網頁原始碼後,只需要使用etree的HTML方法,就可以把複雜的html建立成 一棵文件樹了

from lxml import etree
xpath_tree = etree.HTML(html)

 

這裡首先匯入lxml庫的etree模組,然後宣告瞭一段HTML文字,呼叫HTML類進行初始化,這樣就成功構造了一個XPath解析物件。可以使用type檢視一下xpath_tree的型別,是這樣的 <class 'lxml.etree._Element'>

2.搜尋文件樹:先看一下xpath幾個常用的規則

(1)從整個文件樹中搜尋標籤:一般會用//開頭的XPath規則來選取所有符合要求的節點。這裡以前面的HTML文字為例。例如搜尋 ul 標籤

1 xpath_tree = etree.HTML(html)
2 result = xpath_tree.xpath('ul')
3 print(result)
4 print(type(result))
5 print(type(result[0]))

輸出結果如下:
[<Element ul at 0x2322b7e8608>, <Element ul at 0x2322b7e8648>]
<class 'list'>
<class 'lxml.etree._Element'>

 

上面第二行程式碼表示從整個文件樹中搜尋出所有的ul標籤,可以看到,返回結果是一個列表,裡面的每個元素都是lxml.etree._Element型別,當然,也可以對這個列表進行一個遍歷,然後對每個lxml.etree._Element物件進行操作。

(2)搜尋當前節點的子節點:比如,找到每一個ul標籤裡面的 li 標籤:

1 xpath_tree = etree.HTML(html)
2 result = xpath_tree.xpath('//ul')
3 for r in result:
4     li_list = r.xpath('./li')
5     print(li_list)

輸出結果如下:
[<Element li at 0x23433127748>, <Element li at 0x23433127788>, <Element li at 0x23433127a88>, <Element li at 0x23433127988>, <Element li at 0x23433127ac8>]
[<Element li at 0x23433127cc8>, <Element li at 0x23433127d08>, <Element li at 0x23433127d48>, <Element li at 0x23433127d88>, <Element li at 0x23433127dc8>]

 

第四行程式碼表示,選取當前的這個ul標籤,並獲取到它裡面的所有li標籤。

(3)根據屬性過濾:如果你需要根據標籤的屬性進行一個過濾,則可以這樣來做

1 xpath_tree = etree.HTML(html)
2 result = xpath_tree.xpath('//ul')
3 for r in result:
4     li_list = r.xpath('./li[@class="item-0"]')
5     print(li_list)

輸出結果如下:
[<Element li at 0x15c436695c8>, <Element li at 0x15c436698c8>]
[<Element li at 0x15c43669988>, <Element li at 0x15c436699c8>]

 

與之前的程式碼相比,旨在第四行的後面加了 [@class="item-0"] ,它表示找到當前ul標籤下所有class屬性值為item-0的li標籤,當然,也可以在整個文件樹搜尋某個標籤時,在標籤後面加上某個屬性,進行過濾,下面例子中有用到

(4)獲取文字:獲取具體某個標籤的文字內容

1 xpath_tree = etree.HTML(html)
2 result = xpath_tree.xpath('//ul[@class="list"]')
3 for r in result:
4     li_list = r.xpath('./li[@class="item-0"]')
5     for li in li_list:
6         print(li.xpath('./text()'))

輸出結果如下:
['first item']
[]
['first item']
[]

 

 

首先,在第二行的ul標籤後面加了屬性過濾,但因為兩個ul標籤的class屬性值都是list,所以結果沒加之前是一樣的。然後又加了一個for迴圈,用來獲取列表裡面每一個元素的文字,因為第二個li標籤裡面沒有文字內容,所以是空

(5)獲取屬性:獲取具體某個標籤的某個屬性內容

1 xpath_tree = etree.HTML(html)
2 result = xpath_tree.xpath('//ul[@class="list"]')
3 for r in result:
4     li_list = r.xpath('./li[@class="item-0"]')
5     for li in li_list:
6         print(li.xpath('./@class'))

輸出結果如下:
['item-0']
['item-0']
['item-0']
['item-0']

 

把第六行的text()方法換成@符號,並在後面加上想要的屬性,就獲取到了該屬性的屬性值。

這是xpath這個解析庫基本的使用方法,也有一些沒說到的地方,大家可以看一下靜謐大佬的文章。另外兩個解析庫,放在後面兩篇隨筆裡面

https://cuiqingcai.com/5545.html

*************************不積跬步,無以至千里。*************************

相關文章