【问题标题】:How to get the inner text for a single node using HtmlAgilityPack如何使用 HtmlAgilityPack 获取单个节点的内部文本
【发布时间】:2016-07-03 10:37:19
【问题描述】:

我的 HTML 如下所示:

        <div id="footer">
            <div id="footertext">
                <p> 
                    Copyright &copy; FUCHS Online Ltd, 2013. All Rights Reserved.
                </p>
             </div>
        </div>

我想从标记中获取此文本并将其作为字符串存储在我的 C# 代码中:“版权所有 © FUCHS Online Ltd, 2013. All Rights”。

这是我尝试过的:

   public string getvalue()
        {
            HtmlWeb web = new HtmlWeb();
            HtmlAgilityPack.HtmlDocument doc = web.Load("www.fuchsonline.com");
            var link = doc.DocumentNode.SelectNodes("//div[@id='footertext']");
            return link.ToString();
        }

这将返回“HtmlAgilityPack.HtmlNodeCollection”类型的对象。我如何获得这个文本值?

【问题讨论】:

  • 您要获取的文本不是属性——它是 DOM 中的文本节点。对于什么是 html 属性,Xml attributes.
  • @Veverke 用一条错误信息替换另一条错误信息可能不是一个好主意。 XML 不是 HTML,属性的规则不同(虽然相似)。
  • @Spender:html 不是 XML 的子集吗?我认为 XML 是所有“标记”数据结构格式的保护伞。我的意思是,如果所有这些标记语言都是“可扩展标记语言”,那么我想,所有这些都是从 xml 中“派生”出来的。似乎我与可扩展标记语言和 XML 的单方面关联是错误的(xml 是可扩展标记语言的缩写,而 XML 表示可扩展标记语言的实现实例)。
  • @Veverke。 XML 对属性的格式非常严格。 HTML 的规则要宽松得多。例如id='foo' 是有效的 HTML 属性,但在 XML 中无效。实际上,它们都是 SGML 的衍生产品。将 HTML 转换为 XML (XHTML) 的努力或多或少都失败了。
  • 明白了,你是对的。 SGML 是我的想法。感谢您的更正。

标签: c# html-agility-pack


【解决方案1】:

你需要一个节点的值。因此最好使用SelectSingleNode 方法。

HtmlWeb web = new HtmlWeb();
var doc = web.Load("http://www.fuchsonline.com");
var link = doc.DocumentNode.SelectSingleNode("//div[@id='footertext']/p");

string rawText = link.InnerText.Trim();
string decodedText = HttpUtility.HtmlDecode(text); // or WebUtility

return decodedText;

您可能还需要解码 html 实体 &amp;copy;

【讨论】:

  • 这确实应该是选择的答案。我们都错过了我们正在处理的 ID(尽管网站不会“阻止”开发人员在 dom 中使用重复的 ID,在这种情况下 selectsingle 不会得到想要的结果,但这些是边缘和不太可能的情况)。
【解决方案2】:

您可以这样做:

string html = @"
    <div id='footer'>
        <div id='footertext'>
            <p>
                Copyright &copy; FUCHS Online Ltd, 2013. All Rights Reserved.
            </p>
         </div>
    </div>";

//in my example I am not use HtmlWeb because I am working with the piece of html you provided. You will continue to you HtmlWeb and access the url...
HtmlDocument htmlDoc = new HtmlDocument();
htmlDoc.LoadHtml(html);

var texts = htmlDoc.DocumentNode.SelectNodes("//*[@id='footertext']").Select(n => n.InnerText.Trim());

foreach (var text in texts)
{
    Console.WriteLine(text);
}

输出:

【讨论】:

    【解决方案3】:
    public string getvalue()
    {
        HtmlWeb web = new HtmlWeb();
        HtmlAgilityPack.HtmlDocument doc =web.Load("www.fuchsonline.com");
        var link = doc.DocumentNode.SelectNodes("//div[@id='footertext']");
        return link.InnerText.ToString();
    }
    

    【讨论】:

    • 但它说htmlagility包不包含任何InnerText的定义
    • InnerText 仅在我们使用 SelectSingleNode() 方法时有效;
    • 如果你做 link.Document.Body.InnerText 会怎样
    猜你喜欢
    • 1970-01-01
    • 2023-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-02
    • 1970-01-01
    相关资源
    最近更新 更多