如何使用HtmlAgilityPack精确解析HTML文档中的指定表格

来源:Vuejs社区作者:香港程序员头衔:程序员
导读:本期聚焦于小伙伴创作的《如何使用HtmlAgilityPack精确解析HTML文档中的指定表格》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《如何使用HtmlAgilityPack精确解析HTML文档中的指定表格》有用,将其分享出去将是对创作者最好的鼓励。

在.NET开发中处理HTML文档解析任务时,HtmlAgilityPack是常用的轻量级解析工具,它不需要文档完全符合XML规范,能够适配大多数实际场景下的HTML结构,尤其适合提取文档中的表格数据。

如何使用HtmlAgilityPack精确解析HTML文档中的指定表格

环境准备与基础配置

首先需要在项目中引入HtmlAgilityPack库,若使用NuGet包管理器,可以直接搜索安装HtmlAgilityPack包,安装完成后在代码文件顶部添加对应的命名空间引用。

using HtmlAgilityPack;
using System;
using System.Collections.Generic;

namespace HtmlTableParseDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            // 后续解析逻辑将在此处编写
            Console.WriteLine("HtmlAgilityPack表格解析示例");
        }
    }
}

定位目标表格的常用方法

要精确解析指定表格,首先需要准确定位到目标表格节点,HtmlAgilityPack提供了多种定位方式,开发者可以根据实际HTML结构选择最合适的方法。

通过表格属性定位

如果目标表格带有唯一的id、class或者其他自定义属性,可以直接通过XPath表达式定位。例如目标表格的id为targetTable,定位代码如下:

// 加载HTML文档,这里以加载本地字符串为例,也可以加载本地文件或网络地址
string htmlContent = "<html><body><table id='targetTable'><tr><td>测试数据</td></tr></table></body></html>";
HtmlDocument htmlDoc = new HtmlDocument();
htmlDoc.LoadHtml(htmlContent);

// 通过id定位表格节点
HtmlNode targetTable = htmlDoc.DocumentNode.SelectSingleNode("//table[@id='targetTable']");
if (targetTable != null)
{
    Console.WriteLine("成功定位到目标表格");
}
else
{
    Console.WriteLine("未找到目标表格");
}

通过表格位置定位

如果表格没有唯一属性,也可以通过其在文档中的顺序定位,比如获取页面中第二个表格:

// 获取所有table节点,取索引为1的第二个表格(索引从0开始)
HtmlNodeCollection allTables = htmlDoc.DocumentNode.SelectNodes("//table");
if (allTables != null && allTables.Count > 1)
{
    HtmlNode targetTable = allTables[1];
    Console.WriteLine("通过位置定位到第二个表格");
}

通过表格内容特征定位

如果表格有固定的表头内容,也可以通过表头文本匹配定位,例如表头包含“用户姓名”的表格:

// 查找包含表头文本为用户姓名的表格
HtmlNode targetTable = null;
HtmlNodeCollection tables = htmlDoc.DocumentNode.SelectNodes("//table");
if (tables != null)
{
    foreach (HtmlNode table in tables)
    {
        // 检查表格内是否存在包含用户姓名的th或td
        HtmlNode headerCell = table.SelectSingleNode(".//th[contains(text(),'用户姓名')]");
        if (headerCell != null)
        {
            targetTable = table;
            break;
        }
    }
}
if (targetTable != null)
{
    Console.WriteLine("通过内容特征定位到目标表格");
}

提取表格行列数据

定位到目标表格后,就可以按照表格结构逐行提取数据,通常表格的行用<tr>标签表示,表头用<th>标签,单元格用<td>标签。

提取表头数据

先提取表格的第一行作为表头,获取所有<th>或第一个<tr>下的<td>内容:

List<string> headers = new List<string>();
// 获取表格的第一行
HtmlNode firstRow = targetTable.SelectSingleNode(".//tr[1]");
if (firstRow != null)
{
    // 优先获取th标签,没有则获取td标签
    HtmlNodeCollection headerCells = firstRow.SelectNodes(".//th");
    if (headerCells == null)
    {
        headerCells = firstRow.SelectNodes(".//td");
    }
    if (headerCells != null)
    {
        foreach (HtmlNode cell in headerCells)
        {
            // 去除空白字符后添加到表头列表
            headers.Add(cell.InnerText.Trim());
        }
    }
}
Console.WriteLine("表头内容:" + string.Join(",", headers));

