【问题标题】:How to get a specific span tag from a HTML Node collection如何从 HTML 节点集合中获取特定的 span 标签
【发布时间】:2020-07-05 03:36:05
【问题描述】:

我正在尝试从 HTML 节点集合中获取 div 中的每个第二个 span 标签,但由于某种原因,我只是获得了第一个 span 标签。我怀疑是关于我的 XPath 表达式的问题,但我不确定。

Program.cs

static void Main(string[] args) {
    var doc = new HtmlDocument();
    doc.Load("test.html");
            
    var htmlNodes = doc.DocumentNode.SelectNodes("//body/div/div/div");
    foreach (var node in htmlNodes) {
        Console.WriteLine(node.ChildNodes[1].InnerText);
    }
}

HTML 文件

<doctype! html>

<html lang='pt-br'>
    <head>
        <title>Teste</title>
        <meta charset='utf-8'/>

        <!-- Bootstrap -->
        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css"
        integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
        <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
        <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
        <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js" integrity="sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI" crossorigin="anonymous"></script>
        
        <!-- Custom CSS -->
        <link rel="stylesheet" type="text/css" href="./styles.css"/>
    </head>

    <body>
        <div class="container-fluid">
            <h1 class="title">Relatório</h1>

            <div id="infoField" class="container">
                <div>
                    <span>Matricula: </span>
                    <span>1111</span> <!-- Supposed to be this span tag -->
                </div>

                <div>
                    <span>Nome: </span>
                    <span>any</span> <!-- Supposed to be this span tag -->
                </div>

                <div>
                    <span>Sobrenome: </span>
                    <span>any</span> <!-- Supposed to be this span tag -->
                </div>

                <div>
                    <span>Porto: </span>
                    <span>2</span> <!-- Supposed to be this span tag -->
                </div> 
            </div>
        </div>
    </body>
</html>

返回值

Matricula:
Nome:
Sobrenome:
Porto:

【问题讨论】:

  • 我有一种预感,在您的内部 &lt;div&gt; 和第一个 &lt;span&gt; 之间可能有一个文本节点,创建节点 0。这使节点 1 成为您的第一个 &lt;span&gt;。在这种情况下,两个&lt;span&gt; 标记之间可能还会有一个。如果我是对的,您的第二个 &lt;span&gt; 将是节点 3。
  • 所以,看看node.ChildNodes[3].InnerText 是否有你想要的文本,或者抛出一个IndexOutOfRangeException。如果确实如此,请告诉我,这样我就可以构建一个正式的答案。 ??????
  • 它使用索引 '3' 工作,感谢您的 cmets。但是我不太明白为什么span标签之间有一个文本节点或其他东西。
  • 我会在我的回答中解释。 ??????
  • 如果我的 cmets 帮助了您,请考虑接受我的回答作为您问题的答案。谢谢!

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


【解决方案1】:

我有一种预感,HtmlAgilityPack 正在读取您的内部 &lt;div&gt; 和第一个 &lt;span&gt; 之间的文本节点。

该文本节点将是节点 0,使节点 1 (node.ChildNodes[1]) 成为您的第一个 &lt;span&gt;

发生这种情况是因为一些(大多数?)HTML 解析器将任何不是标记的内容读取为文本,包括空格。在 HTML 中,&lt;div&gt;&lt;span&gt; 之间有空格。

唯一的方法是没有空格,因此没有文本节点,就是将标签相互写下来,如下所示:

<div><span>Matricula:</span><span>1111</span></div>

如果您在 &lt;div&gt;&lt;span&gt; 之间包含文本节点,并且在两个 &lt;span&gt; 标记之间包含文本节点,则您的第二个 &lt;span&gt; 将是节点 3。因此,此行可能会起作用:

Console.WriteLine(node.ChildNodes[3].InnerText);

但您可能不想考虑 HTML 中的文本节点和空间。你只需要&lt;span&gt; 标签!

刷新了我对 HtmlAgilityPack 的记忆,我认为这将为您提供更好的服务:

foreach (var node in htmlNodes) {
    Console.WriteLine(node.Elements("span")[1].InnerText);
}

参考:https://html-agility-pack.net/elements

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-02-23
    • 1970-01-01
    • 2021-04-19
    • 2019-09-03
    • 1970-01-01
    • 2021-10-14
    • 2021-07-26
    相关资源
    最近更新 更多