跳转到主内容
websoft网络软件专家 - 深耕网络技术,打造实用软件!

Python lxml解析不规范XML 如何处理未闭合的HTML/XML标签

应使用 lxml.html.fromstring() 替代 etree.fromstring(),因 HTML 解析器自动修复未闭合标签、补全结构并返回标准 Element 对象,支持 xpath/cssselect;而 etree 严格遵循 XML 规范,遇 等自闭合标签直接报 XMLSyntaxError。 lxml 默认拒绝解析未闭合标签,直接报
XMLSyntaxError
;想让它“将错就错”继续解析,得换用
html
模块而非
etree
,并明确告知它:这不是 XML,是 HTML。 为什么 etree.parse() 一遇到
就崩溃
etree.parse()
是为规范 XML 设计的,严格遵循 XML 规则:所有标签必须闭合、大小写敏感、必须有唯一根节点。像
或

这类 HTML 中合法但 XML 中非法的自闭合写法,在
etree
眼里就是语法错误。 常见错误现象:
XMLSyntaxError: Opening and ending tag mismatch
或
NoneType is not callable
(因解析失败返回
None
后调用方法) 使用场景:抓取网页源码、解析用户提交的富文本、处理老旧 CMS 导出内容 参数差异:
etree.parse()
读文件,
etree.fromstring()
读字符串;但两者都走 XML 解析器,同样拒收不规范标签 性能影响:HTML 解析器比 XML 解析器稍慢,但对千行级文档基本无感;兼容性反而更好——它本就为容忍而生 改用
html.fromstring()
是最简解法
lxml.html
模块底层调用的是 libxml2 的 HTML 解析器,会自动修复缺失闭合、补全
、标准化属性大小写,结果仍是标准
Element
对象,后续用
.xpath()
或
.cssselect()
完全不受影响。 使用HTML,CSS,JavaScript开发Android应用程序 英文文字pdf版附源文件 如果你了解HTML,CSS和JavaScript,您已经拥有所需的工具开发Android应用程序。本动手本书展示了如何使用这些开源web标准设计和建造,可适应任何Android设备的应用程序 - 无需使用Java。您将学习如何创建一个在您选择的平台的Andr​​oid友好的网络应用程序,然后转换与自由PhoneGap框架到一个原生的Andr​​oid应用程序。了解为什么设备无关的移动应用是未来的潮流,并开始构建应用程序,提供更 下载 立即学习 “ Python免费学习笔记(深入) ”; 实操建议:把所有
from lxml import etree
替成
from lxml import html
,再把
etree.fromstring(text)
换成
html.fromstring(text)
注意:不要混用——
html.fromstring()
返回的对象不能传给
etree.tostring()
直接用,但可传给
html.tostring()
如果原始内容是 XML 片段(比如只有

hello

),
html.fromstring()
仍能处理;而
etree.fromstring()
会因缺少根节点报错
from lxml import html doc = html.fromstring('

test

') print(doc.xpath('//img/@src')) # ['x'] —— 成功提取
需要保留原始标签大小写或禁用自动修复?别用
html
HTML 解析器默认会把
转成小写
,也会补全缺失的
和
。如果你在做 HTML 格式校验、diff 对比,或必须保持原样输出,这种“好心”反而坏事。 此时只能退回到
etree
,但需预处理:用正则或
html.parser
先做最小修复(如把
替成
),再交给
etree
更稳妥的做法是用
etree.XMLParser(recover=True)
,但它只对部分错误有效(比如缺失结束标签),对孤立标签如
仍可能失败 兼容性提示:libxml2 的
recover=True
在旧版本中行为不稳定,不同系统编译的 lxml 可能表现不一 真正麻烦的不是怎么修,而是你得先判断:这到底是 HTML 还是假扮成 XML 的 HTML?如果连文档声明都写着
,还硬用
etree
,那不是严谨,是给自己加戏。

相关文章