如何等待WebBrowser在VB.NET中完全加载?
我在VB.NET应用程序中使用WebBrowser控件加载一些URL(~10-15),并将它们的HTML源代码保存在文本文件中。但是,我的代码并没有编写当前页面的源代码,而是编写初始页面的源代码,因为它甚至在加载页面之前就被触发了 在调用任何事件之前,如何等待页面完全加载 我尝试了下面的代码,但不起作用如何等待WebBrowser在VB.NET中完全加载?,vb.net,webbrowser-control,Vb.net,Webbrowser Control,我在VB.NET应用程序中使用WebBrowser控件加载一些URL(~10-15),并将它们的HTML源代码保存在文本文件中。但是,我的代码并没有编写当前页面的源代码,而是编写初始页面的源代码,因为它甚至在加载页面之前就被触发了 在调用任何事件之前,如何等待页面完全加载 我尝试了下面的代码,但不起作用 Do Until WebBrowser1.ReadyState = WebBrowserReadyState.Complete Application.DoEvents() Loop 听
Do Until WebBrowser1.ReadyState = WebBrowserReadyState.Complete
Application.DoEvents()
Loop
听起来您想捕获webbrowser控件的事件
MSDN有几篇关于webbrowser控件的好文章-有很多例子,还有Salvete!我只需要调用一个函数,让代码等待页面加载,然后再继续运行。在搜索了网页上的答案后,我花了好几个小时,想出了这个方法来为自己解决你所面临的困境。我知道我在游戏中已经迟到了,但我想把这篇文章发给其他任何人 用法:只需在调用导航后调用
WaitForPageLoad()
:
whatbrowser.Navigate("http://www.google.com")
WaitForPageLoad()
另一个例子
我们不将导航功能与页面加载相结合,因为有时您需要等待加载而不进行导航,例如,您可能需要等待加载一个由invokemember
事件启动的页面:
whatbrowser.Document.GetElementById("UserName").InnerText = whatusername
whatbrowser.Document.GetElementById("Password").InnerText = whatpassword
whatbrowser.Document.GetElementById("LoginButton").InvokeMember("click")
WaitForPageLoad()
代码如下:您需要两个sub加上可访问变量,pageready
。
首先,确保将名为whatbrowser
的变量固定为webbrowser控件
现在,在模块或类中的某个位置,放置以下内容:
Private Property pageready As Boolean = False
#Region "Page Loading Functions"
Private Sub WaitForPageLoad()
AddHandler whatbrowser.DocumentCompleted, New WebBrowserDocumentCompletedEventHandler(AddressOf PageWaiter)
While Not pageready
Application.DoEvents()
End While
pageready = False
End Sub
Private Sub PageWaiter(ByVal sender As Object, ByVal e As WebBrowserDocumentCompletedEventArgs)
If whatbrowser.ReadyState = WebBrowserReadyState.Complete Then
pageready = True
RemoveHandler whatbrowser.DocumentCompleted, New WebBrowserDocumentCompletedEventHandler(AddressOf PageWaiter)
End If
End Sub
#End Region
从技术上讲,BGM发布的代码存在两个问题:
我与这个“满负荷”问题斗争了一段时间,但发现以下解决方案对我有效。我使用的是IE7,所以我不确定它是否适用于其他版本,但值得一看 我把问题分成两部分;首先,我需要DocumentComplete事件的消息
Private Sub WebBrowser1_DocumentComplete(ByVal pDisp As Object, URL As Variant)
fullyLoaded = True
End Sub
然后在我需要等待网页完全加载的代码部分,我调用另一个子模块来完成这项工作
Private Sub holdBrowserPage()
fullyLoaded = False
Do While fullyLoaded = False
DoEvents
Loop
fullyLoaded = False
End Sub
此外,我还需要在等待javascript代码完成时做同样的事情。例如,在一个页面上,当您从html下拉列表中选择一个项目时,它填充了下一个下拉列表,但需要一段时间才能显示出来。在那种情况下,我发现把它叫做
Private Sub holdBrowser()
Do While WebBrowser1.Busy Or WebBrowser1.ReadyState <> READYSTATE_COMPLETE
DoEvents
Loop
End Sub
Private子浏览器()
在WebBrowser1.Busy或WebBrowser1.ReadyState ReadyState\u完成时执行此操作
多芬特
环
端接头
足够容纳浏览器。不确定这是否会帮助所有人,因为IE7、我正在加载的网站和页面单独运行的javascript的组合可能允许使用此解决方案,但肯定值得一试。在加载事件中,使用
Me.Hide
在WebBrowser1.docueCompleted中,使用Me.Show
我制作了类似的功能(仅对我有效);抱歉,它是C语言的,但很容易翻译
private void WaitForPageLoad () {
while (pageReady == false)
Application.DoEvents();
while (webBrowser1.IsBusy || webBrowser1.ReadyState != WebBrowserReadyState.Complete)
Application.DoEvents();
}
等一下
根据我的经验,您应该确保DocumCompleted
属于您的URL,而不是框架子页面、脚本、图像、CSS等,这与IsBusy
或ReadyState
是否完成无关,当页面稍微复杂时,这两个属性通常都不准确
这是我个人的经验,关于VB.2013和IE11的工作程序。我还要提到的是,您还应该考虑到兼容性模式IE7,该模式在webBrowser1
上默认为启用状态
' Page, sub-frame or resource was totally loaded.
Private Sub webBrowser1_DocumentCompleted(sender As Object, _
e As WebBrowserDocumentCompletedEventArgs) _
Handles webBrowser1.DocumentCompleted
' Check if finally the full page was loaded (inc. sub-frames, javascripts, etc)
If e.Url.ToString = webBrowser1.Url.ToString Then
' Only now you are sure!
fullyLoaded = True
End If
End Sub
有时,如果使用JavaScript,
DocumentComplete
事件不会返回正确答案;我使用事件ProgressChanged
:
Private Sub WebBrowser1_ProgressChanged(sender As Object, e As WebBrowserProgressChangedEventArgs) Handles WebBrowser1.ProgressChanged
Console.WriteLine("Current Progress: " + e.CurrentProgress.ToString)
If e.CurrentProgress = e.MaximumProgress Then
' The maximum progress is reached
load_started = True
End If
' The page is confirmed downloaded after the progress returns to 0
If e.CurrentProgress = 0 Then
If load_started Then
' The page is ready to print or download...
WebBrowser1.Print()
load_started = False
End If
End If
End Sub
另一个选项是检查它是否正忙着使用计时器: 默认情况下,将计时器设置为禁用。然后,无论何时导航,都要启用它。i、 e:
WebBrowser1.Navigate("https://www.somesite.com")
tmrBusy.Enabled = True
和计时器:
Private Sub tmrBusy_Tick(sender As Object, e As EventArgs) Handles tmrBusy.Tick
If WebBrowser1.IsBusy = True Then
Debug.WriteLine("WB Busy ...")
Else
Debug.WriteLine("WB Done.")
tmrBusy.Enabled = False
End If
End Sub
在WebBrowser本身的声明中,我使用的是私有子WebBrowser 1_DocumentCompleted。当页面在WebBrowser的declarion中完全加载时,我如何实现发生的事情?@Shubham:(MSDN:“如何:编写事件处理程序”),或者看看Hans的示例。不要忘记方法声明末尾的
Handles
关键字。请稍候。。。让我从我的角度(见我的答案)提出一个DocumentCompleted
的准确例子,我也想知道这一点。在加载过程中,Read状态通常达到4。我们只需要知道它什么时候完成。就这些了。@shubham如果你在这方面还有问题,请告诉我,因为我多年来已经开发了解决这个问题的技术,这些方法还不为人所知,也没有发表过。这个问题是整个WebBrowser控件中最重要也是最困难的问题。阅读我最近关于webbrowser控件的一些帖子(在过去几天里我做了很多),特别是关于WB控件限制的帖子,在我的下一篇评论中。基本上,我已经解决了所有的问题,如果你仍然