教育行業(yè)A股IPO第一股(股票代碼 003032)

全國(guó)咨詢(xún)/投訴熱線(xiàn):400-618-4000

lxml庫(kù)獲取子節(jié)點(diǎn)的方法匯總

更新時(shí)間:2021年06月21日14時(shí)56分 來(lái)源:傳智教育 瀏覽次數(shù):

好口碑IT培訓(xùn)

lxml是使用Python語(yǔ)言編寫(xiě)的庫(kù),主要用于解析和提取HTML或者XML格式的數(shù)據(jù),它不僅功能非常豐富,而且便于使用,可以利用XPath語(yǔ)法快速地定位特定的元素或節(jié)點(diǎn)。

lxml庫(kù)中大部分功能都位于lxml.etree模塊中,導(dǎo)入lxml.etree模塊的常見(jiàn)方式如下:

from lxml import etree

lxml庫(kù)的一些相關(guān)類(lèi)如下:
(1) Element類(lèi):可以理解為XML的節(jié)點(diǎn)。
(2) ElementTree類(lèi):可以理解為一個(gè)完整的XML文檔樹(shù)。
(3) ElementPath類(lèi):可以理解為XPath,用于搜索和定位節(jié)點(diǎn)。

1.Element 類(lèi)簡(jiǎn)介

Element類(lèi)是XML處理的核心類(lèi),可以直觀地理解為XML的節(jié)點(diǎn),大部分XML節(jié)點(diǎn)的處理都是圍繞著Element類(lèi)進(jìn)行的。要想創(chuàng)建一個(gè)節(jié)點(diǎn)對(duì)象,則可以通過(guò)構(gòu)造函數(shù)直接創(chuàng)建。例如:

root=etree.Element('root')

上述示例中,參數(shù)root表示節(jié)點(diǎn)的名稱(chēng)。 關(guān)于Element類(lèi)的相關(guān)操作,主要可分為三部分,分別是節(jié)點(diǎn)操作、節(jié)點(diǎn)屬性的操作、節(jié)點(diǎn)內(nèi)文本的操作,下面進(jìn)行逐一介紹。 (1)節(jié)點(diǎn)操作:若要獲取節(jié)點(diǎn)的名稱(chēng),可以通過(guò)tag屬性獲取。例如:

print(root.tag)
# 輸出結(jié)果如下
root


(2)節(jié)點(diǎn)屬性的操作:在創(chuàng)建節(jié)點(diǎn)的同時(shí),可以為節(jié)點(diǎn)增加屬性。節(jié)點(diǎn)中的屬性是以key-value的形式進(jìn)行存儲(chǔ)的,類(lèi)似于字典的存儲(chǔ)方式。通過(guò)構(gòu)造方法創(chuàng)建節(jié)點(diǎn)時(shí),可以在該方法中以參數(shù)的形式設(shè)置屬性,其中參數(shù)的名稱(chēng)表示屬性的名稱(chēng),參數(shù)的值表示為屬性的值。創(chuàng)建屬性的示例如下:

# 創(chuàng)建root節(jié)點(diǎn),并為其添加屬性
root=etree.Element('root', interesting='totally')
print(etree.tostring(root))
# 輸出結(jié)果如下
b'<root interesting=" totally" />'

此外,可以通過(guò)set()方法給已有的節(jié)點(diǎn)添加屬性。在調(diào)用該方法時(shí)可以傳入兩個(gè)參數(shù),其中第一個(gè)參數(shù)表示屬性的名稱(chēng),第二個(gè)參數(shù)表示屬性的值。例如:

# 再次給root節(jié)點(diǎn)添加age屬性
root.set('age', '30')
print(etree.tostring(root))
# 輸出結(jié)果如下
b'<root interesting="totally"age="30"/>'

在上述兩個(gè)示例中,都用到了tostring()函數(shù),該函數(shù)可以將元素序列化為XML樹(shù)的編碼字符串表示形式。