提取表格主体数据

提取完表头后,遍历剩余的行,获取每一行的单元格内容,整理成结构化的数据:

List<List<string>> tableData = new List<List<string>>();
// 获取表格所有行,跳过第一行表头
HtmlNodeCollection rows = targetTable.SelectNodes(".//tr");
if (rows != null)
{
    for (int i = 1; i < rows.Count; i++)
    {
        HtmlNode row = rows[i];
        List<string> rowData = new List<string>();
        HtmlNodeCollection cells = row.SelectNodes(".//td");
        if (cells != null)
        {
            foreach (HtmlNode cell in cells)
            {
                rowData.Add(cell.InnerText.Trim());
            }
        }
        tableData.Add(rowData);
    }
}
// 输出提取到的表格数据
Console.WriteLine("表格主体数据:");
foreach (List<string> row in tableData)
{
    Console.WriteLine(string.Join("|", row));
}

常见异常处理与注意事项

在实际解析过程中,可能会遇到一些特殊情况,需要提前做好处理:

  • 如果HTML文档结构不规范,部分<tr>或<td>标签缺失,需要在提取时做空值判断,避免索引越界。
  • 表格内如果包含嵌套表格,上述直接提取<td>的逻辑会把嵌套表格的内容也提取出来,此时可以通过判断<td>的直接子节点过滤,或者调整XPath表达式仅匹配当前层级的单元格。
  • 如果单元格内有换行、空格等冗余字符,使用Trim()方法清理后再存储,保证数据整洁。
  • 加载外部HTML时,注意处理编码问题,若文档编码不是UTF-8,需要在加载时指定正确的编码格式。

完整示例演示

以下是一个完整的示例,模拟解析一个包含id的表格,输出表头和所有行数据:

using HtmlAgilityPack;
using System;
using System.Collections.Generic;

namespace HtmlTableParseDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            // 模拟待解析的HTML内容,包含一个id为userTable的表格
            string htmlContent = @"<html>
<body>
<table id='userTable'>
    <tr>
        <th>用户ID</th>
        <th>用户姓名</th>
        <th>用户年龄</th>
    </tr>
    <tr>
        <td>1001</td>
        <td>张三</td>
        <td>25</td>
    </tr>
    <tr>
        <td>1002</td>
        <td>李四</td>
        <td>28</td>
    </tr>
</table>
</body>
</html>";

            HtmlDocument htmlDoc = new HtmlDocument();
            htmlDoc.LoadHtml(htmlContent);

            // 定位id为userTable的表格
            HtmlNode targetTable = htmlDoc.DocumentNode.SelectSingleNode("//table[@id='userTable']");
            if (targetTable == null)
            {
                Console.WriteLine("未找到目标表格");
                return;
            }

            // 提取表头
            List<string> headers = new List<string>();
            HtmlNode firstRow = targetTable.SelectSingleNode(".//tr[1]");
            if (firstRow != null)
            {
                HtmlNodeCollection headerCells = firstRow.SelectNodes(".//th");
                if (headerCells != null)
                {
                    foreach (HtmlNode cell in headerCells)
                    {
                        headers.Add(cell.InnerText.Trim());
                    }
                }
            }
            Console.WriteLine("表头:" + string.Join(", ", headers));

            // 提取表格数据
            List<List<string>> tableData = new List<List<string>>();
            HtmlNodeCollection rows = targetTable.SelectNodes(".//tr");
            if (rows != null)
            {
                for (int i = 1; i < rows.Count; i++)
                {
                    HtmlNode row = rows[i];
                    List<string> rowData = new List<string>();
                    HtmlNodeCollection cells = row.SelectNodes(".//td");
                    if (cells != null)
                    {
                        foreach (HtmlNode cell in cells)
                        {
                            rowData.Add(cell.InnerText.Trim());
                        }
                    }
                    tableData.Add(rowData);
                }
            }

            // 输出数据
            Console.WriteLine("表格数据:");
            foreach (List<string> row in tableData)
            {
                Console.WriteLine(string.Join(" | ", row));
            }
        }
    }
}

运行上述代码后,会先输出表头内容,再逐行输出表格中的数据,实现精确解析指定表格的需求。开发者可以根据实际HTML文档的结构,调整定位表达式和数据提取逻辑,适配不同的表格解析场景。

HtmlAgilityPackHTML解析表格提取Csharp修改时间:2026-06-14 13:21:34

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。