C#解析通用HTML?

C#解析通用HTML?,c#,.net,html,C#,.net,Html,获取HTML字符串并将其转换为有用内容的最佳方法是什么 基本上,如果我获取一个URL并在.net中从该URL获取HTML,我会得到一个响应,但这将以文件、流或字符串的形式出现 如果我想要一个实际的文档或者像XmlDocument对象一样可以爬行的东西,该怎么办 我对此有一些想法和已经实现的解决方案,但我有兴趣了解社区对此的看法。HTML页面即使是用XHTML编写的,也很少是有效的XML,因此它们无法加载到标准XML对象中 请看下面的图片。此.net组件将允许您遍历DOM,即使它无效。我使用MSH

获取HTML字符串并将其转换为有用内容的最佳方法是什么

基本上,如果我获取一个URL并在.net中从该URL获取HTML,我会得到一个响应,但这将以文件、流或字符串的形式出现

如果我想要一个实际的文档或者像XmlDocument对象一样可以爬行的东西,该怎么办


我对此有一些想法和已经实现的解决方案,但我有兴趣了解社区对此的看法。

HTML页面即使是用XHTML编写的,也很少是有效的XML,因此它们无法加载到标准XML对象中

请看下面的图片。此.net组件将允许您遍历DOM,即使它无效。

我使用MSHTMLAPI

只需引用mshtml程序集,然后包含名称空间

从那里你可以声明一个HTMLDocument对象,它是可查询的,这在某些地方有点让人头疼,因为API设计迫使你进行随机转换,但它确实完成了任务,而且它总是可以自己放入一个util类中,所以你不必在主应用程序代码类中保留你的奇怪之处

var browser = new System.Windows.Forms.WebBrowser();
browser.Navigate(new System.Uri("http://example.com"));
var doc = browser.Document;
HtmlDocument
有许多有用的

例如,
doc.All
,它是
HtmlControlCollection
,可以成为通用集合
ICollection

HtmlControl.doElement
指的是另一个答案中提到的
mshtml
名称空间


您可以在

中找到一些使用示例最简单的方法是将其加载到System.Windows.Forms.HtmlDocument类中。然后可以从那里访问DOM

当然,您可能希望查看HTTP响应中的内容类型,以确定这是否实际上是HTML(问题所指),或者这是否可能是二进制数据,例如图像

HTTP基本上只是吐出一个原始文档,它要么是二进制数据,要么是标记文本,而浏览器通常使用响应头中提供的提示来完成其余的工作。当然,这些都很好地包装在HTTPWebResponse clas中,可以随时使用。

您可以使用它来格式化您在响应中获得的html。然后,您将能够将其加载到XmlDocument中,并遍历节点以获得所需的内容

Tidy document = new Tidy();
TidyMessageCollection messageCollection = new TidyMessageCollection();

document.Options.DocType = DocType.Omit;
document.Options.Xhtml = true;
document.Options.CharEncoding = CharEncoding.UTF8;
document.Options.LogicalEmphasis = true;

document.Options.MakeClean = false;
document.Options.QuoteNbsp = false;
document.Options.SmartIndent = false;
document.Options.IndentContent = false;
document.Options.TidyMark = false;

document.Options.DropFontTags = false;
document.Options.QuoteAmpersand = true;
document.Options.DropEmptyParas = true;

MemoryStream input = new MemoryStream();
MemoryStream output = new MemoryStream();
byte[] array = Encoding.UTF8.GetBytes(xmlResult);
input.Write(array, 0, array.Length);
input.Position = 0;

document.Parse(input, output, messageCollection);

string tidyXhtml = Encoding.UTF8.GetString(output.ToArray());

XmlDocument outputXml = new XmlDocument();
outputXml.LoadXml((tidyXhtml);

除了HTML敏捷包,我还在Github上发布了我的(一个轻量级HTML解析器)


它不依赖任何第三方工具。它只是检查文本的每个字符以提取HTML标记,并构建一个可以从代码中遍历的DOM。

为什么不使用.NET库进行XML解析?哈哈,我真不敢相信你这么说。。。html不是xml,某些使html有效的东西不是有效的xml,这是行不通的。简单。。。很简单。。。但是试试这个。。。1.创建一个新的控制台应用程序2。把代码放进去。添加对System.Windows.Forms 4的引用。运行它。此示例似乎已中断,但使用mshtml api不起作用,但不确定agility pack。@Wardy:WebBrowser控件在控制台应用程序中不起作用,因为它是COM对象上的包装器,无法在STA模式下运行。确切地说,我有作为独立程序集一部分的代码,我只是引用它并根据需要使用它,最好的解决方案总是一个干净的便携式:)@Wardy:Hi,Wardy。你的问题成功了吗?:)我已经标出了我认为最干净、最灵活的答案。但是我已经有了几种解决方案。这就是为什么我说“像xml文档”的原因,就像在。。。我对此非常了解。有关于此组件的详细文档吗?请尝试tidy.net派生的tidy项目。不是.net,但应该能让您了解其用法。很有趣,但要使文档处于可读状态,需要很多代码,你不这么认为吗。。。如果你只需要写一次就好了,不过我想。。。然而,我怀疑代码的性能大多数只是设置属性。对于大小适中的html页面来说,性能并不是一个真正的问题。你可以尝试一些性能测试,我想是针对你可能遇到的最大的html页面。大多数代码都是设置属性的,你是对的……但是代码中的dom加载了两次,我还没有对它做任何处理。这对我来说是个糟糕的做法,但我并不总是对的。我不喜欢在网络问题上依赖windows窗体,虽然这在技术上是“最简单的方法”,但不是最实用的。。。为什么要引入不相关的依赖项?