WebBrowser导航功能没有';t工作,并且不调用处理程序
本文关键字:调用 程序 处理 工作 功能 导航 WebBrowser | 更新日期: 2023-09-27 18:29:06
下面的代码。
我正在尝试导航到一个网站并读取信息,问题是navigate不起作用,唯一被调用的事件是Navigation,并且打印的Url为空,其他事件从未被调用。我错过了什么?我必须使用Form类才能导航吗?我不能从控制台应用程序中以程序方式使用它吗?
请帮忙。
class WebNavigator
{
private readonly WebBrowser webBrowser;
public WebNavigator()
{
webBrowser = new WebBrowser
{
AllowNavigation = true
};
webBrowser.Navigated += webBrowser_Navigated;
webBrowser.Navigating += webBrowser_Navigating;
webBrowser.DocumentCompleted += webBrowser_DocumentCompleted;
}
// Navigates to the given URL if it is valid.
public void Navigate(string address)
{
if (String.IsNullOrEmpty(address)) return;
if (address.Equals("about:blank")) return;
if (!address.StartsWith("http://") &&
!address.StartsWith("https://"))
{
address = "http://" + address;
}
try
{
Trace.TraceInformation("Navigate to {0}", address);
webBrowser.Navigate(new Uri(address));
}
catch (System.UriFormatException)
{
Trace.TraceError("Error");
return;
}
}
// Occurs when the WebBrowser control has navigated to a new document and has begun loading it.
private void webBrowser_Navigated(object sender, WebBrowserNavigatedEventArgs e)
{
Trace.TraceInformation("Navigated to {0}", webBrowser.Url);
}
// Occurs before the WebBrowser control navigates to a new document.
private void webBrowser_Navigating(object sender, WebBrowserNavigatingEventArgs e)
{
Trace.TraceInformation("Navigating to {0}", webBrowser.Url);
}
private void webBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
var wb = sender as WebBrowser;
Trace.TraceInformation("DocumentCompleted {0}", wb.Url);
}
}
我会使用wait/async。
用法:
static async void DoWork()
{
var html = await GetHtmlAsync("http://www.google.com/");
}
实用方法
static Task<string> GetHtmlAsync(string url)
{
var tcs = new TaskCompletionSource<string>();
var thread = new Thread(() =>
{
WebBrowser wb = new WebBrowser();
WebBrowserDocumentCompletedEventHandler documentCompleted = null;
documentCompleted = async (o, s) =>
{
wb.DocumentCompleted -= documentCompleted;
await Task.Delay(2000); //Run JS a few seconds more
tcs.TrySetResult(wb.DocumentText);
wb.Dispose();
Application.ExitThread();
};
wb.ScriptErrorsSuppressed = true;
wb.DocumentCompleted += documentCompleted;
wb.Navigate(url);
Application.Run();
});
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
return tcs.Task;
}
您提到这是一个控制台应用程序。为了使WebBrowser
在控制台应用程序中工作,您需要确保浏览器的线程是STA线程(thread.SetApartmentState(ApartmentState.STA
)。此外,为了能够处理事件,线程必须泵送消息(Application.Run
)。考虑到这一点,您可能需要创建一个单独的线程(从主控制台线程)来运行WebBrowser。
感谢您的回答。通过添加this while子句(包括Application.DoEvents();
webBrowser.Navigate(new Uri(address));
while (!navigationCompleted)
{
Application.DoEvents();
Thread.Sleep(navigationPollInterval);
}
我不确定这是否是最佳解决方案,如果能听到更好的解决方案,我将不胜感激。