在學(xué)習(xí)了python如何解析xml后,很多小伙伴可能會有這樣的感受——這學(xué)的是啥,怎么那么復(fù)雜?沒錯,內(nèi)置的python標(biāo)準(zhǔn)庫向來都是差強人意(實際上python內(nèi)置庫已經(jīng)做得很好了,只不過第三方的庫做得更好,相比之下就覺得內(nèi)置庫不香了)。xml的內(nèi)置標(biāo)準(zhǔn)庫其實并不是最好的xml解析工具,還有有一個解析xml更加強大的庫,它就是lxml。
介紹
lxml庫是一個python的xml解析庫,它支持HTML和xml的解析,并且支持Xpath解析方式。相比于原生的xml解析而言,lxml的接下效率相當(dāng)高。
Xpath是一門在xml文檔中查找信息的語言,雖然它最早是用來搜尋XML文檔的,但它也可以用于查找html語言。它的選擇功能十分強大,提供了非常簡單明了的路徑選擇表達(dá)式,另外他還提供了超過100個內(nèi)建函數(shù)用于數(shù)據(jù)處理。關(guān)于Xpath的學(xué)習(xí)和更多了解,可以前往Xpath教程。
安裝
使用pip進(jìn)行安裝即可,對應(yīng)的pip命令如下:
?pip install lxml
?
使用
一、讀取文本解析節(jié)點
from lxml import etree
text='''
<div>
<ul>
<li class="item-0"><a href="link1.html">第一個</a></li>
<li class="item-1"><a href="link2.html">second item</a></li>
<li class="item-0"><a href="link5.html">a屬性</a>
</ul>
</div>
'''
html=etree.HTML(text) #初始化生成一個XPath解析對象
result=etree.tostring(html,encoding='utf-8') #解析對象輸出代碼
print(type(html))
print(type(result))
print(result.decode('utf-8'))
etree會修復(fù)缺少的HTML文本節(jié)點,所以打印結(jié)果是有補全html標(biāo)簽的。
二、讀取HTML文件進(jìn)行解析
from lxml import etree
html=etree.parse('test.html',etree.HTMLParser()) #指定解析器HTMLParser會根據(jù)文件修復(fù)HTML文件中缺失的如聲明信息
result=etree.tostring(html) #解析成字節(jié)
#result=etree.tostringlist(html) #解析成列表
print(type(html))
print(type(result))
print(result)
三、獲取所有節(jié)點
from lxml import etree
html=etree.parse('test',etree.HTMLParser())
result=html.xpath('//*') #//代表獲取子孫節(jié)點,*代表獲取所有
print(type(html))
print(type(result))
print(result)
返回一個列表,每個元素都是Element類型,所有的節(jié)點都包含在其中。
如需獲取li節(jié)點,可以在//后面加上節(jié)點名稱,然后調(diào)用Xpath方法。
四、文本獲取
from lxml import etree
text='''
<div>
<ul>
<li class="item-0"><a href="link1.html">第一個</a></li>
<li class="item-1"><a href="link2.html">second item</a></li>
</ul>
</div>
'''
html=etree.HTML(text,etree.HTMLParser())
result=html.xpath('//li[@class="item-1"]/a/text()') #獲取a節(jié)點下的內(nèi)容
result1=html.xpath('//li[@class="item-1"]//text()') #獲取li下所有子孫節(jié)點的內(nèi)容
print(result)
print(result1)
通過Xpath的text()方法,我們可以獲取節(jié)點中的文本。
五、屬性獲取
通過@符號即可獲取節(jié)點的屬性,比如下面代碼的獲取a標(biāo)簽的href屬性:
result=html.xpath('//li/a/@href') #獲取a的href屬性
result=html.xpath('//li//@href') #獲取所有l(wèi)i子孫節(jié)點的href屬性
六、按序選擇
我們進(jìn)行選擇的時候有時候會匹配多個節(jié)點,但我們只需要其中的一個,這時候我們就可以通過引入索引的方法(中括號內(nèi)加索引值)獲取特定次序的節(jié)點:
from lxml import etree
text1='''
<div>
<ul>
<li class="aaa" name="item"><a href="link1.html">第一個</a></li>
<li class="aaa" name="item"><a href="link1.html">第二個</a></li>
<li class="aaa" name="item"><a href="link1.html">第三個</a></li>
<li class="aaa" name="item"><a href="link1.html">第四個</a></li>
</ul>
</div>
'''
html=etree.HTML(text1,etree.HTMLParser())
result=html.xpath('//li[contains(@class,"aaa")]/a/text()') #獲取所有l(wèi)i節(jié)點下a節(jié)點的內(nèi)容
result1=html.xpath('//li[1][contains(@class,"aaa")]/a/text()') #獲取第一個
result2=html.xpath('//li[last()][contains(@class,"aaa")]/a/text()') #獲取最后一個
result3=html.xpath('//li[position()>2 and position()<4][contains(@class,"aaa")]/a/text()') #獲取定位值大于3且小于4的節(jié)點(也就是獲取第三個)
result4=html.xpath('//li[last()-2][contains(@class,"aaa")]/a/text()') #獲取倒數(shù)第三個
print(result)
print(result1)
print(result2)
print(result3)
print(result4)
小結(jié)
對于lxml庫而言,上面的功能其實只是一小部分,但是卻是比較常用的部分。憑心而論,Xpath的定位方式雖然看起來很復(fù)雜,但實際使用上比DOM的各種getelement方法好用得多,而且現(xiàn)代瀏覽器很多都支持生成Xpath路徑,更加方便了我們的使用。
以上就是關(guān)于lxml庫的全部介紹,更多python學(xué)習(xí)內(nèi)容請關(guān)注菜鳥自學(xué)python編程。