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

高效解析HTML数据的Delphi实现方案及HTMLP组件使用咨询

嗨,针对你的HTML解析需求,我来给你梳理几个更高效的方案,还有帮你调整HTMLP组件的代码:

一、更高效的解析思路与开源组件推荐

你当前逐行判断的方法虽然可行,但容错性低(比如HTML标签换行不规整就会失效),也不够高效。推荐几个Delphi生态里成熟的开源HTML解析组件:

  • HtmlViewer + HtmlParser:老牌组件,社区使用广泛,支持完整的DOM树遍历、属性提取,文档和示例相对丰富,能轻松处理复杂HTML结构。
  • TMS Web Core HTML解析类:如果你的项目偏Web相关,这套工具类的API设计直观,处理HTML节点和属性的逻辑非常顺畅。
  • NativeXML(HTML兼容模式):轻量且解析速度快,开启HTML兼容模式后,可以用类似XML的方式遍历HTML节点,适合追求性能的场景。

这些组件都是基于DOM树解析的,能直接定位到<tr>、<td>这类目标标签,不用自己手动处理字符串切割和边界判断,容错性和效率都比逐行判断高很多。

二、HTMLP组件代码调整方案

你当前的代码只遍历了body的直接子节点,没深入到<tr>内部的<td>层级。修改后的代码会先批量定位所有<tr>元素,再逐个提取每条记录的字段:

var 
  HtmlParser: THtmlParser;
  HtmlDoc: TDocument;
  body: TElement;
  trNodes: TNodeList;
  trNode, tdNode: TNode;
  trElement, tdElement: TElement;
  i, j: Integer;
  currentRecord: TStringList; // 暂存单条记录的所有字段
begin
  HtmlParser := THtmlParser.Create;
  currentRecord := TStringList.Create;
  try
    HtmlDoc := HtmlParser.parseString(memo1.Text);
    try
      body := GetDocBody(HtmlDoc);
      if Assigned(body) then
      begin
        // 批量获取所有<tr>元素,比手动遍历更高效
        trNodes := body.getElementsByTagName('tr');
        try
          for i := 0 to trNodes.length - 1 do
          begin
            trNode := trNodes.item(i);
            if trNode is TElement then
            begin
              trElement := trNode as TElement;
              currentRecord.Clear;
              // 遍历当前<tr>下的所有<td>子节点
              for j := 0 to trElement.childNodes.length - 1 do
              begin
                tdNode := trElement.childNodes.item(j);
                if tdNode is TElement then
                begin
                  tdElement := tdNode as TElement;
                  if tdElement.tagName = 'td' then
                  begin
                    // 提取data-th属性作为字段名,文本内容作为字段值
                    var fieldName := tdElement.GetAttribute('data-th');
                    var fieldValue := tdElement.textContent.Trim;
                    currentRecord.Add(Format('%s: %s', [fieldName, fieldValue]));
                  end;
                end;
              end;
              // 输出单条记录结果,也可以改成存入数组/数据库
              memo1.Lines.Add('--- 新记录分割线 ---');
              memo1.Lines.AddStrings(currentRecord);
            end;
          end;
        finally
          trNodes.Free;
        end;
      end;
    finally
      HtmlDoc.Free;
    end;
  finally
    HtmlParser.Free;
    currentRecord.Free;
  end;
end;

代码关键说明:

  1. 用getElementsByTagName批量定位:直接获取所有<tr>元素,避免手动遍历无关节点,提升效率。
  2. 逐层提取字段:针对每条<tr>,遍历内部的<td>,用data-th作为字段标识,textContent提取内容。
  3. 暂存单条记录:用TStringList临时存储一条记录的所有字段,方便后续扩展处理(比如写入数据库、转换成对象)。

如果你的实际HTML里<tr>嵌套在<table>标签内,只需要先定位到<table>元素,再在table内调用getElementsByTagName('tr')即可,逻辑完全通用。

三、额外小贴士
  • 可以加边界判断:比如检查<td>是否存在data-th属性、文本内容是否为空,避免出现异常或无效数据。
  • 优先用组件最新版本:新版本的HTMLP组件可能修复了DOM遍历的bug,API也会更稳定。

内容的提问来源于stack exchange,提问作者Peter Jones

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 15:14:10