lxml 的安裝
pip install lxml
Element 類(lèi)
- 導(dǎo)入模塊 from lxml import etree
- 添加tag名為root 的節(jié)點(diǎn)
root = etree.Element("root") - 打印tag名
print(root.tag) - 添加子節(jié)點(diǎn)
- root.append( etree.Element("child1") )
- child2 = etree.SubElement(root, "child2")
- tostring 節(jié)點(diǎn)字符化
print(etree.tostring(root, pretty_print=True))
Element 是一個(gè)列表误辑,最小單元是element
列表的長(zhǎng)度 print(len(root))
讀取列表的節(jié)點(diǎn)名 print(root[0].tag)
列表的索引 root.index(root[1])
-
列表的切片
- start = root[:1] 開(kāi)頭
- end = root[-1:] 結(jié)尾
判斷element否有子節(jié)點(diǎn)斩披,即子節(jié)點(diǎn)列表是否為空
print(etree.iselement(root))刪除子節(jié)點(diǎn)區(qū)別于列表
root[0] = root[-1]
root[0] 指向root[-1]的節(jié)點(diǎn)對(duì)象查邢,root[0]的節(jié)點(diǎn)對(duì)象刪除復(fù)制需要使用到copy模塊的深層復(fù)制
from copy import deepcopygetparent()查詢節(jié)點(diǎn)的根節(jié)點(diǎn)
root is root[0].getparent()getprevious() 前一個(gè)節(jié)點(diǎn)
root[0] is root[1].getprevious()getnext()后一個(gè)節(jié)點(diǎn)
root[1] is root[0].getnext()
element 的屬性是dict
etree.Element('root', interesting = 'totally')
etree.tostring(root)
b'<root interesting="totally"/>'
- element 屬性的設(shè)置
root.set('hello', 'huhu')
print(root.get('hello'))
huhu
- 打印element屬性的鍵值對(duì)
sorted(root.keys())
sorted 返回一個(gè)新列表倡勇,其中包含所有可迭代項(xiàng)川蒙,默認(rèn)按升序進(jìn)行迭代
for name, value in sorted(root.items()):
... print('%s = %r' % (name, value))
hello = 'Huhu'
interesting = 'totally'
- 使用attrib打印鍵值對(duì)列表
d = dict(root.attrib)
sorted(d.items())
[('hello', 'Guten Tag'), ('interesting', 'totally')]
element 構(gòu)成文本
>>> html = etree.Element("html")
>>> body = etree.SubElement(html, "body")
>>> body.text = "TEXT"
>>> etree.tostring(html)
b'<html><body>TEXT</body></html>'
root = etree.Element("root")
用層次結(jié)構(gòu)最底部的tag標(biāo)記封裝
>>> root.text = "TEXT"
>>> print(root.text)
TEXT
>>> etree.tostring(root)
b'<root>TEXT</root>'
<html><body>Hello
World</body></html>
標(biāo)簽被文本包圍,文檔樣式,使用tail屬性來(lái)支持br
如果希望不在文本顯示tail文本,tostring()函數(shù)接受關(guān)鍵字參數(shù)with_tail= False
如果你想讀的只有文字,即沒(méi)有任何中間變量霹期,你必須遞歸串聯(lián)所有文字和尾部 以正確的順序?qū)傩浴M瑯诱铮瑃ostring()函數(shù)來(lái)拯救历造,這次使用method關(guān)鍵字:
etree.tostring(html, method="text")
b'TEXTTAIL'
使用XPath查找文本
XPath允許您將單獨(dú)的文本塊提取到列表中
>>> print(html.xpath("string()")) # lxml.etree only!
>>> print(html.xpath("http://text()")) # lxml.etree only!
包裝在一個(gè)函數(shù)里面:
>>> build_text_list = etree.XPath("http://text()") # lxml.etree only!
>>> print(build_text_list(html))
['TEXT', 'TAIL']
可以通過(guò)其getparent()方法詢問(wèn)它的來(lái)源,就像使用Elements一樣:
>>> texts = build_text_list(html)
>>> print(texts[0])
TEXT
>>> parent = texts[0].getparent()
>>> print(parent.tag)
body
>>> print(texts[1])
TAIL
>>> print(texts[1].getparent().tag)
br
- 判斷文本內(nèi)容
>>> print(texts[0].is_text)
True
>>> print(texts[1].is_text)
False
>>> print(texts[1].is_tail)
True
tree迭代器
>>> root = etree.Element("root")
>>> etree.SubElement(root, "child").text = "Child 1"
>>> etree.SubElement(root, "child").text = "Child 2"
>>> etree.SubElement(root, "another").text = "Child 3"
>>> print(etree.tostring(root, pretty_print=True))
<root>
<child>Child 1</child>
<child>Child 2</child>
<another>Child 3</another>
</root>
>>> for element in root.iter():
... print("%s - %s" % (element.tag, element.text))
root - None
child - Child 1
child - Child 2
another - Child 3
- 對(duì)單個(gè)標(biāo)記感興趣,可以將其名稱(chēng)傳遞給 iter()以讓它過(guò)濾帕膜,還可以在迭代期間傳遞多個(gè)標(biāo)記以攔截多個(gè)標(biāo)記枣氧。
>>> for element in root.iter("child"):
... print("%s - %s" % (element.tag, element.text))
child - Child 1
child - Child 2
>>> for element in root.iter("another", "child"):
... print("%s - %s" % (element.tag, element.text))
child - Child 1
child - Child 2
another - Child
默認(rèn)情況下溢十,迭代會(huì)生成樹(shù)中的所有節(jié)點(diǎn)垮刹,包括ProcessingInstructions,Comments和Entity實(shí)例张弛。如果要確保僅返回Element對(duì)象荒典,可以將Element作為標(biāo)記參數(shù)傳遞
>>> for element in root.iter(tag=etree.Element):
... print("%s - %s" % (element.tag, element.text))
root - None
child - Child 1
child - Child 2
another - Child 3
序列化
序列化通常使用返回字符串的tostring()函數(shù),或者寫(xiě)入文件吞鸭,類(lèi)文件對(duì)象或URL(通過(guò)FTP PUT或HTTP POST)的ElementTree.write()方法寺董。兩個(gè)調(diào)用都接受相同的關(guān)鍵字參數(shù),如pretty_print刻剥,用于格式化輸出或編碼遮咖,以選擇除純ASCII以外的特定輸出編碼:
>>> root = etree.XML('<root><a><b/></a></root>')
>>> etree.tostring(root)
b'<root><a><b/></a></root>'
>>> print(etree.tostring(root, xml_declaration=True))
<?xml version='1.0' encoding='ASCII'?>
<root><a><b/></a></root>
>>> print(etree.tostring(root, encoding='iso-8859-1'))
<?xml version='1.0' encoding='iso-8859-1'?>
<root><a><b/></a></root>
>>> print(etree.tostring(root, pretty_print=True))
<root>
<a>
<b/>
</a>
</root>
通過(guò)傳遞method關(guān)鍵字來(lái)序列化為HTML或提取文本內(nèi)容:
XPath常用規(guī)則
nodename 選取此節(jié)點(diǎn)的所有子節(jié)點(diǎn)
/ 從當(dāng)前節(jié)點(diǎn)選取直接子節(jié)點(diǎn)
// 從當(dāng)前節(jié)點(diǎn)選取子孫節(jié)點(diǎn)
. 選取當(dāng)前節(jié)點(diǎn)
.. 選取當(dāng)前節(jié)點(diǎn)的父節(jié)點(diǎn)
@ 選取屬性
- 通配符,選擇所有元素節(jié)點(diǎn)與元素名
@* 選取所有屬性
[@attrib] 選取具有給定屬性的所有元素
[@attrib='value'] 選取給定屬性具有給定值的所有元素
[tag] 選取所有具有指定元素的直接子節(jié)點(diǎn)
[tag='text'] 選取所有具有指定元素并且文本內(nèi)容是text節(jié)點(diǎn)