可以使用Html Agility Pack来解析HTML片段吗?

时间:2012-09-21 14:37:47

标签: c# .net html parsing html-agility-pack

我需要从ASP.NET页面,用户控件和母版页中获取LINKMETA元素,获取其内容,然后在我正在使用的实用程序中将更新的值写回这些文件上。

我可以尝试使用正则表达式来抓取这些元素,但这种方法有几个问题:

  • 我希望许多输入文件包含损坏的HTML(缺失/无序元素等)。
  • SCRIPT包含注释和/或VBScript / JavaScript的元素,看起来像有效元素等。
  • 我需要能够在IE条件注释中使用特殊情况IE条件注释以及METALINK元素
  • 更不用说HTML不是常规语言了

我在.NET中对HTML解析器进行了一些研究,许多SO帖子和博客推荐了HTML Agility Pack。我以前从未使用它,我不知道它是否可以解析破碎的HTML和HTML片段。 (例如,假设一个用户控件只包含一个HEAD元素,其中包含一些内容 - 没有HTMLBODY。)我知道我可以阅读文档但它会节省如果有人可以提出建议,我会花很多时间。 (大多数SO帖子涉及解析完整的HTML页面。)

2 个答案:

答案 0 :(得分:5)

当然,这就是它擅长的。

事实上,由于缺少<html>标签或不正确关闭的标签,您在野外发现的许多网页都可能被描述为HTML片段。

HtmlAgilityPack模拟浏览器必须做的事情 - 尝试从有时混乱的不匹配标签中弄清楚。一个不完美的科学,但HtmlAgilgityPack做得很好。

答案 1 :(得分:5)

Html Agility Pack的替代品是CsQuery,一个C#jQuery端口,我是其主要作者。它允许您使用CSS选择器和完整的查询API来访问和操作DOM,对于许多人来说,这比XPATH更容易。此外,它的HTML解析器专门针对各种目的而设计,并且有几种解析HTML的选项:作为完整文档(将添加缺少的html, body标记,并且在体内移动任何孤立的内容);作为内容块(意思是 - 它不会被包装为完整文档,但是DOM中仍然是必需的可选标记,例如tbody,会自动添加,与浏览器一样),并作为真正的片段没有标签的地方(例如,如果您只是使用构建块)。

有关详细信息,请参阅creating a new DOM

此外,CsQuery的HTML解析器旨在遵循可选结束标记的HTML5规范。例如,关闭p标记是可选的,但是有一些特定的规则可以确定何时应该关闭该块。为了生成与浏览器相同的DOM,解析器需要实现相同的规则。 CsQuery这样做是为了给定源提供与浏览器DOM的高度兼容性。

使用CsQuery非常简单,例如

CQ docFromString = CQ.Create(htmlString); 
CQ docFromWeb = CQ.CreateFromUrl(someUrl);

// there are other methods for asynchronous web gets, creating from files, streams, etc.

// css selector: the indexer [] is like jQuery $(..)

CQ lastCellInFirstRow = docFromString["table tr:first-child td:last-child"];

// Text() is a jQuery method returning text contents of selection 

string textOfCell = lastCellInFirstRow.Text();

最后,CsQuery对类,id,属性和标记上的文档进行索引 - 与Html Agility Pack相比,使选择器的速度极快。