标签?
" />
lxml 的 XMLPullParser 在解析非标准或结构不完整的内容时,若误用 HTML 解析逻辑(如未指定严格 XML 解析器),可能将文本片段错误地包裹为 标签——根本原因在于混合了 HTML 容错解析行为与 XHTML 文档的预期。
lxml 为何在解析 xhtml 时自动插入 `
` 标签?
当你使用 lxml 解析 XHTML 文件却意外得到大量孤立 <p></p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/xiazai/skill8961" title="html-to-pptx-converter"><img
src="https://img.php.cn/upload/skill/000/000/081/179232667384043.jpg" alt="html-to-pptx-converter" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/xiazai/skill8961" title="html-to-pptx-converter" class="overflowclass">html-to-pptx-converter</a>
<p class="overflowclass">使用 PptxGenJS 和 Python 解析,将结构化的 HTML/CSS 幻灯片内容转换为原生、可编辑的 PowerPoint(.pptx)演示文稿。</p>
</div>
<a rel="nofollow" href="/xiazai/skill8961" title="html-to-pptx-converter" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div> 标签(如 <p> T </p>
<p>></p>…),这通常并非 lxml 的“bug”,而是解析器类型误配或输入内容不符合 XML 语法规范所致。
关键原因有两点:
误用了 HTML 解析逻辑:
lxml 默认的etree.parse()或etree.fromstring()在检测到类似 HTML 的内容时,可能自动切换至HTMLParser(尤其当文档缺少<?xml ?>声明或 DOCTYPE 不严谨时)。HTML 解析器会主动修复“破损”结构——例如将连续文本按空白或符号切分,并用<p></p>包裹段落。而你的原始 XHTML 是合法 XML,理应由严格 XML 解析器处理。输入字符串本身存在 XML 语法错误:
如答案中指出,>(缺少分号)和<是非法实体引用,在 XML 中必须写作>和。当 lxml 的 XML 解析器遇到此类错误时,部分版本可能退化为容错模式,或触发底层 libxml2 的恢复策略,导致文本被错误分段并包装为块级元素(如 <code><p></p>)。
✅ 正确做法如下:
-
始终显式使用 XML 解析器:
from lxml import etree as et # ✅ 强制 XML 解析(禁用 HTML 自动检测) parser = et.XMLParser(recover=False, strip_cdata=False) tree = et.parse("input.xhtml", parser) root = tree.getroot() -
确保输入是合规的 UTF-8 编码 XML 字节串,且实体完整:
# ✅ 正确的 XHTML 片段(注意 > T > 85C : 10ms 85 => T > 30C : 100ms T ' # 使用 XMLPullParser 时也需绑定 XMLParser target = et.TreeBuilder() parser = et.XMLPullParser(target=target, recover=False) parser.feed(xml_bytes) parser.close() root = target.close() print(et.tostring(root, encoding="utf-8").decode()) # 输出: T > 85C : 10ms 85 => T > 30C : 100ms T
⚠️ 注意事项:
- 避免直接对未转义的 HTML 字符串调用
etree.fromstring()—— 它会默认启用 HTML 模式; - 若源文件为 XHTML,建议先用
xmllint --noout input.xhtml验证其有效性; - 在 DITA 转换流程中,推荐统一使用
etree.XMLParser(load_dtd=False, no_network=True)提升安全性和一致性; -
XMLPullParser的recover=False(默认)可防止静默纠错,便于早期暴露格式问题。
总结:lxml 插入 <p></p> 标签本质是解析器对“非标准输入”的适应性响应。坚持使用严格 XML 解析、校验实体合法性、避免混用 HTML/XHTML 解析上下文,即可彻底规避该现象。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










