Html Agility Pack仍然是最好的.NET HTML解析器吗?

Ian*_*ose 57 .net html c# parsing html-agility-pack

Html Agility Pack是前一段时间给出StackOverflow问题的答案,它仍然是最好的选择吗?还应该考虑哪些其他选择?有更轻量级的东西吗?

小智 53

有一个包含比较的电子表格.

综上所述:

CsQuery性能与Html Agility Pack和Fizzler我将一些性能测试放在一起,将CsQuery与我所知道的唯一实用替代品(Fizzler,一个HtmlAgilityPack扩展)进行比较.我测试了三种不同的文件:

  • 嘶嘶声测试文件(约11 k)
  • 维基百科条目"奶酪"(约170 k)
  • 单页HTML 5规范(约6兆字节)

总体结果是:

  • HAP在将HTML字符串加载到对象模型中的速度更快.这是有道理的,因为我不认为Fizzler构建索引(或者它可能只构建一个相对简单的索引).CsQuery需要1.1到2.6倍的时间才能加载文档.更多关于此的信息.
  • 几乎所有其他东西的CsQuery都更快.有时因数为10,000或更多.唯一的例外是"*"选择器,有时Fizzler更快.对于所有测试,结果都是完全列举的; 这种情况只会导致树中的每个节点都被枚举.因此,这不会像数据结构那样测试选择引擎.
  • CsQuery在返回与浏览器相同的结果方面做得更好.这里的每个选择器都使用jQuery 1.7.2在Chrome中针对同一文档进行了验证,并且数字与CsQuery返回的数字相匹配.这可能是因为HtmlAgilityPack以不同方式处理可选(缺失)标签.另外,在Fizzler中没有完全实现nth-child - 它只支持简单的值(而不是公式).

  • Html Agility Pack是HTML解析器,而不是Awesonium的无头浏览器. (4认同)
  • 请注意,此答案中引用的博客文章是由CsQuery的作者撰写的.这并不是说任何内容都是不准确或有偏见的,但请注意,这不是一个公正的来源. (4认同)

Jam*_*rgy 37

谈到HTML解析时,没有与真实的东西进行比较.这是validator.nu解析器的C#端口.这与基于Gecko的浏览器(例如Firefox)使用的代码库相同.回购看起来有点尘土飞扬,但不要被愚弄..港口非常出色.它被忽略了.我大约一个月前将它集成到CsQuery中.它通过了所有的CsQuery测试(其中包括大多数移植到C#的jQuery和Sizzle测试).

我不知道用C#编写的任何其他HTML5解析器,或者甚至是任何在丢失,可选和无效标记处理方面做得很好的任何HTML5解析器.这不仅做得很好 - 它符合标准.

我上面链接的repo是原始端口,它包含一个生成XML节点树的基本包装器.CsQuery 1.3及更高版本使用此解析器.

  • 我喜欢这样一个事实,即接受的答案是指向_your_博客上的文章和引用_you_的段落的链接.哈哈获得+400的胜利. (8认同)

Sim*_*mon 13

还有AngleSharp

AngleSharp是一个.NET库,使您能够分析基于角括号的超文本,如HTML,SVG和MathML.库也支持未经验证的XML.AngleSharp的一个重要方面是CSS也可以被解析.解析器基于官方W3C规范.这产生了给定源代码的完全可移植的HTML5 DOM表示.此外,当前的功能(如querySelector或querySelectorAll)也适用于树遍历.


csh*_*net 11

很久以前,Html Agility Pack就作为StackOverflow问题的答案

Html Agility Pack仍然是解析HTML的出色解决方案.

它仍然是最好的选择吗?

最好?好吧,一切都取决于手头的任务,但总的来说我是这么认为的.在某些情况下,它确实达不到理想状态,但通常它会做得很好.

有更轻量级的东西吗?

您可以试试这个:http://csharptest.net/browse/src/Library/Html/ 这只不过是一个手工填充的源文件,通过Regex分离HTML/XML.它支持轻量级DOM和XPath,但不是很多.(帮助内容)

[例]

public void TestParse() {
        string notxml = "<html id=a ><body foo='bar' bar=\"foo\" />";
        var html = new HtmlLightDocument(notxml).Root;

        Assert.AreEqual("html", html.TagName);
        Assert.AreEqual(1, html.Attributes.Count);
        Assert.AreEqual("a", html.Attributes["id"]);
        Assert.AreEqual(1, html.Children.Count);
}
Run Code Online (Sandbox Code Playgroud)

或者,您可以直接使用解析器,而不是构建DOM树.只需实现IXmlLightReader接口,并调用静态XmlLightParser.Parse方法.

PS:它是为解决内部辩论而编写的:Regex 可以解析HTML!从那时起,我们实际上已经找到了许多用途,因为它足够轻便可以嵌入任何地方.仍有一些方法可以混淆DOM层次结构构建器,但我还没有找到解析器无法处理的任何HTML.