我正在使用建议作为我的另一个问题(Automate website log-in and form filling?)的答案的方法,并注意到一些好奇的东西。
上述问题的答案是使用一系列javascript调用作为URL来填写网络表单并提交。我一直试图在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事件等待浏览到nest 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
奇怪的是,在wait循环中检查ReadyState(或IsBusy)有时会抛出InvalidCastException。据推测这些不是线程安全的吗?我不知道。如果我将违规调用置于Try块中,则等待循环无法正常工作。事实上,甚至看起来异常“坚持”将一切都搞砸了,因为即使使用try块Visual Studio踩踏代码也会冻结好10到20秒(没有try块也会这样做)。
有什么想法吗?
答案 0 :(得分:4)
我经历过的最有趣的问题之一,对我而言 无法在inet中找到解决方案 - 与之相关的问题 WebBrowser控件。问题是当我试图访问时 我正在获取WebBrowser控件实例的Document属性 “无效的强制转换异常”。问题是WebBrowser控件是 旨在在一个线程中工作。所以要解决这个问题,你必须只检查 InvokeRequired属性,如果值为true,则调用逻辑 来自委托,提供给browser.Invoke(...)方法。
答案 1 :(得分:1)
关注msdn文章:“控件上有四种方法可以线程安全地调用:Invoke,BeginInvoke,EndInvoke和CreateGraphics以及InvokeRequired属性”
因此,在Sub Wait中调用WebBrowser1.ReadyState不是线程安全的