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

C# foreach循环提取HTML表格写入DataGridView重复执行300+次问题

问题原因

你代码中内层查询使用的//tr是全局 XPath 语法,会从整个HTML文档的根节点开始匹配所有符合条件的<tr>节点,而非限定在当前遍历的<tbody>节点范围内。如果页面中存在N个<tbody>节点,你就会把全文档符合条件的<tr>重复插入N次,最终导致循环执行次数、新增数据行数量远超出预期。

修复方案

把内层XPath的//tr修改为.//tr,开头加.代表从当前节点的子节点开始检索,仅匹配当前<tbody>下的符合条件的行:

foreach (HtmlNode table in doc.DocumentNode.SelectNodes("//tbody"))
{
    // 加.限定只查询当前tbody下的tr
    foreach (HtmlNode row in table.SelectNodes(".//tr[(@style='height:16.4pt;') or (@style='height:15.7pt;')]"))
    {
        DataRow r = dt.NewRow();
        int i = 0;

        HtmlNodeCollection cells = row.SelectNodes("td");
        if (cells == null)
            continue;
        foreach (HtmlNode cell in cells)
        {
            r[i] = cell.InnerText;
            i++;
        }
        dt.Rows.Add(r);
    }
}

可选优化

如果你不需要对每个<tbody>做单独的逻辑处理,可以直接合并查询,减少嵌套层级:

// 直接查询全文档所有tbody下符合条件的tr,无需嵌套循环
var rows = doc.DocumentNode.SelectNodes("//tbody//tr[(@style='height:16.4pt;') or (@style='height:15.7pt;')]");
if (rows != null)
{
    foreach (HtmlNode row in rows)
    {
        DataRow r = dt.NewRow();
        int i = 0;
        HtmlNodeCollection cells = row.SelectNodes("td");
        if (cells == null)
            continue;
        foreach (HtmlNode cell in cells)
        {
            r[i] = cell.InnerText;
            i++;
        }
        dt.Rows.Add(r);
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 09:57:03