lxml 的安装
pip install lxml
Element 类
- 导入模块 from lxml import etree
- 添加tag名为root 的节点
root = etree.Element("root") - 打印tag名
print(root.tag) - 添加子节点
- root.append( etree.Element("child1") )
- child2 = etree.SubElement(root, "child2")
- tostring 节点字符化
print(etree.tostring(root, pretty_print=True))
Element 是一个列表,最小单元是element
列表的长度 print(len(root))
读取列表的节点名 print(root[0].tag)
列表的索引 root.index(root[1])
-
列表的切片
- start = root[:1] 开头
- end = root[-1:] 结尾
判断element否有子节点,即子节点列表是否为空
print(etree.iselement(root))删除子节点区别于列表
root[0] = root[-1]
root[0] 指向root[-1]的节点对象,root[0]的节点对象删除复制需要使用到copy模块的深层复制
from copy import deepcopygetparent()查询节点的根节点
root is root[0].getparent()getprevious() 前一个节点
root[0] is root[1].getprevious()getnext()后一个节点
root[1] is root[0].getnext()
element 的属性是dict
etree.Element('root', interesting = 'totally')
etree.tostring(root)
b' '
- element 属性的设置
root.set('hello', 'huhu')
print(root.get('hello'))
huhu
- 打印element属性的键值对
sorted(root.keys())
sorted 返回一个新列表,其中包含所有可迭代项,默认按升序进行迭代
for name, value in sorted(root.items()):
... print('%s = %r' % (name, value))
hello = 'Huhu'
interesting = 'totally'
- 使用attrib打印键值对列表
d = dict(root.attrib)
sorted(d.items())
[('hello', 'Guten Tag'), ('interesting', 'totally')]
element 构成文本
>>> html = etree.Element("html")
>>> body = etree.SubElement(html, "body")
>>> body.text = "TEXT"
>>> etree.tostring(html)
b'TEXT'
root = etree.Element("root")
用层次结构最底部的tag标记封装
>>> root.text = "TEXT"
>>> print(root.text)
TEXT
>>> etree.tostring(root)
b'TEXT '
HelloWorld
标签被文本包围,文档样式,使用tail属性来支持br
如果希望不在文本显示tail文本,tostring()函数接受关键字参数with_tail= False
如果你想读的只有文字,即没有任何中间变量,你必须递归串联所有文字和尾部 以正确的顺序属性。同样,tostring()函数来拯救,这次使用method关键字:
etree.tostring(html, method="text")
b'TEXTTAIL'
使用XPath查找文本
XPath允许您将单独的文本块提取到列表中
>>> print(html.xpath("string()")) # lxml.etree only!
>>> print(html.xpath("//text()")) # lxml.etree only!
包装在一个函数里面:
>>> build_text_list = etree.XPath("//text()") # lxml.etree only!
>>> print(build_text_list(html))
['TEXT', 'TAIL']
可以通过其getparent()方法询问它的来源,就像使用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
- 判断文本内容
>>> 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))
Child 1
Child 2
Child 3
>>> for element in root.iter():
... print("%s - %s" % (element.tag, element.text))
root - None
child - Child 1
child - Child 2
another - Child 3
- 对单个标记感兴趣,可以将其名称传递给 iter()以让它过滤,还可以在迭代期间传递多个标记以拦截多个标记。
>>> 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
默认情况下,迭代会生成树中的所有节点,包括ProcessingInstructions,Comments和Entity实例。如果要确保仅返回Element对象,可以将Element作为标记参数传递
>>> 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()函数,或者写入文件,类文件对象或URL(通过FTP PUT或HTTP POST)的ElementTree.write()方法。两个调用都接受相同的关键字参数,如pretty_print,用于格式化输出或编码,以选择除纯ASCII以外的特定输出编码:
>>> root = etree.XML(' ')
>>> etree.tostring(root)
b' '
>>> print(etree.tostring(root, xml_declaration=True))
>>> print(etree.tostring(root, encoding='iso-8859-1'))
>>> print(etree.tostring(root, pretty_print=True))
通过传递method关键字来序列化为HTML或提取文本内容:
XPath常用规则
nodename 选取此节点的所有子节点
/ 从当前节点选取直接子节点
// 从当前节点选取子孙节点
. 选取当前节点
.. 选取当前节点的父节点
@ 选取属性
- 通配符,选择所有元素节点与元素名
@* 选取所有属性
[@attrib] 选取具有给定属性的所有元素
[@attrib='value'] 选取给定属性具有给定值的所有元素
[tag] 选取所有具有指定元素的直接子节点
[tag='text'] 选取所有具有指定元素并且文本内容是text节点
https://lxml.de/tutorial.html