【问题标题】:How to parse text from anonymous block in AngleSharp?如何在 AngleSharp 中解析匿名块中的文本?
【发布时间】:2017-03-11 14:11:37
【问题描述】:

我正在使用 AngleSharp 解析网站内容,但遇到了匿名块问题。

查看示例代码:

var parser = new HtmlParser();
var document = parser.Parse(@"<body>
<div class='product'>
    <a href='#'><img src='img1.jpg' alt=''></a>
    Hello, world
    <div class='comments-likes'>1</div>
</div>
<div class='product'>
    <a href='#'><img src='img2.jpg' alt=''></a>
    Yet another helloworld
    <div class='comments-likes'>25</div>
</div>
<body>");

var products = document.QuerySelectorAll("div.product");
foreach (var product in products)
{
    var productTitle = product.Text();
    productTitle.Dump();
}

所以,productTitle 包含来自 div.cmets-likes 的数字,输出为:

你好,世界 1

又一个 helloworld 25

我尝试过类似product.FirstElementChild.NextElementSibling.Text(); 但链接元素的下一个兄弟是 div.cmets-likes,而不是匿名块。它显示:

1

25

因此,会跳过匿名块。 :(

我发现的最佳解决方法是删除所有阻止块,例如:

product.QuerySelector(".comments-likes").Remove();
var productTitle = product.Text().Trim();

从匿名块中解析文本的更好方法是什么?

【问题讨论】:

    标签: c# anglesharp


    【解决方案1】:

    文本被建模为TextNode,它是元素、注释节点、处理指令等旁边的节点类型。这就是为什么你尝试的NextElementSibling没有包含文本结果,顾名思义,它只打算返回元素。

    您可以通过遍历divChildNodes,然后通过NodeType 过滤来获取直接位于产品div 内的文本节点,例如:

    var products = document.QuerySelectorAll("div.product");
    foreach (var product in products)
    {
        var productTitle = product.ChildNodes
                                  .First(o => o.NodeType == AngleSharp.Dom.NodeType.Text 
                                                && o.TextContent.Trim() != "");
        Console.WriteLine(productTitle.TextContent.Trim());
    }
    

    dotnetfiddle demo

    注意元素之间的换行符也是文本节点,所以我们需要在上面的演示中过滤掉它们。

    【讨论】:

    猜你喜欢
    • 2018-05-16
    • 1970-01-01
    • 2016-07-05
    • 2017-10-16
    • 1970-01-01
    • 2020-03-31
    • 2015-08-22
    • 1970-01-01
    • 2020-08-13
    相关资源
    最近更新 更多