C# 使用 xpath 解析 html

本文关键字:html 解析 xpath 使用 | 更新日期: 2023-09-27 18:35:33

我正在尝试从HTML文档中解析出股票交易信息,其中包含一段简单的C#。 问题是我无法理解语法,tr class="LomakeTaustaVari" 被解析出来,但我如何获得没有 tr 类的第二位?

这是一段 HTML,它以不同的值重复它。

<tr class="LomakeTaustaVari">
    <td><div class="Ensimmainen">12:09</div></td>
    <td><div>MSI</div></td>
    <td><div>POH</div></td>
    <td><div>42</div></td>
    <td><div>64,50</div></td>
</tr>
<tr>
    <td><div class="Ensimmainen">12:09</div></td>
    <td><div>SRE</div></td>
    <td><div>POH</div></td>
    <td><div>156</div></td>
    <td><div>64,50</div></td>
</tr>

我的 C# 代码:

{
    HtmlAgilityPack.HtmlWeb web = new HtmlWeb();
    HtmlAgilityPack.HtmlDocument doc = web.Load ("https://www.op.fi/op/henkiloasiakkaat/saastot-ja-sijoitukset/kurssit-ja-markkinat/markkinat?sivu=alltrades.html&sym=KNEBV.HSE&from=10:00&to=19:00&id=32453");
    foreach (HtmlNode row in doc.DocumentNode.SelectNodes("//tr[@class='LomakeTaustaVari']")) 
    {
        Console.WriteLine(row.InnerText);     
    }
    Console.ReadKey();
}

C# 使用 xpath 解析 html

尝试使用下一个 xpath //tr[preceding-sibling::tr[@class='LomakeTaustaVari']]

var nodes = doc.DocumentNode.SelectNodes("//tr[preceding-sibling::tr[@class='LomakeTaustaVari']]");

它应选择具有类 LomakeTaustaVari 的前面节点tr的节点。

仅供参考:如果未找到节点,SelectNodes方法返回null

如果您设法获得对 <tr class="LomakeTaustaVari"> 元素的引用,我看到两种可能的解决方案。

您可以导航到父级,然后找到其所有<tr>子项:

lomakeTaustaVariElement.Parent.SelectNodes("tr"); // iterate over these if needed

您还可以使用 NextSibling 获取下一个<tr>

var trWithoutClass = lomakeTaustaVariElement.NextSibling;

请注意,使用第二种选择可能会遇到问题,因为 HTML 中存在的空格可能会被解释为一个不同的元素。

为了克服这个问题,您可以递归调用NextSibling,直到遇到tr元素。

这将遍历文档中的所有节点。您可能还需要更具体地说明起始节点,因此您只会选择您感兴趣的节点。

foreach (HtmlNode row in doc.DocumentNode.SelectNodes("//tr")) 
{
    Console.WriteLine(row.InnerText);     
}

可能我不明白什么,但是任何 tr 元素选择的最简单的 XPath 都应该完成这项工作:

doc.DocumentNode.SelectNodes("//tr")

否则,如果您只想选择具有特定属性的元素,则可能是:

doc.DocumentNode.SelectNodes("//tr[@class = 'someClass1' or @class = 'someClass2']")

如果您不喜欢加载页面并且想要使用现成的html字符串,例如来自 WebBrowser 元素,您可以使用以下示例:

var web = new HtmlAgilityPack.HtmlDocument();
web.LoadHtml(webBrowser1.Document.Body.Parent.OuterHtml);
var q = web.DocumentNode.SelectNodes("/html/body/div[2]/div/div[1]") //XPath /html/body/div[2]/div/div[1]