XPath的问题

时间:2011-06-05 19:03:38

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

这是一个链接:

http://www.covers.com/pageLoader/pageLoader.aspx?page=/data/nba/results/2010-2011/boxscore819588.html

我正在使用HTML Agility Pack,我想从'赔率'专栏中提取188。当被问到路径时,我的编辑会给出/html/body/form/div/div[2]/div/table/tr/td[2]/div/table/tr[3]/td[7]。我尝试使用各种遗漏body或html的路径,但是当传递给.DocumentNode.SelectNodes()时,它们都没有返回任何结果。我也在开头尝试//(我认为,这是文档树的根)。是什么给了什么?

编辑:

代码:

        WebClient client = new WebClient();
        string html = client.DownloadString(url);
        HtmlDocument doc = new HtmlDocument();
        doc.LoadHtml(html);

        foreach(HtmlNode node in doc.DocumentNode.SelectNodes("/some/xpath/expression"))
        {
            Console.WriteLine("[" + node.InnerText + "]");
        }

3 个答案:

答案 0 :(得分:1)

试试这个:

/html/body/form/div/div[2]/div/table/*/tr/td[2]/div/table/*/tr[3]/td[7]

*捕获强制<tbody>元素,该元素是表的DOM表示的一部分,即使它没有在HTML中表示。

除此之外,通过ID,CSS类名或其他一些独特属性而不是层次结构和文档结构来选择它更加健壮:

//table[@class='data']//tr[3]/td[7]

答案 1 :(得分:1)

在抓取网站时,你不能安全地依赖工具给出的确切XPATH,因为它们过于严格,实际上大部分时间都没有抓到。最好的方法是查看HTML并确定更适应变化的内容。

以下是一段适用于您的示例的代码:

    HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
    doc.Load(your html);

    foreach (HtmlNode node in doc.DocumentNode.SelectNodes("//a[text()='MIA']/ancestor::tr/td[7]"))
    {
        Console.WriteLine(node.InnerText.Trim());
    }

输出188

它的工作方式是:

  • 选择内部文本设置为“MIA”的A元素
  • 找到此A元素的父TR元素
  • 到达此TR元​​素的第七个TD
  • 然后我们使用该TD元素的InnerText属性

答案 2 :(得分:0)

默认情况下,HtmlAgilityPack对表单标签的处理方式不同(因为表单标签可以重叠),所以你需要从xpath中删除表单标签,例如:/ html / body // div / div [2] / div / table / tr / TD [2] / DIV /表/ TR [3] / TD [7]

其他方法是强制HtmlAgilityPack将表单标记视为其他标记:

HtmlNode.ElementsFlags.Remove("form");