webbrowser自动导航事件

时间:2017-11-29 19:11:31

标签: vb.net webbrowser-control

我正在使用webbrowser导航到一个网站,然后自动登录。一切都完美无缺,直到评论“导航事件”为止。输入一个凭证后,它将登录并导航到另一个网站。事件发生后,没有任何代码可以正常工作,因为它没有拿起新网站。我正在使用waitforpageload()函数让我知道它何时完成加载但是当我检查url时它仍然指向原始站点。任何想法为什么会这样做以及如何绕过它?

    Private Property pageready As Boolean = False

    webBrowser1.Navigate("https://www.lamedicaid.com/sprovweb1/provider_login/provider_login.asp")
            waitforpageload()

    Dim allelements As HtmlElementCollection = webBrowser1.Document.All
            For Each webpageelement As HtmlElement In allelements
                'NPI #
                If webpageelement.GetAttribute("name") = "Provider_Id" Then
                    webpageelement.SetAttribute("value", "xxxxxx")
                End If
                'Clicking enter to input NPI
                If webpageelement.GetAttribute("name") = "submit1" Then
                    webpageelement.InvokeMember("focus")
                    webpageelement.InvokeMember("click")
                    waitforpageload()
                End If

                'Navigation event happens here

                'Entering username
                If webpageelement.GetAttribute("name") = "Login_Id" Then
                    webpageelement.SetAttribute("value", "xxxxxxx")
                End If
                'Entering Password
                If webpageelement.GetAttribute("name") = "Password" Then
                    webpageelement.SetAttribute("value", "xxxxxxxxx")
                End If
                'logging in
                If webpageelement.GetAttribute("name") = "submit_button" Then
                    webpageelement.InvokeMember("focus")
                    webpageelement.InvokeMember("click")
                    waitforpageload()
                End If




    #Region "Page Loading Functions"
    Private Sub waitforpageload()
        AddHandler webBrowser1.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 webBrowser1.ReadyState = WebBrowserReadyState.Complete Then
            pageready = True
            RemoveHandler webBrowser1.DocumentCompleted, New WebBrowserDocumentCompletedEventHandler(AddressOf PageWaiter)
        End If
    End Sub
#End Region

1 个答案:

答案 0 :(得分:2)

请为了上帝的爱, 摆脱waitforpageload()功能 !使用Application.DoEvents() BAD PRACTICE ,在这样的循环中,将使用100%的CPU!

最初编写该功能的人(来自另一个Stack Overflow帖子)显然不知道他/她当时在做什么。使用Application.DoEvents()会产生比解决的问题更多的问题, NEVER 应该在任何人的代码中使用(它的存在主要是因为内部方法使用它)。

有关详细信息,请参阅:Keeping your UI Responsive and the Dangers of Application.DoEvents

每次页面(或页面的一部分,例如iframe)完全加载时,WebBrowser都会有一个专用的DocumentCompleted event

要确保页面确实已完全加载,请订阅DocumentCompleted事件并检查ReadyState property是否等于WebBrowserReadyState.Complete

能够更多地运行代码"动态地"引发DocumentCompleted事件时,您可以使用lambda expressions作为创建内联方法的方法。

在你的情况下,他们可以像这样使用:

'Second step (these must always be in descending order since the first step must be able to reference the second, and so on).
Dim credentialHandler As WebBrowserDocumentCompletedEventHandler = _
    Sub(wsender As Object, we As WebBrowserDocumentCompletedEventArgs)
        'If the WebBrowser HASN'T finished loading, do not continue.
        If webBrowser1.ReadyState <> WebBrowserReadyState.Complete Then Return

        'Remove the event handler to avoid this code being called twice.
        RemoveHandler webBrowser1.DocumentCompleted, credentialHandler

        'Entering username
        If webpageelement.GetAttribute("name") = "Login_Id" Then
            webpageelement.SetAttribute("value", "xxxxxxx")
        End If

        'Entering Password
        If webpageelement.GetAttribute("name") = "Password" Then
            webpageelement.SetAttribute("value", "xxxxxxxxx")
        End If

        'logging in
        If webpageelement.GetAttribute("name") = "submit_button" Then
            webpageelement.InvokeMember("focus")
            webpageelement.InvokeMember("click")
        End If
    End Sub


'First step.
Dim loginHandler As WebBrowserDocumentCompletedEventHandler = _
    Sub(wsender As Object, we As WebBrowserDocumentCompletedEventArgs)
        'If the WebBrowser hasn't finished loading, do not continue.
        If webBrowser1.ReadyState <> WebBrowserReadyState.Complete Then Return

        'Remove the event handler to avoid this code being called twice.
        RemoveHandler webBrowser1.DocumentCompleted, loginHandler

        Dim allelements As HtmlElementCollection = webBrowser1.Document.All
        For Each webpageelement As HtmlElement In allelements
            'NPI #
            If webpageelement.GetAttribute("name") = "Provider_Id" Then
                webpageelement.SetAttribute("value", "xxxxxx")
                '-- Why would you even wait in here?? There's no reason for you to wait after only changing an attribute since nothing is loaded from the internet.
            End If

            'Clicking enter to input NPI
            If webpageelement.GetAttribute("name") = "submit1" Then

                'Adding the event handler performing our next step.
                AddHandler webBrowser1.DocumentCompleted, credentialHandler

                webpageelement.InvokeMember("focus")
                webpageelement.InvokeMember("click")
            End If
        Next
    End Sub

'Add the event handler performing our first step.
AddHandler webBrowser1.DocumentCompleted, loginHandler

webBrowser1.Navigate("https://www.lamedicaid.com/sprovweb1/provider_login/provider_login.asp")

现在,每当您需要等待文档/网站完全加载时,只需声明一个新的lambda并将其作为事件处理程序添加到DocumentCompleted

Dim thirdStepHandler As WebBrowserDocumentCompletedEventHandler = _
    Sub(wsender As Object, we As WebBrowserDocumentCompletedEventArgs)
        'If the WebBrowser hasn't finished loading, do not continue.
        If webBrowser1.ReadyState <> WebBrowserReadyState.Complete Then Return

        'Remove the event handler to avoid this code being called twice.
        RemoveHandler webBrowser1.DocumentCompleted, thirdStepHandler

        'Your goes code here...
    End Sub


'To wait until performing the next step (be sure to do this BEFORE navigating):
AddHandler webBrowser1.DocumentCompleted, thirdStepHandler
相关问题