Webbrowser Document Complete
I'm using a webbrowser control to pull some information from a website. It works fine.
I load the web page when the user clicks a button and then I pull the information from the site when the page completely loads. I have this bit of code in the DocumentComplete event.
I am doing this for two different websites. So, my code as it is, looks something likes this:
vb.net Code:
Private Sub btnStart_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStart.Click
WebBrowser1.Navigate("http://www.website.com")
End If
Private Sub WebBrowser1_DocumentCompleted(ByVal sender As System.Object, ByVal e As System.Windows.Forms.WebBrowserDocumentCompletedEventArgs) Handles WebBrowser1.DocumentCompleted
Dim q As String = WebBrowser1.Document.GetElementById("123").InnerText
txtOne.Text = (q)
End If
If I add a second Navigate to the same WebBrowser control, and then add another Document.GetElementById line, using different variables, it doesn't work.
Its obvious that it loads both sites and then it finishes. So, it never has time to finish the first load and then pull the info into the text box.
Is there a way to do this? To load the first site, pull the info, load the second site, then pull the info from there?
Thanks
Re: Webbrowser Document Complete
vb Code:
Private Sub btnStart_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStart.Click
WebBrowser1.Navigate("http://www.website.com")
While Not WebBrowser1.ReadyState = WebBrowserReadyState.Complete
Application.DoEvents()
End While
txtOne.Text = WebBrowser1.Document.GetElementById("123").InnerText
End If
Re: Webbrowser Document Complete
Re: Webbrowser Document Complete
I thought I had this resolved, but apparently I'm mistaken.
I put the code into two If statements that depend on the checked state of a check box.
I tried this:
vb.net Code:
If CheckBox1.Checked And CheckBox2.Checked = True Then
WebBrowser1.Navigate("http://www.website.com")
While Not WebBrowser1.ReadyState = WebBrowserReadyState.Complete
Application.DoEvents()
End While
Dim q As String = WebBrowser1.Document.GetElementById("123").InnerText
TextBox1.Text = (q)
End If
If CheckBox3.Checked And CheckBox4.Checked = True Then
WebBrowser1.Navigate("http://www.website.com")
While Not WebBrowser1.ReadyState = WebBrowserReadyState.Complete
Application.DoEvents()
End While
Dim q As String = WebBrowser1.Document.GetElementById("456").InnerText
TextBox2.Text = (q)
End If
When I run the code, it loads the first item into the first box. After that, the code doesn't work.
I think it has something to do with the state of the webbrowser, but i'm not sure.
Re: Webbrowser Document Complete
Hi,
Wouldn't be better to put these if statements in a select case statement.
Re: Webbrowser Document Complete
It probably would be, Sparrow. I've just been using If statements since I started and I didn't want to learn select case because If statements have been working.
I didn't want to introduce something new and possibly have some more unknown problems.
But, I should probably get to it finally. I'll see what I come up with.
Thanks
Re: Webbrowser Document Complete
DocumentCompleted can fire multiple times and only the last time will be the real McCoy. You can get lost in your code where one DocumentCompleted is waiting for the While to finish and another DocumentCompleted gets raised, your code starts another Do...While and so on.
Try it with a simple If:
If WebBrowser1.ReadyState = WebBrowserReadyState.Complete Then
'your code
A simpler (lamer) way would be:
Code:
If WebBrowser1.ReadyState <> WebBrowserReadyState.Complete Then
Exit Sub
End If
'your code
Re: Webbrowser Document Complete
When DocumentCompleted fires, it also contains the URL in the eventargs for the page it just loaded. If it was a frame on the page it loaded, the URL will be specifically that frames URL, not the page you navigated to. When the event fires the final time, it should be for the actual URL you were navigated to.
Re: Webbrowser Document Complete
While Not WebBrowser1.ReadyState = WebBrowserReadyState.Complete IS NOT RELIABLE.
There are many website today that NEVER fire a complete event.
Re: Webbrowser Document Complete
Quote:
Originally Posted by
scrapersNbots.com
While Not WebBrowser1.ReadyState = WebBrowserReadyState.Complete IS NOT RELIABLE.
There are many website today that NEVER fire a complete event.
You should have mentioned that 7.5 years ago, when this thread was last active :D
Re: Webbrowser Document Complete
Quote:
Originally Posted by
scrapersNbots.com
While Not WebBrowser1.ReadyState = WebBrowserReadyState.Complete IS NOT RELIABLE.
There are many website today that NEVER fire a complete event.
Yes and no. You're right, websites don't fire a complete event... they don't fire any event. It's the webbrowser that fires it.
But that's not where the unreliability comes in. The .ReadyState should be in the DocumentComplete event, and it shouldn't be in a loop. That's going to be the most accurate way to determine if a page has finished loading. But you're right in that it isn't 100% reliable, in that sites these days use AJAX and other methods to dynamically load stuff. THOSE don't fire the documentComplete event and those don't reflect the ReadyState. So you have to keep polling something on the page, before deciding if you should continue or not.
So the DocumentComplete event along with checking the ReadyState IN the event (no in a click or in a loop) will get you there 90% of the time. But there are sometimes when that's not going to be enough.
-tg
Re: Webbrowser Document Complete
What I have done is created a control that I named BrowserMonitor which has a timer set at interval of 200
Private Sub Tmr_Timer()
On Error GoTo err:
Static sText As String
'the document won't have any innerText unless the document is complete (enough)
Code:
Dim sT As String: sT = Trim(mWebBrowser.Document.body.innerText)
'the text on the page has changed
If sText <> sT Then
sText = sT
mWebBrowser.Silent = True
v.bBrowserReady = True
RaiseEvent BrowserReady
End If
When I have my program navigate to a webpage via webbrowser.navigate the next line of code is to a function that pauses and then the next line of code calls this function within the same control.
Code:
'call this function to see when the browser is ready
Public Function bfBrowserReady() As Boolean
Do
Pause.subFor 1
Loop Until v.bBrowserReady = True
bfBrowserReady = True
v.bBrowserReady = False
End Function
so for example:
Code:
webbrowser1.navigate "http://www.scrapersnbots.com"
pause.subFor 2
if BrowserMonitor.bfBrowserReady = "false" then stop
Because its a function call it won't return until it returns true
By the way, the pause code is (separate module)
Code:
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Sub subFor(ByVal Delay As Single)
Delay = (Timer + Delay)
Do
DoEvents: DoEvents: If vars.v.bClosingApplication Then Exit Do: DoEvents: DoEvents
Sleep 10
Loop While Delay > Timer
End Sub
Surprisingly the whole thing has proven to be pretty reliable because even if only part of a page changes
do to ajax call this still picks it up. I am determined to invent a real elegant solution, however, this is just for nows.