
XML解析库 lxml 教程(三)
发布日期:2021-05-06 19:34:30
浏览次数:24
分类:技术文章
本文共 2372 字,大约阅读时间需要 7 分钟。
简介
本篇文章主要介绍利用 XPath 提取文本节点或属性节点
XPath 回顾
对于 XPath 表达式, nodename 表示元素节点, @attribute 表示属性节点, text() 表示文本节点
除了节点, XPath 还提供了表示节点之间关系的符号, // 表示所有后代节点, / 表示直接子节点, 某一个节点的属性或文本内容均属于该节点的直接子节点
XPath 提取文本节点
与 text() 不同, 功能函数 string() 表示递归提取元素的文本内容, 并将它们连接成一个文本
创建 XML 示例
from lxml import etree# 创建 Elementshtml = etree.Element("html")body = etree.SubElement(html, "body")body.text = "BODY"span = etree.SubElement(body, "span")span.text = "SPAN_1"span.tail = "SPAN_2"html_s = etree.tostring(html, pretty_print=True).decode()print(html_s)
BODYSPAN_1SPAN_2
对比 text() 与 string()
# 使用 //text() 提取所有文本节点print(html.xpath("//text()"))# 使用 string() 提取所有文本节点print(html.xpath("string()"))
打印结果
['BODY', 'SPAN_1', 'SPAN_2']BODYSPAN_1SPAN_2
使用 html 调用 xpath 表示从 html 节点开始解析
# string() 中使用参数, 仅寻找 span 的文本节点print(html.xpath("string(//span)"))# 寻找所有 body 的文本节点print(html.xpath("//body/text()"))
打印结果
SPAN_1['BODY', 'SPAN_2']
string() 中可以使用参数限制递归查找的范围, 仅寻找 html 下所有 span 元素的文本节点
这里 span 元素末尾的文本内容 “SPAN_2” 被分给了 body 元素
如果要经常使用某一个 XPath 表达式, 可以将解析规则保存到变量
# 保存解析规则text_xpath = etree.XPath("//text()")# 解析 html 元素r = text_xpath(html)# 解析结果为列表print(r)# 查看解析后的文本类型r_0, r_1, r_2 = rprint(type(r_0))
打印结果
['BODY', 'SPAN_1', 'SPAN_2']
在 lxml 包中, XPath 解析的结果通常为列表
对于lxml.etree._ElementUnicodeResult
这个类无需感到陌生, 因为它直接继承了str
, 并新增了一些内容
# 直接继承字符串print("r_0 -> str:", isinstance(r_0, str))# 可获取父元素p = r_0.getparent()# 父元素标签名print(p.tag)print("r_0 is text:", r_0.is_text)print("r_2 is tail:", r_2.is_tail)
打印结果
r_0 -> str: Truebodyr_0 is text: Truer_2 is tail: True
XPath 提取属性节点
创建 HTML 示例
# 创建 Elementshtml = etree.Element("html")html.attrib["lang"] = "en"head = etree.SubElement(html, "head")meta = etree.SubElement(head, "meta")meta.set("charset", "UTF-8")etree.SubElement(head, "title").text = "Element_3"html_s = etree.tostring(html, pretty_print=True).decode()print(html_s)
Element_3
@*
表示匹配所有属性节点, 对比一下几种提取方法
# 绝对路径-1charset_1 = html.xpath("/html/@*")# 绝对路径-2head = html[0]charset_2 = head.xpath("/html/@*")# 相对路径charset_3 = html.xpath("./@*")print(charset_1)print(charset_2)print(charset_3)
三种方法的结果是一致的
['en']['en']['en']
提取属性节点和文本节点的结果类型是一样的, 都是继承了内置字符串并新增了一些方法
# 结果类型r = charset_1[0]print(type(r))# 父元素标签名print("parent's tag:", r.getparent().tag)# 是否为属性节点print("is_attribute:", r.is_attribute)# 属性名print("attrname:", r.attrname)
parent's tag: htmlis_attribute: Trueattrname: lang
发表评论
最新留言
路过,博主的博客真漂亮。。
[***.116.15.85]2025年04月05日 19时20分29秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
属性闭包求解算法——数据库考试复习
2019-03-04
中缀表达式转后缀表达式
2019-03-04
砍树问题(二分法)
2019-03-04
poj3260The Fewest Coins
2019-03-04
poj3617
2019-03-04
poj3069
2019-03-04
Day160.MySql优化的前置知识简介、Linux 安装 -MySql高级
2019-03-04
Java洛谷P5461 赦免战俘讲解
2019-03-04
关于 form表单 嵌套问题的解决方案
2019-03-04
论转发与重定向参数传递问题(jsp+servlet项目开发遇到的问题)
2019-03-04
Spring Boot怎么样处理静态资源(静态资源映射规则)_Web开发
2019-03-04
Android—— log.e(),log.d(),log.i()等的区别
2019-03-04