使用Html Agility Pack获取特定表

时间:2014-09-26 18:09:25

标签: c# xpath html-agility-pack

我无法使用HTML Agility Pack获取某些特定的表格。我也无法更改实际的HTML,所以我不能使用其他ID或类或任何东西。

有人可以告诉我如何访问以下各个表吗?

<table class="newTable">
      //table 1 contents
    <table border="0" cellpadding="3" cellspacing="2" width="100%">
         //table 1 - A contents
    </table>
</table>
<table border="0" cellpadding="0" cellspacing="0" class="newTable">
     //table 2 contents
    <table width="100%" border="0" cellspacing="2" cellpadding="0">
        //table 2 - A contents
    </table>
    <table width="100%" border="0" cellspacing="2" cellpadding="0">
       //table 2 - B contents
    </table>
    <table width="100%" cellspacing="2" cellpadding="0">
       //table 2 - C contents
    </table>
</table>
<table>
     //table 3 contents
</table>

现在,如果我打电话给以下

HtmlNode table = doc.DocumentNode.SelectSingleNode("//table");
foreach (var cell in table.SelectNodes("//tr/td"))
{
     string someVariable = cell.InnerText
}

我会经历一切。我希望能够以不同方式访问表以关联我存储数据的位置。

我试过看

之类的东西

doc.DocumentNode.SelectNodes("//table[1]");

但是使用索引似乎不起作用,当我尝试用它指定一个表时,它仍会读入所有表或没有。

同样适用于此,它要么根本不起作用,要么得到一切。

foreach (var cell in table.SelectNodes("//table").Skip(some_number))
{
     string someVariable = cell.InnerText
}

我正在使用HTML Agility Pack 1.4.9的NuGet包

修改

我试图获得表1 - A的内容。两者都给出null或endcodingfound异常。

HtmlNode table = doc.DocumentNode.SelectSingleNode("//table/tr/td/table[1]");

HtmlNode table = doc.DocumentNode.SelectSingleNode("//table[1]/tr/td/table[1]");

1 个答案:

答案 0 :(得分:6)

错误是在第二次调用时,“// tr / td”将返回到根元素。您的索引器是问题第一部分的正确解决方案,第二部分可以通过指定您想要从您所在位置导航来修复:

HtmlNode table = doc.DocumentNode.SelectSingleNode("//table[1]");
foreach (var cell in table.SelectNodes(".//tr/td")) // **notice the .**
{
     string someVariable = cell.InnerText
}

不确定还有什么,但是extending your test table to this code,以下内容仅适用于我的测试。这可能意味着你需要分享更多的背景。

这是我用于测试的文件:

<!DOCTYPE html>

<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8" />
    <title></title>
</head>
<body>
    <table class="newTable">
        <tr>
            <td>
                <table border="0" cellpadding="3" cellspacing="2" width="100%">
                    <tr><td>
                        //table 1 - A contents
                    </td></tr>
                </table>
            </td>
        </tr>

    </table>
    <table border="0" cellpadding="0" cellspacing="0" class="newTable">
        <tr>
            <td>
                //table 2 contents
                <table width="100%" border="0" cellspacing="2" cellpadding="0">
                    <tr>
                        <td>
                            //table 2 - A contents
                        </td>
                    </tr>
                </table>
                <table width="100%" border="0" cellspacing="2" cellpadding="0">
                    <tr>
                        <td>
                            //table 2 - B contents
                        </td>
                    </tr>
                </table>
                <table width="100%" cellspacing="2" cellpadding="0">
                    <tr>
                        <td>
                            //table 2 - C contents
                        </td>
                    </tr>
                </table>
            </td>
        </tr>
    </table>
    <table>
        <tr>
            <td>
                //table 3 contents
            </td>
        </tr>
    </table>
</body>
</html>

这是用于提取您所追求的值的代码:

HtmlDocument doc = new HtmlDocument();
doc.LoadHtml(text);

var node1A = doc.DocumentNode.SelectSingleNode("//table[1]//table[1]");
string content1A = node1A.InnerText;
Console.WriteLine(content1A);

var node2C = doc.DocumentNode.SelectSingleNode("//table[2]//table[3]");
string content2C = node2C.InnerText;
Console.WriteLine(content2C);

节目:

enter image description here

更新

好的,我拿了你的实际HTML,我也得到了一个N​​ullReference。一定有一些东西会让Agility Pack大为混乱,不知道为什么。使用Linq API的一些实验似乎有用,我希望它可以替代你:

var table = doc.DocumentNode.DescendantsAndSelf("table").Skip(1).First().Descendants("table").First();
var tds   = table.Descendants("td");