我一直玩的方法,被建議作爲我的另一個問題的答案(Automate website log-in and form filling?),並注意到一些好奇。InvalidCastException與WebBrowser.IsBusy或ReadyState(VB.NET)
上述問題的答案是使用一系列JavaScript調用作爲URL來填寫Web表單並提交它。我一直試圖在VB.NET程序中自動執行此操作,但沒有成功。
原來的例子,我被給予不工作,大概是因爲你是在同一個線程等待作爲其中WebBrowser控件工作:
WebBrowser1.Navigate("http://www.google.com")
Do While WebBrowser1.IsBusy OrElse WebBrowser1.ReadyState <> WebBrowserReadyState.Complete
Threading.Thread.Sleep(1000)
Application.DoEvents()
Loop
WebBrowser1.Navigate("javascript:function%20f(){document.forms[0]['q'].value='stackoverflow';}f();")
Threading.Thread.Sleep(2000) 'wait for javascript to run
WebBrowser1.Navigate("javascript:document.forms[0].submit()")
Threading.Thread.Sleep(2000) 'wait for javascript to run
如果你不等待,當然,它也不起作用。您最初瀏覽的URL被中斷。但有趣的是,您無法毫無延遲地執行javascript調用的「導航」。
所以我嘗試了兩種其他方法:使用DocumentCompleted事件等待瀏覽到嵌套URL,直到瀏覽器加載完頁面。不幸的是,DocumentCompleted並不總是觸發,並且在每個JavaScript URL之後似乎都不會觸發。
我試過的第二種方法是把等待在一個單獨的線程:
Private Delegate Sub SetTextDelegate(ByVal TheText As String)
Private Sub delSetText(ByVal TheText As String)
WebBrowser1.Navigate(TheText)
End Sub
Private Sub BrowseTo(ByVal URL As String)
If WebBrowser1.InvokeRequired Then
Me.BeginInvoke(New SetTextDelegate(AddressOf delSetText), URL)
Else
WebBrowser1.Navigate(URL)
End If
End Sub
Private Sub TargetURL()
BrowseTo("http://www.google.com")
End Sub
Private Sub TypeSomethingIn()
BrowseTo("javascript:function%20f(){document.forms[0]['g'].value='test';}f();")
End Sub
Private Sub SubmitForm()
BrowseTo("javascript:document.forms[0].submit()")
End Sub
Private Sub Wait()
While True
If WebBrowser1.ReadyState = WebBrowserReadyState.Complete Then Exit Sub
Threading.Thread.Sleep(100)
End While
End Sub
Private Sub AutoBrowse()
TargetURL()
Wait()
TypeSomethingIn()
Wait()
SubmitForm()
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim t As Threading.Thread
t = New Threading.Thread(AddressOf AutoBrowse)
t.Start()
End Sub
好奇的是,readyState的在等待循環檢查(或IsBusy,對於這個問題)有時會拋出一個InvalidCastException。大概要求這些不是線程安全的?我不知道。如果我把這個有問題的調用放在一個Try塊中,等待循環就無法工作。事實上,它甚至似乎是一個「堅持」的例外,因爲甚至通過try代碼塊Visual Studio凍結了10秒到20秒的時間(沒有try塊也是這樣)。
任何想法?