【问题标题】:.NET C#: WebBrowser control Navigate() does not load targeted URL.NET C#:WebBrowser 控件 Navigate() 不加载目标 URL
【发布时间】:2011-02-14 09:34:01
【问题描述】:

我正在尝试通过 WebBrowser 控件以编程方式加载网页,目的是测试页面及其 JavaScript 函数。基本上,我想将通过此控件运行的 HTML 和 JavaScript 与已知输出进行比较,以确定是否存在问题。

但是,我在创建和导航 WebBrowser 控件时遇到了麻烦。下面的代码旨在将 HtmlDocument 加载到 WebBrowser.Document 属性中:

WebBrowser wb = new WebBrowser();
wb.AllowNavigation = true;

wb.Navigate("http://www.google.com/");

在 Navigate() 运行后通过 Intellisense 检查 Web 浏览器的状态时,WebBrowser.ReadyState 为“未初始化”,WebBrowser.Document = null,总体上看来完全不受我的调用影响。

根据上下文,我在 Windows 窗体对象之外运行此控件:我不需要加载窗口或实际查看页面。需求表明需要简单地执行页面的 JavaScript 并检查生成的 HTML。

非常感谢任何建议,谢谢!

【问题讨论】:

  • 您是否有可能阻止请求的防火墙?见channel9.msdn.com/forums/TechOff/253431-WebBrowser-Ctrl-in-MFC
  • Windows 防火墙已关闭(我们有路由器防火墙),这是一台开发计算机。我之前已经发出过许多此类请求(TCP、HTTP 等),但都没有问题,所以我不太确定这是一个安全问题。
  • 我添加了一个简单的示例,说明如何从控制台应用程序处理此问题。

标签: c# .net controls browser navigateurl


【解决方案1】:

您应该处理 WebBrowser.DocumentComplete 事件,一旦引发该事件,您将拥有 Document 等。

wb.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(wb_DocumentCompleted);


private void wb_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
  WebBrowser wb = sender as WebBrowser;
  // wb.Document is not null at this point
}

这是一个完整的示例,我在 Windows 窗体应用程序中快速完成并进行了测试。

public partial class Form1 : Form
  {
    public Form1()
    {      
      InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
      WebBrowser wb = new WebBrowser();
      wb.AllowNavigation = true;

      wb.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(wb_DocumentCompleted);

      wb.Navigate("http://www.google.com");

              }

    private void wb_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
    {
      WebBrowser wb = sender as WebBrowser;
      // wb.Document is not null at this point
    }
  }

编辑:这是一个从控制台应用程序运行窗口的简单版本的代码。您当然可以更进一步,将事件暴露给控制台代码等。

using System;
using System.Windows;
using System.Windows.Forms;

namespace ConsoleApplication1
{
  class Program
  {    
    [STAThread] 
    static void Main(string[] args)
    {      
      Application.Run(new BrowserWindow());   

      Console.ReadKey();
    }
  }

  class BrowserWindow : Form
  {
    public BrowserWindow()
    {
      ShowInTaskbar = false;
      WindowState = FormWindowState.Minimized;
      Load += new EventHandler(Window_Load);
    }

    void Window_Load(object sender, EventArgs e)
    {      
      WebBrowser wb = new WebBrowser();
      wb.AllowNavigation = true;
      wb.DocumentCompleted += wb_DocumentCompleted;
      wb.Navigate("http://www.bing.com");      
    }

    void wb_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
    {
      Console.WriteLine("We have Bing");
    }
  }
}

【讨论】:

  • 很遗憾,这不起作用。 Web 浏览器似乎从来没有尝试加载页面。将此代码添加到我的原始 sn-p 会导致 DocumentCompleted 事件永远不会被调用并且程序退出。
  • @Dave,这很奇怪。我附上了一段完整的代码,我快速测试了它以确认它有效。
  • @Chris,我认为最大的区别是我没有在表单或类中创建或使用 WebBrowser。相反,我从类似库的上下文(无 UI)中创建/使用 WebBrowser,而不打算直观地显示输出。目标是在该页面中嵌入的客户端 JavaScript 处理之后,简单地获取请求该页面产生的 HTML。
  • @Dave,问题在于控制台应用程序没有消息泵来处理消息。
  • @Dave,我添加了一个简单的示例,说明如何从控制台应用程序处理此问题。
【解决方案2】:

您可能需要将控件托管在父窗口中。您可以通过将浏览器控件移出屏幕而不显示承载浏览器控件的窗口来执行此操作而不会违反要求。对于开发来说,“看到”它确实加载了一些用于测试、验证等的东西也可能很有用。

那就试试吧:

// in a form's Load handler:

WebBrowser wb = new WebBrowser();
this.Controls.Add(wb);
wb.AllowNavigation = true;
wb.Navigate("http://www.google.com/");

当您通过 IDE 实例化 WebBrowser 对象时,还要检查它设置了哪些其他属性。例如。创建一个表单,将浏览器控件拖放到它上面,然后检查表单的设计器文件以查看生成的代码。您可能缺少一些需要设置的关键属性。我以这种方式在我的代码中发现了许多遗漏,并且还学会了如何以编程方式正确地实例化可视对象。

附:如果您确实使用主机窗口,它应该只在开发过程中可见。您会以某种方式隐藏以进行生产。

另一种方法:

你可以通过尝试这样的方式来“原始”:

 System.Net.WebClient wc = new System.Net.WebClient();

  System.IO.StreamReader webReader = new System.IO.StreamReader(
         wc.OpenRead("http://your_website.com"));

  string webPageData = webReader.ReadToEnd();

...然后 RegEx 或解析 webPageData 以获得您需要的内容。还是您需要页面中的 jscript 才能实际执行? (这应该可以在 .NET 4.0 中实现)

【讨论】:

  • 需要注意的是,我也在 [STAThread] 下运行这个应用程序(这个程序的入口有这个指令)。否则,将引发有关仅支持的 ActiveX 和 STAThreads 的异常。在创建 WebBrowser 的同一函数中,我还尝试创建一个表单并将 WebBrowser 控件放置在该表单中。喜欢:WebBrowser wb = new WebBrowser();表格 f = 新表格(); f.Controls.Add(wb);离开它然后尝试导航什么都不做。显示窗口然后尝试导航没有任何作用。
  • 此应用程序的预期负载要求避免使用 Forms 和 Windows:鉴于它需要使用此 WebBrowser 每天运行 1000 多个测试(如果可行的话),拥有它是不切实际的有人坐下来观看每个页面的加载。
  • @Paul,为了响应您的“另一种方法”部分,原始格式可以,但是我 - 确实 - 需要页面上的 jscript 来执行。特别感兴趣的是嵌入在此应用程序正在测试的页面中的 jscript 是否适当地修改了文档。
【解决方案3】:

Webbrowser 控件只是 Internet Explorer 的包装器。

您可以设置到一个不可见的 Windows 窗体窗口以完全实例化它。

【讨论】:

    【解决方案4】:

    我遇到了这个问题,但我没有意识到我已经卸载了 Internet Explorer。如果你有,什么都不会发生,因为 WebBrowser 控件只实例化 IE。

    【讨论】:

    • 其实恰恰相反——IE实例化了与WebBrowser控件相同的引擎:)
    • 哦,好吧,有道理
    猜你喜欢
    • 2012-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-25
    • 2013-04-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多