【问题标题】:How to select a table which contains certain keyword - c# - xpath - htmlagilitypack如何选择包含特定关键字的表 - c# - xpath - htmlagilitypack
【发布时间】:2012-01-27 18:17:25
【问题描述】:

我必须从没有任何类或 ID 的产品页面收集信息。我正在使用 htmlagilitypack 和 c# 4.0。

此产品页面源代码中有很多表格。价格表包含“KDV”字符串。所以我想得到这个包含表的“KDV”字符串。我该怎么做?

例如,下面的 xpath 将选择所有表

string srxPathOfCategory = "//table";
var selectedNodes = myDoc.DocumentNode.SelectNodes(srxPathOfCategory);

下面的代码选择表,但从最外面的表开始。我需要选择包含给定字符串的大多数内表

//table[contains(., ' KDV')]

c#、xpath、htmlagilitypack

【问题讨论】:

  • 不。我需要通过使用 htmlagilitypack 选择包含某些字符串的表。 htmlagilitypack 使用 xpath。
  • KDV = TAX 在我的语言中。所以它是价格的特定词:) 用作 45 TL + KDV。您无法相信他们使用的 html 结构有多糟糕,但他们是土耳其十大在线卖家。示例页面:pratikev.com/fractalv33/pratikEv/pages/…

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


【解决方案1】:

下面的代码选择表,但从最外面的表开始。一世 需要选择包含给定字符串的大多数内表

使用

//table
    [not(descendant::table) 
   and 
     .//text()[contains(., ' KDV')]
    ]

这会选择 XML 文档中没有 table 后代并且具有包含字符串 " KDV" 的文本节点后代的任何 table

一般来说,上面的表达式可以选择很多这样的table元素。

如果您只想选择其中一个(比如第一个),请使用这个 XPath 表达式——请注意括号

   (//table
        [not(descendant::table) 
       and 
         .//text()[contains(., ' KDV')]
        ]
    )[1]

记住:如果要选择文档中的第一个someName 元素,使用这个(如当前接受的答案)是错误的:

//someName[1]

这是 XPath 中第二常见的常见问题解答(仅次于如何在具有默认命名空间的 XML 文档中选择具有无前缀名称的元素)。

上面的表达式实际上选择了文档中的任何someName 元素,即其父元素的第一个子元素——试试看。

这种不直观行为的原因是因为 XPath [] 运算符的优先级(优先级)高于 // 伪运算符。

真正只选择第一个 someName 元素(在任何 XML 文档中)的正确表达式是:

(//someName)[1]

这里的括号用于显式覆盖默认的 XPath 运算符优先级。

【讨论】:

  • 我不得不说你是最好的 :) 所以这个 experession 是选择那张桌子。为了选择它的 TD 作为节点,我该怎么做?谢谢:pastebin.com/2hHxUHa8
  • @MonsterMMORPG:不客气。选择表的 td 只需在末尾添加 /td 即可:(//table [not(descendant::table) and .//text()[contains(., ' KDV')] ] )[1]/descendant::td[1] 选择此表的第一个 td
【解决方案2】:

可能有更有效的方法来做到这一点。反正, 这是我用于您的案例的全部代码,它适用于我:

        HtmlDocument doc = new HtmlDocument();
        string url = "http://www.pratikev.com/fractalv33/pratikEv/pages/viewProduct.jsp?pInstanceId=3138821";
        using (var response = (WebRequest.Create(url).GetResponse()))
        {
            doc.LoadHtml(new StreamReader(response.GetResponseStream()).ReadToEnd());
        }
        /*There is an bug in the xpath used here. Should have been 
          (//table/tr/td/font[contains(.,'KDV')])[1]/ancestor::table[2] 
          See Dimitre's answer for an explanation and an alternative / 
          more generic / (needless to say) better approach */
        string xpath = "//table/tr/td/font[contains(.,'KDV')][1]/ancestor::table[2]"; 
        HtmlNode table = doc.DocumentNode.SelectSingleNode(xpath);

【讨论】:

  • 这会选择表格,但它会从最外层开始选择。我需要选择最内表,这意味着包含表的 KDV 的第一个父级://table[contains(., 'KDV')]
  • 非常有趣。这两个代码的行为完全不同,因为在我的文档获取方法中,您的 xpath 返回 null :pastebin.com/S9fvyMcL
  • 奇怪,HtmlWeb 似乎造成了麻烦。哦,好吧,至少有一种方法可以让它工作:) 顺便说一句,我已经改变了 xpath。我认为它现在更有效率。
  • Pencho,这个答案有一些问题——我提供了一些见解。
  • @PenchoIlchev:没问题,当我们学到新东西时,我们都很幸运。
猜你喜欢
  • 2013-12-29
  • 1970-01-01
  • 2012-12-12
  • 1970-01-01
  • 2018-08-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-15
相关资源
最近更新 更多