60

我想使用 HTML 敏捷包来解析来自复杂网页的表格,但我不知何故迷失在对象模型中。

我查看了链接示例,但没有以这种方式找到任何表格数据。我可以使用 XPath 来获取表格吗?在加载有关如何获取表格的数据后,我基本上迷失了。我以前在 Perl 中做过这个,有点笨拙,但是很有效。( HTML::TableParser)。

如果有人能阐明解析的正确对象顺序,我也很高兴。

4

5 回答 5

124

怎么样:使用HTML Agility Pack

HtmlDocument doc = new HtmlDocument();
doc.LoadHtml(@"<html><body><p><table id=""foo""><tr><th>hello</th></tr><tr><td>world</td></tr></table></body></html>");
foreach (HtmlNode table in doc.DocumentNode.SelectNodes("//table")) {
    Console.WriteLine("Found: " + table.Id);
    foreach (HtmlNode row in table.SelectNodes("tr")) {
        Console.WriteLine("row");
        foreach (HtmlNode cell in row.SelectNodes("th|td")) {
            Console.WriteLine("cell: " + cell.InnerText);
        }
    }
}

请注意,如果您愿意,可以使用 LINQ-to-Objects 使其更漂亮:

var query = from table in doc.DocumentNode.SelectNodes("//table").Cast<HtmlNode>()
            from row in table.SelectNodes("tr").Cast<HtmlNode>()
            from cell in row.SelectNodes("th|td").Cast<HtmlNode>()
            select new {Table = table.Id, CellText = cell.InnerText};

foreach(var cell in query) {
    Console.WriteLine("{0}: {1}", cell.Table, cell.CellText);
}
于 2009-03-17T20:13:52.963 回答
30

我发现获取特定元素的 XPath 的最简单方法是为 Firefox 安装 FireBug 扩展,转到站点/网页按 F12 调出 firebug;右键选择并右键单击页面上要查询的元素并选择“检查元素” Firebug 将在其 IDE 中选择该元素,然后右键单击 Firebug 中的元素并选择“复制 XPath”此功能将为您提供确切的 XPath查询您需要使用 HTML 敏捷库获取所需的元素。

于 2010-06-23T17:33:23.323 回答
3

我知道这是一个非常古老的问题,但这是我的解决方案,有助于可视化表格,以便您可以创建类结构。这也是使用 HTML Agility Pack

HtmlDocument doc = new HtmlDocument();
doc.LoadHtml(@"<html><body><p><table id=""foo""><tr><th>hello</th></tr><tr><td>world</td></tr></table></body></html>");
var table = doc.DocumentNode.SelectSingleNode("//table");
var tableRows = table.SelectNodes("tr");
var columns = tableRows[0].SelectNodes("th/text()");
for (int i = 1; i < tableRows.Count; i++)
{
    for (int e = 0; e < columns.Count; e++)
    {
        var value = tableRows[i].SelectSingleNode($"td[{e + 1}]");
        Console.Write(columns[e].InnerText + ":" + value.InnerText);
    }
Console.WriteLine();
}
于 2019-04-26T19:21:52.773 回答
1

就我而言,有一个表恰好是来自路由器的设备列表。如果您希望使用 TR/TH/TD(行、标题、数据)而不是上面提到的矩阵来读取表格,您可以执行以下操作:

    List<TableRow> deviceTable = (from table in document.DocumentNode.SelectNodes(XPathQueries.SELECT_TABLE)
                                       from row in table?.SelectNodes(HtmlBody.TR)
                                       let rows = row.SelectSingleNode(HtmlBody.TR)
                                       where row.FirstChild.OriginalName != null && row.FirstChild.OriginalName.Equals(HtmlBody.T_HEADER)
                                       select new TableRow
                                       {
                                           Header = row.SelectSingleNode(HtmlBody.T_HEADER)?.InnerText,
                                           Data = row.SelectSingleNode(HtmlBody.T_DATA)?.InnerText}).ToList();
                                       }  

TableRow 只是一个以 Header 和 Data 作为属性的简单对象。该方法处理空值和这种情况:

<tr>
    <td width="28%">&nbsp;</td>
</tr>

这是没有标题的行。带有常量的 HtmlBody 对象可能很容易推断出来,但我仍然为它道歉。我来自一个世界,如果你的代码中有“,它应该是常量或可本地化的。

于 2017-05-04T23:45:21.643 回答
-1

从上面的答案行:

HtmlDocument doc = new HtmlDocument();

这在 VS 2015 C# 中不起作用。你不能再构造一个HtmlDocument了。

另一个让事情更难使用的 MS“功能”。尝试HtmlAgilityPack.HtmlWeb查看此链接以获取一些示例代码。

于 2016-01-13T02:11:50.813 回答