HtmlAgilityPack |错误检索表节点

时间:2012-01-23 20:03:02

标签: c# html xpath html-agility-pack nodes

您好我刚刚在这个网站上注册,因为我需要一些帮助。

我想从nyaa.eu网站获得结果。

基本上:

  • 表节点名为<table class="tlist">
  • 每个行节点都被称为<tr class="tlistrow">,有时它也是'信任tlistrow'等。
  • 我尝试检索的节点是:<td class="tlistname"> <td class="tlistsize"> <td class="tlistsn"> and <td class="tlistln">

首先,我正在检索一个包含有关种子的所有信息的表格:

HtmlNode hnTable = doc.DocumentNode.SelectSingleNode("//table[@class='tlist']");

所以,接下来要检索其class属性中包含'tlistrow'的所有行:

HtmlNodeCollection hncRows = hnTable.SelectNodes("//tr[contains(@class,'tlistrow')]");

最后问题是,当我读取每个节点时,它始终是同一个节点:

foreach (HtmlNode row in hncRows)
{
    foreach (HtmlNode child in row.ChildNodes)
    {
        if (child.SelectSingleNode("//td[@class='tlistname']") != null)
        {
            MessageBox.Show("Something found!\n\n" + child.SelectSingleNode("//td[@class='tlistname']").InnerText);
            break;
        }
    }
}

消息框中显示的文本始终相同,看起来只是多次选择一个节点。

我如何解决这个问题,或者如果我做错了什么,请纠正我。

2 个答案:

答案 0 :(得分:1)

    foreach (HtmlNode child in row.ChildNodes)
    {
        if (child.SelectSingleNode("//td[@class='tlistname']") != null)
        {
            MessageBox.Show("Something found!\n\n" + child.SelectSingleNode("//td[@class='tlistname']").InnerText);
            break;
        }
    }

您需要了解 相对 XPath表达式与 绝对 XPath表达式之间的区别

相对XPath表达式被评估为(作为初始上下文节点)XML文档中的特定节点。

针对整个XML文档评估绝对XPath表达式(将文档节点作为初始上下文节点)。

任何以字符/开头的XPath表达式都是绝对的XPath表达式。

根据提供的代码,您希望使用具有初始上下文节点的相对XPath表达式,该变量包含在名为child的变量中。

问题在于你正在使用的表达式:

//td[@class='tlistname'] 

/开头,因此是绝对的XPath表达式。

传递给SelectSingleNode()方法的方法总是选择整个XML文档中的第一个td元素,该元素具有字符串值为class的{​​{1}}属性

解决方案:使用相对XPath表达式,例如:

"tlistname."

答案 1 :(得分:0)

表达式中的// XPath将在文档中的任何位置查找匹配项。当你不需要时删除它。

所以,试试类似:

HtmlNode hnTable = doc.DocumentNode.SelectSingleNode("//table[@class='tlist']"); 
HtmlNodeCollection hncRows = hnTable.SelectNodes("/tr[contains(@class,'tlistrow')]");
foreach (HtmlNode row in hncRows)
{
    foreach (HtmlNode child in row.ChildNodes)
    {
        if (child.SelectSingleNode("/td[@class='tlistname']") != null)
        {
            MessageBox.Show("Something found!\n\n" + child.SelectSingleNode("/td[@class='tlistname']").InnerText);
            break;
        }
    }
}