(3)節(jié)點(diǎn)內(nèi)文本的操作:一般情況下,可以通過(guò)text、tail屬性或者xpath()方法來(lái)訪(fǎng)問(wèn)文本內(nèi)容。通過(guò)text屬性訪(fǎng)問(wèn)節(jié)點(diǎn)的示例如下:

root=etree.Element('root')    # 創(chuàng)建root節(jié)點(diǎn)
root.text='Hello, World!'    # 給root節(jié)點(diǎn)添加文本
print(root.text)
print(etree.tostring(root))
# 輸出結(jié)果如下
Hello, world!
b'<root>Hello, World!</root>'

2.從字符串或文件中解析XML

為了能夠?qū)ML文件解析為樹(shù)結(jié)構(gòu),etree模塊中提供了如下3個(gè)函數(shù): (1 ) fromstring()函數(shù):從字符串中解析XML文檔或片段,返回根節(jié)點(diǎn)(或解析器目標(biāo)返回的結(jié)果)。 (2) XML()函數(shù):從字符串常量中解析XML文檔或片段,返回根節(jié)點(diǎn)(或解析器目標(biāo)返回的結(jié)果)。 (3) HTML()函數(shù):從字符串常量中解析HTML文檔或片段,返回根節(jié)點(diǎn)(或解析器目標(biāo)返回的結(jié)果)。 其中,XML()函數(shù)的行為類(lèi)似于fromstring0函數(shù),通常用于將XML字面量直接寫(xiě)入到源代碼中;HTML()函數(shù)可以自動(dòng)補(bǔ)全缺少的<html>和<body>標(biāo)簽。以上3個(gè)函數(shù)的示例如下:

xml_data='<root>data</root>'
# fromstring()方法
root_one=etree.fromstring(xml_data)
print(root_one.tag)
print(etree.tostring(root_one))
# XML方法,與fromstring方法基本一樣
root_two=etree.XML(xml_data)
print(root_two.tag)
print(etree.tostring(root_two))
# HTML()方法,如果沒(méi)有<html>和<body>標(biāo)簽,會(huì)自動(dòng)補(bǔ)上
root_three=etree.HTML(xml_data)
print(root_three.tag)
print(etree.tostring(root_three))
程序運(yùn)行結(jié)果為:
root
b'<root>data</root>'
root
b'<root>data</root>'
html
b'<html><body><root>data</root></body></html>'

除了上述3個(gè)函數(shù)之外,還可以調(diào)用parse()函數(shù)從XML文件中直接解析。在調(diào)用函數(shù)時(shí),如果沒(méi)有提供解析器,則使用默認(rèn)的解析器,函數(shù)會(huì)返回一個(gè)ElemenfTree 類(lèi)的對(duì)象。例如:

html=etree.parse('./hello.html')
result=etree.tostring(html, pretty_print=True)

ElementPath類(lèi)簡(jiǎn)介

ElementTree類(lèi)中附帶了一個(gè)類(lèi)似于XPath路徑語(yǔ)言的ElementPath類(lèi)。在ElementTree類(lèi)或Elements類(lèi)的API文檔中,提供了3個(gè)常用的方法,可以滿(mǎn)足大部分搜索和查詢(xún)需求,并且這3個(gè)方法的參數(shù)都是XPath語(yǔ)句。具體如下: (1) find()方法:返回匹配到的第一 個(gè)子元素。 (2) findall()方法:以列表的形式返回所有匹配的子元素。 (3) iterfind()方法:返回一個(gè)所有匹配元素的迭代器。 從文檔樹(shù)的根節(jié)點(diǎn)開(kāi)始,搜索符合要求的節(jié)點(diǎn)。例如:

