简介
本篇文章和上一篇文章主要介绍Element
对象的接口
字典接口
在 XML 或 HTML 中每一个标签都有属性, Element
类通过字典接口支持属性操作
创建带有属性的Element
对象
from lxml import etree
# 带属性的 Element
root = etree.Element("root", name="root", **{"class": "main"})
# 序列化为 XML 标签
root_s = etree.tostring(root).decode()
print(root_s)
打印结果
<root name="root" class="main"/>
注意class
是 Python 关键字, 因此无法使用class="main"
按名称传参
访问属性
# 访问已有属性
print("name:", root.get("name"))
# 没有相应属性时, 可指定缺省值
print("title:", root.get("title", "element"))
打印结果
name: root
title: element
与字典不同, 无法通过 root["name"]
访问和设置属性值, Element 的魔法方法 __getitem__
不支持字符串索引
设置属性
# 设置属性
root.set("id", "root-elem")
遍历属性
# 遍历键-值
for k, v in root.items():
# Python3.7 以上才支持 f-string
print(f"{k}: {v}")
打印结果
name: root
class: main
id: root-elem
除了 items()
, root 与字典一样还支持 keys()
和values()
获取属性字典
借助于property
类, Element
对象的attrib
属性可视为字典对象
# 将 Element 的 attrib 属性视为字典
print("root.attrib", root.attrib)
# 通过字符串索引修改和访问标签属性
root.attrib["id"] = "root-attrib"
print('root.attrib["id"]:', root.attrib["id"])
# 通过 attrib 修改后, Element 也相应被修改
root_s = etree.tostring(root).decode()
print("root:", root_s)
打印结果
root.attrib: {'name': 'root', 'class': 'main', 'id': 'root-elem'}
root.attrib["id"]: root-attrib
root: <root name="root" class="main" id="root-attrib"/>
对 Element 元素属性的修改会映射到 attrib 属性, 反之亦然
操作属性字典
root.attrib
比root
本身更接近字典
# 更新属性
root.attrib.update({"id": "root-update"})
# 仅遍历值
for v in root.attrib.values():
print("attribute value:", v)
打印结果
attribute value: root
attribute value: main
attribute value: root-update
添加文本内容
如果将Element
对象看做元素节点, 那么其包含的文本就可看做文本节点, 在 lxml 包中Element
对象可以添加文本内容
创建包含文本内容的Element
对象
from lxml import etree
root = etree.Element("root")
# 设置文本内容
root.text = "Text"
root_s = etree.tostring(root).decode()
print("root:", root_s)
打印结果
root: <root>Text</root>
由于包含文本内容, root 变为双标签
在 XML 文档中, 文本内容只能包含于双标签内, 而 HTML 则不同, 文本内容可位于不同的标签之间, 所以Element
对象新增了tail
属性, 可在Element 末尾新增文本内容
html = etree.Element("html")
body = etree.SubElement(html, "body")
body.text = "BODY"
span = etree.SubElement(body, "span")
span.text = "SPAN_1"
html_1 = etree.tostring(html, pretty_print=True).decode()
print(html_1)
# 在尾部新增内容
span.tail = "SPAN_2"
html_2 = etree.tostring(html, pretty_print=True).decode()
print(html_2)
打印结果
<html>
<body>BODY<span>SPAN_1</span></body>
</html>
<html>
<body>BODY<span>SPAN_1</span>SPAN_2</body>
</html>
在序列化 Element 对象时, 可以忽略末尾文本, 也可以仅输出文本内容
# 忽略末尾文本
html_3 = etree.tostring(html, with_tail=True, pretty_print=True).decode()
print(html_3)
# 仅文本内容
html_4 = etree.tostring(html, method='text').decode()
print(html_4)
打印结果
<html>
<body>BODY<span>SPAN_1</span>SPAN_2</body>
</html>
BODYSPAN_1SPAN_2