You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Python 3.8的xml.etree模块解析HTML文件?

基于Python标准库xml.etree解析HTML的实现方案

问题根因

你遇到的undefined entity报错是因为默认xml.etree.ElementTree调用parse方法时使用XML解析器,仅预定义了<、>、&、'、"5个实体,无法识别HTML特有的实体(比如&nbsp;、&copy;等),同时XML解析器对HTML的松散语法(比如未闭合标签)容错性极低。

标准库实现方案

无需引入第三方lxml包,也不用切换到html包,你可以将标准库html.parser.HTMLParser和xml.etree.TreeBuilder结合,生成完全兼容xml.etreeAPI的节点树,具体实现代码如下:

import xml.etree.ElementTree as etree
from html.parser import HTMLParser
from html.entities import name2codepoint

class HTMLElementTreeParser(HTMLParser):
    def __init__(self):
        super().__init__()
        # 初始化ElementTree的树构建器
        self.tree_builder = etree.TreeBuilder()

    def handle_starttag(self, tag, attrs):
        # 处理标签开始,属性转成字典格式传入构建器
        self.tree_builder.start(tag, dict(attrs))

    def handle_endtag(self, tag):
        # 处理标签结束
        self.tree_builder.end(tag)

    def handle_data(self, text):
        # 处理标签内文本
        self.tree_builder.data(text)

    def handle_entityref(self, name):
        # 处理HTML实体,转成对应字符传入构建器,解决实体未定义报错
        if name in name2codepoint:
            self.tree_builder.data(chr(name2codepoint[name]))

    def get_root(self):
        # 解析完成后返回ElementTree根节点
        return self.tree_builder.close()

# 调用示例
if __name__ == "__main__":
    filepathname = "你的HTML文件路径"
    with open(filepathname, "r", encoding="utf-8") as f:
        html_content = f.read()
    parser = HTMLElementTreeParser()
    parser.feed(html_content)
    html_root = parser.get_root()

    # 后续可以正常使用xml.etree的所有API操作节点树,比如:
    # 遍历所有p标签
    for p_node in html_root.iter("p"):
        print(p_node.text)
    # 用xpath语法查找节点
    all_a_nodes = html_root.findall(".//a")

方案优势

  • 完全基于Python标准库实现,无需额外安装依赖,满足即开即用的需求
  • 生成的根节点是标准的Element对象,你之前熟悉的xml.etree所有遍历、查询方法都可以直接使用
  • 自动兼容所有HTML预定义实体,不会再抛出实体未定义的异常

内容的提问来源于stack exchange,提问作者Jonathan Sachs

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 04:36:05