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

不使用外部库的Python HTML解析器开发方案咨询

自研HTML解析器+CRUD实现思路

你的现有方案可行性分析

1. 元组列表存储

可行,但仅适用于极简单的扁平HTML结构(比如只有单层无嵌套的标签)。元组的不可变性会导致更新/删除操作必须重新生成整个列表,完全无法表示HTML的嵌套层级关系,CRUD操作会非常繁琐,复杂场景下基本不可用。

2. 字符串拆分标签

可行,但需要处理大量边界情况,维护成本极高。比如要区分注释、自闭合标签、带引号/不带引号的属性、嵌套标签、转义字符等,稍有遗漏就会解析出错;而且拆分后的数据无结构化,CRUD需要手动定位字符串位置,极易引入bug,仅适合快速验证原型。

更优实现方案:自定义DOM类构建层级树

这是最适配HTML结构和CRUD需求的方案,核心是用自定义类封装HTML节点的所有属性,通过树结构表示嵌套关系,操作灵活且易维护。

核心DOM节点类示例

class DOMNode:
    def __init__(self, tag_name, attributes=None, text_content=''):
        self.tag_name = tag_name  # 标签名,如'div'、'p'
        self.attributes = attributes or {}  # 属性字典,如{'id': 'header', 'class': 'bold'}
        self.text_content = text_content  # 节点内的纯文本内容
        self.children = []  # 子节点列表,存储DOMNode实例

    def add_child(self, node):
        self.children.append(node)
    
    def remove_child(self, node):
        if node in self.children:
            self.children.remove(node)

解析器实现步骤

1. 文件读取与预处理

  • 读取HTML文件内容为字符串,先过滤掉注释(<!-- 注释内容 -->),可以用字符串替换或正则匹配移除。
  • 可选:合并连续的空白字符(比如多个换行、空格),但要注意保留文本节点内的必要空白。

2. 词法分析(分词)

遍历字符串,拆分出以下类型的token:

  • 开始标签:如<div class="box">,拆分出标签名div和属性{'class': 'box'}
  • 结束标签:如</div>,拆分出标签名div
  • 自闭合标签:如<img src="pic.jpg"/>,拆分出标签名img和属性{'src': 'pic.jpg'}
  • 文本节点:非标签范围内的纯文本内容

3. 语法分析(构建DOM树)

用栈结构处理嵌套关系:

  • 遇到开始标签:创建DOMNode实例,压入栈中,作为当前父节点
  • 遇到文本节点:将文本内容添加到栈顶节点的text_content(或作为独立文本节点,视需求而定)
  • 遇到自闭合标签:创建DOMNode实例,添加到栈顶节点的子节点列表
  • 遇到结束标签:弹出栈顶节点,将其添加到新的栈顶节点的子节点列表(栈为空时作为根节点)

CRUD操作实现要点

  • 创建(Create):新建DOMNode实例,调用目标父节点的add_child方法;或在子节点列表的指定位置插入。
  • 读取(Read):写递归遍历方法,根据标签名、属性值或层级路径查找节点;比如:
    def find_nodes_by_tag(root, tag_name):
        result = []
        if root.tag_name == tag_name:
            result.append(root)
        for child in root.children:
            result.extend(find_nodes_by_tag(child, tag_name))
        return result
    
  • 更新(Update):直接修改节点的tag_name、attributes或text_content;或替换子节点。
  • 删除(Delete):找到目标节点的父节点,调用remove_child方法;或清空节点的子节点列表。

关键边界处理

  • 自闭合标签:解析时判断标签末尾是否带有/,无需匹配结束标签
  • 属性解析:支持带双引号、单引号或无引号的属性值,比如class="box"、class='box'、class=box
  • 转义字符:维护一个转义映射表,将&lt;转成<、&gt;转成>等

内容的提问来源于stack exchange,提问作者Todor Popov

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 01:15:57