這兩天看了一下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> '''
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
*************************不積跬步,無以至千里。*************************