HTML Agility包 - 解析表

时间:2009-03-17 19:00:19

标签: c# html html-parsing html-agility-pack

我想使用HTML敏捷包来解析复杂网页中的表格,但我在对象模型中丢失了。

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

如果能够解释正确的解析对象顺序,我也很高兴。

5 个答案:

答案 0 :(得分:113)

如下: 使用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);
}

答案 1 :(得分:31)

我发现获取特定元素的XPath最简单的方法是为Firefox安装FireBug扩展程序,然后按F12的网站/网页调出firebug;右键选择并右键单击要查询的页面上的元素,然后选择“Inspect Element”Firebug将在其IDE中选择元素,然后右键单击Firebug中的Element并选择“Copy XPath”,此函数将为您提供精确的XPath查询您需要使用HTML Agility Library获取所需的元素。

答案 2 :(得分:1)

我知道这是一个非常老的问题,但这是我的解决方案,有助于可视化表,以便您可以创建类结构。这也使用了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();
}

答案 3 :(得分:0)

就我而言,有一个表恰好是路由器的设备列表。如果您希望使用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对象可能很容易推断出来,但我还是为它道歉。我来自这个世界,如果你有“在你的代码中,它应该是不变的或可本地化的。

答案 4 :(得分:-1)

从上面回答:

HtmlDocument doc = new HtmlDocument();

这在VS 2015 C#中不起作用。您无法再构建HtmlDocument

另一个MS&#34;功能&#34;这使得事情更难以使用。请尝试HtmlAgilityPack.HtmlWeb并查看this link以获取一些示例代码。