使用 AngleSharp 从 html 注释中剥离解析的 html 文本

本文关键字:html 文本 剥离 AngleSharp 注释 使用 | 更新日期: 2023-09-27 18:32:15

我使用以下代码使用 AngleSharp 从解析的 html 中删除特定的 html 标签(因为建议使用正则表达式来执行此类工作(AngleSharp目前维护,HtmlAgilityPack没有,因此我一直在转向后者)。

它工作得很好 - 但现在我也想删除 html 注释。表示在<!---->标签之间找到的任何内容。

如何使用AngleSharp实现这一点?使用QuerySelector似乎不适合这里。

private string ExtractContentFromHtml(string input)
{
    List<string> tagsToRemove = new List<string>
    {
        "script",
        "style",
        "img"
    };
    var config = Configuration.Default.WithJavaScript();
    HtmlParser hp = new HtmlParser(config);
    List<IElement> tags = new List<IElement>();
    List<string> nodeTypes = new List<string>();
    var hpResult = hp.Parse(input);
    try
    {
        foreach (var tagToRemove in tagsToRemove)
            tags.AddRange(hpResult.QuerySelectorAll(tagToRemove));
        foreach (var tag in tags)
            tag.Remove();
    }
    catch (Exception ex)
    {
        _errors.Add(string.Format("Error in cleaning html. {0}", ex.Message));
    }
    var content = hpResult.QuerySelector("body");
    return (content).InnerHtml;
}

使用 AngleSharp 从 html 注释中剥离解析的 html 文本

在玩了上面的代码和AngleSharp的API之后,我想出了以下工作解决方案。最初我认为我可以替换我所有的标签删除内容,并且仅依靠处理文本节点,但这不推荐,由于某些文本节点将通过JavaScript代码动态生成,这意味着无论如何您都需要删除JavaScript节点。所以我也离开了样式 + img 删除。

值得一提的是,DOM 根据类型对节点进行分类,并且可以通过搜索类型 8 的节点来找到注释。

private string ExtractContentFromHtml(string input)
{
    List<string> tagsToRemove = new List<string>
    {
        "script",
        "style",
        "img"
    };
    var config = Configuration.Default.WithJavaScript();
    HtmlParser hp = new HtmlParser(config);
    List<IElement> tags = new List<IElement>();
    List<string> nodeTypes = new List<string>();
    var hpResult = hp.Parse(input);
    List<string> textNodesValues = new List<string>();
    try
    {
        foreach (var tagToRemove in tagsToRemove)
            tags.AddRange(hpResult.QuerySelectorAll(tagToRemove));
        foreach (var tag in tags)
            tag.Remove();

/*
   the following will not work, because text nodes that are not immediate children will not be considered 
   textNodesValues = hpResult.All.Where(n => n.NodeType == NodeType.Text).Select(n => n.TextContent).ToList();
*/

        var treeWalker = hpResult.CreateTreeWalker(hpResult, FilterSettings.Text);
        var textNode = treeWalker.ToNext();
        while (textNode != null)
        {
            textNodesValues.Add(textNode.TextContent);
            textNode = treeWalker.ToNext();
        }
    }
    catch (Exception ex)
    {
        _errors.Add(string.Format("Error in cleaning html. {0}", ex.Message));
    }
    return string.Join(" ", textNodesValues);
}