我在VB.NET应用程序中使用WebBrowser控件加载一些URL(~10-15)并将其HTML源保存在文本文件中。但是,我的代码不会写入当前页面的源而不是初始页面,因为它甚至在页面加载之前就被触发了。
在调用任何事件之前,我怎么能等到页面完全加载?
我尝试了以下代码,但它不起作用。
Do Until WebBrowser1.ReadyState = WebBrowserReadyState.Complete
Application.DoEvents()
Loop
答案 0 :(得分:20)
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()
以下是代码:您需要两个潜点加上可访问变量pageready
。
首先,确保将名为whatbrowser
的变量修复为您的web浏览器控件
现在,在你的模块或课堂的某个地方,放置一下:
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
答案 1 :(得分:7)
听起来您想要捕获webbrowser控件的DocumentCompleted事件。
MSDN有几篇关于webbrowser控件的好文章 - WebBrowser Class有很多例子,How to: Add Web Browser Capabilities to a Windows Forms Application答案 2 :(得分:3)
从技术上讲,BGM发布的代码存在两个问题:
在WaitForPageLoad方法中添加处理程序可能为时已晚。在添加处理程序之前启动导航,这意味着在非常罕见的情况下,浏览器已经拥有页面,它可以在添加处理程序之前完成,在这种情况下,您将错过该事件并永远等待。
解决方案是在导航开始之前添加处理程序,并在导航完成后删除它们
这意味着WaitForPageLoad方法需要拆分为两个方法。在启动导航之前调用一个。它应该设置处理程序。第二部分进行ReadyState监控,并在“准备就绪”时进行清理。
良好的编程习惯是添加超时,以便丢失(或崩溃或循环)浏览器不会使您的代码永远等待文档完成,甚至
答案 3 :(得分:3)
有时如果使用JavaScript,DocumentComplet事件不会返回正确的答案,我会使用事件ProgressChanged
Private Sub WebBrowser1_ProgressChanged(sender As Object, e As WebBrowserProgressChangedEventArgs) _
Handles WebBrowser1.ProgressChanged
Console.WriteLine("CurrentProgress: " + e.CurrentProgress.ToString)
If e.CurrentProgress = e.MaximumProgress Then
'The maximun progres is reached
load_stated = True
End If
'The page is confirmed downloaded after the pregres return to 0
If e.CurrentProgress = 0 Then
If load_stated Then
'the page is ready to print or download...
WebBrowser1.Print()
load_stated = False
End If
End If
End Sub
答案 4 :(得分:1)
在加载事件中,使用Me.Hide
。
在WebBrowser1.DocuementCompleted中,使用Me.Show
答案 5 :(得分:1)
坚持......
根据我的经验,您应该确保DocumCompleted
属于您的网址,而不是框架子网页,脚本,图片,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
答案 6 :(得分:0)
我在这个“满载”问题上挣扎了一段时间,但发现以下解决方案对我有用。我正在使用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
足以容纳浏览器。不确定这是否会对每个人有所帮助,作为IE7的组合,我加载的网站,以及单独运行该页面的javascript可能已经允许这个解决方案,但当然值得一试。
答案 7 :(得分:0)
另一种选择是检查计时器是否忙:
将计时器默认设置为禁用。然后,每当导航时,启用它。即:
removeItem(itemID, n) {
}
还有计时器:
WebBrowser1.Navigate("https://www.somesite.com")
tmrBusy.Enabled = True
答案 8 :(得分:-1)
我做了类似的功能(只对我有用) - 抱歉它在C#中,但很容易翻译......
private void WaitForPageLoad ( ) {
while (pageReady == false)
Application.DoEvents();
while (webBrowser1.IsBusy || webBrowser1.ReadyState != WebBrowserReadyState.Complete)
Application.DoEvents();
}