在不使用WebBrowser或HAP的情况下,将字符串或html文件转换为C#HtmlDocument

本文关键字:html 字符串 文件 C#HtmlDocument 转换 情况下 WebBrowser HAP | 更新日期: 2023-09-27 18:25:08

我能找到的唯一解决方案是使用:

            mshtml.HTMLDocument htmldocu = new mshtml.HTMLDocument();
            htmldocu .createDocumentFromUrl(url, "");

我不确定它的性能,它应该比在WebBrowser中加载html文件,然后从那里获取HtmlDocument要好。无论如何,那个代码在我的机器上不起作用。应用程序在尝试执行第二行时崩溃。

有人能有效地或以任何其他方式实现这一目标吗?

注意:请理解我需要HtmlDocument对象来进行DOM处理。我不需要html字符串。

在不使用WebBrowser或HAP的情况下,将字符串或html文件转换为C#HtmlDocument

使用WebClient对象的DownloadString方法。例如

WebClient client = new WebClient();
string reply = client.DownloadString("http://www.google.com");

在上面的示例中,执行后,reply将包含端点http://www.google.com的html标记。

WebClient.DownloadString MSDN

为了回答您四年前的实际问题(在我发布此答案时),我正在提供一个有效的解决方案。如果你找到了另一种方法,我也不会感到惊讶,所以这主要是为其他人寻找类似的解决方案。但是,请记住,这被视为

  1. 有些过时(HtmlDocument的实际使用)
  2. 不是处理HTML DOM解析的最佳方法(首选解决方案是使用HtmlAgilityPack或CsQuery或其他使用实际解析而非正则表达式的方法)
  3. 非常黑客,因此不是最安全/最兼容的方式
  4. 你真的不应该做我要展示的事

此外,请记住,HtmlDocument实际上只是mshtml.HTMLDocument2的包装器,因此从技术上讲,它比直接使用COM包装器慢,但我完全理解用例,只是为了便于编码。

如果你对以上所有内容都很满意,下面是如何实现你想要的。

public class HtmlDocumentFactory
{
  private static Type htmlDocType = typeof(System.Windows.Forms.HtmlDocument);
  private static Type htmlShimManagerType = null;
  private static object htmlShimSingleton = null;
  private static ConstructorInfo docCtor = null;
  public static HtmlDocument Create()
  {
    if (htmlShimManagerType == null)
    {
      // get a type reference to HtmlShimManager
      htmlShimManagerType = htmlDocType.Assembly.GetType(
        "System.Windows.Forms.HtmlShimManager"
        );
      // locate the necessary private constructor for HtmlShimManager
      var shimCtor = htmlShimManagerType.GetConstructor(
        BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[0], null
        );
      // create a new HtmlShimManager object and keep it for the rest of the
      // assembly instance
      htmlShimSingleton = shimCtor.Invoke(null);
    }
    if (docCtor == null)
    {
      // get the only constructor for HtmlDocument (which is marked as private)
      docCtor = htmlDocType.GetConstructors(
        BindingFlags.NonPublic | BindingFlags.Instance
        )[0];
    }
    // create an instance of mshtml.HTMLDocument2 (in the form of 
    // IHTMLDocument2 using HTMLDocument2's class ID)
    object htmlDoc2Inst = Activator.CreateInstance(Type.GetTypeFromCLSID(
      new Guid("25336920-03F9-11CF-8FD0-00AA00686F13")
      ));
    var argValues = new object[] { htmlShimSingleton, htmlDoc2Inst };
    // create a new HtmlDocument without involving WebBrowser
    return (HtmlDocument)docCtor.Invoke(argValues);
  }
}

使用它:

var htmlDoc = HtmlDocumentFactory.Create();
htmlDoc.Write("<html><body><div>Hello, world!</body></div></html>");
Console.WriteLine(htmlDoc.Body.InnerText);
// output:
// Hello, world!

我没有直接测试过这段代码——我已经从一个旧的Powershell脚本中翻译了它,该脚本需要与您请求的功能相同的功能。如果失败了,请告诉我。功能已经存在,但代码可能需要非常小的调整才能正常工作。