2

我使用下面的代码从解析的 html 中剥离特定的 html 标记AngleSharp(因为建议使用正则表达式来执行此类工作(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;
}
4

1 回答 1

4

在使用了上面的代码和 AngleSharp 的 API 之后,我想出了以下工作解决方案。最初我以为我可以替换我所有的标签删除东西,只依赖于处理文本节点,但这是不推荐的,因为一些文本节点将通过 javascript 代码动态生成,这意味着无论如何你都需要删除 javascript 节点. 所以我也离开了 style + 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);
}
于 2016-01-28T16:15:06.953 回答