# 從字符串中解析XML,返回根節(jié)點(diǎn)
root=etree.XML("<root><a x='123'>aText<b/><c/><b/></a></root>")
# 從根節(jié)點(diǎn)查找,返回匹配到的節(jié)點(diǎn)名稱(chēng)
print(root.find("a").tag)
# 從根節(jié)點(diǎn)開(kāi)始查找,返回匹配到的第一個(gè)節(jié)點(diǎn)的名稱(chēng)
print(root.findall(".//a[@x]")[0].tag)

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

a
A

還可以調(diào)用xpath()方法,使用元素作為上下文節(jié)點(diǎn)來(lái)評(píng)估XPath表達(dá)式。

lxml庫(kù)的基本使用

這里使用一個(gè)HTML示例文件作為素材來(lái)介紹lxml庫(kù)的基本應(yīng)用。該文件名為hello.html,內(nèi)容如下:

<!-- hello.html -->
<div>
    <ul>
        <li class="item-0"><a href="link1.html">first item</a></li>
        <li class="item-1"><a href="link2.html">second item</a></li> 
        <li class="item-inactive"><a href="link3.html"><span class="bold">third item</span></a></li>
        <li class="item-1"><a href="link4.html">fourth item</a></li>
        <li class="item-0"><a href="link5.html">fifth item</a></li>
    </ul>
</div>

按下來(lái),基于上述HTML文檔,使用lxml庫(kù)中的路徑表達(dá)式技巧,通過(guò)調(diào)用xpath()方法匹配選取的節(jié)點(diǎn),具體如下:

獲取任意位置的li節(jié)點(diǎn) 可以直接使用“//”從任意位置選取節(jié)點(diǎn)li,路徑表達(dá)式如下:

//li

通過(guò)lxml.etree模塊的xpath()方法,將hello.html文件中與該路徑表達(dá)式匹配到的列表返回,并打印輸出。具體代碼如下:

from lxml import etree
html=etree.parse('hello.html')
# 查找所有的li節(jié)點(diǎn)
result=html.xpath('//li')
# 打印<li>標(biāo)簽的元素集合
print(result)
# 打印<li>標(biāo)簽的個(gè)數(shù)
print(len(result))
# 打印返回結(jié)果的類(lèi)型
print(type(result))
# 打印第一個(gè)元素的類(lèi)型
print(type(result[0]))

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

[<Element li at 0x2cc9a48>, <Element li at 0x2cc99c8>, <Element li at 0x2cc9a88>, <Element li at 0x2cc9ac8>, <Element li at 0x2cc9b08>]
5
<class 'list'>
<class 'lxml.etree._Element'>

繼續(xù)獲取<li>標(biāo)簽的class屬性

在上個(gè)表達(dá)式的末尾,使用“/”向下選取節(jié)點(diǎn),并使用@選取class屬性節(jié)點(diǎn),表達(dá)式如下:

//1i/@class

獲取<li>標(biāo)簽的class屬性的示例代碼如下:

from lxml import etree
html=etree.parse('hello.html')
# 查找位于li標(biāo)簽的class屬性
result=html.xpath('//li/@class')
print(result)

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

['item-0', 'item-1', 'item-inactive', 'item-1', 'item-0']

獲取倒數(shù)第二個(gè)元素的內(nèi)容

從任意位置開(kāi)始選取倒數(shù)第二個(gè)<li>標(biāo)簽,再向下選取標(biāo)簽<a>。如果要獲取該標(biāo)簽中的 文本,可以使用如下表達(dá)式:

//li[last()-1]/a

或者

//li[last()-1]/a]/text()

不同的是,第個(gè)表達(dá)式需要訪(fǎng)問(wèn)text屬性,才能拿到標(biāo)簽的文本,而第二個(gè)表達(dá)式可直 接獲取文本。使用第一 個(gè)路徑表達(dá)式的示例如下:

from lxml import etree
html=etree.parse('hello.html')
# 獲取倒數(shù)第二個(gè)元素的內(nèi)容
result=html.xpath('//li[last()-1]/a')
print(result[0].text)

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

fourth item


0 分享到:
和我們?cè)诰€(xiàn)交談!