3

我已经搜索了有关 WebBrowser DocumentCompleted 事件的其他问题,但似乎没有人遇到我遇到的确切问题。

我正在尝试在航空公司网站上自动搜索航班。我使用的第一个 url 每次都是相同的,除了日期部分,所以很容易让 WebBrowser 通过组合字符串来访问 URL。但是,该页面是一个免责声明页面,其中包含一个“继续”按钮,需要在显示价格之前单击该按钮。如果我在表单上使用一系列按钮,我可以通过单击 button1 来访问第一个 URL,然后通过单击 button2 来单击继续按钮。它工作正常。

但是,我想消除单击 button2 的需要,因此尝试使用 WebBrowser DocumentCompleted 事件。我遇到的问题是第一页似乎永远不会完全加载到网络浏览器中,因此永远不会单击该按钮。

这是我用于两个按钮和 DocumentCompleted 事件的代码

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

    TextBox1.Text = fullURL
    WebBrowser1.Navigate(fullURL)

    End Sub


    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click

    Dim allElements As HtmlElementCollection = WebBrowser1.Document.All

    For Each webpageelement As HtmlElement In allElements

        If webpageelement.GetAttribute("src") = proceedbuttonattribute Then

            webpageelement.InvokeMember("click")

        End If

    Next

    End Sub

Private Sub WebBrowser1_DocumentCompleted(ByVal sender As System.Object, ByVal e As System.Windows.Forms.WebBrowserDocumentCompletedEventArgs) Handles WebBrowser1.DocumentCompleted

    If TextBox1.Text.StartsWith(firstURL) = True Then 'make sure that button is only clicked after first webpage loads

        Dim allElements As HtmlElementCollection = WebBrowser1.Document.All

        'Click 'Proceed to Booking' button
        For Each webpageelement As HtmlElement In allElements

            If webpageelement.GetAttribute("src") = proceedbuttonattribute Then

                webpageelement.InvokeMember("click")

            End If

        Next

    End If

    End Sub

谢谢!

4

2 回答 2

3
WebBrowser1.Navigate(fullURL)
    Do While wb.ReadyState <> WebBrowserReadyState.Complete
        Application.DoEvents()

    Loop

;)

于 2012-09-25T14:14:34.403 回答
1

当您说 DocumentCompleted 从未被触发时,您是说它根本没有被触发,还是您说 If 语句可能没有返回 True,因此内容(和单击操作)没有运行?

此外,此页面上是否有任何框架或 iframe?因为,如果有,DocumentCompleted 将在每个单独的帧都加载并完成之前运行,如果它是一个 ajaxed 帧,那么这将引入 mroe 问题。只需要其中一个帧无法正确加载或保持在“交互”模式(其中 .readystate = 3)而不是完全正确加载(其中 .readystate = 4),这将阻止 DocumentCompleted 事件被触发。

另外,您要等待 DC 事件触发多长时间?

有一个更好的方法解决这个问题,您需要做的就是运行一个 Do/While 循环,使用与 DC 事件中完全相同的代码,它会坐在那里(在调用 .Navigate2 之后)并等到该按钮显示在 DOM 中,一旦以下返回 True,您就可以使用 .InvokeMember 并单击该按钮。

If webpageelement.GetAttribute("src") = proceedbuttonattribute Then

因此,在这种情况下,您将创建另一个名为“WaitUntilButtonFound”的函数,并可能在每个循环之间放置一个 100 毫秒的睡眠(等待),并在睡眠方法(也可以找到)之后或之前放置一个 .DoEvents(在 .Threading 命名空间中)在 .Threading 我认为)。

这样,当文档对象模型中出现相关按钮时,您可以单击它,如果需要,一旦找到,您可以再等待 2-3 秒(如果需要,不需要)然后单击它。因为在 DOM 中找到该按钮表明页面已加载或部分加载(相关或必要部分已完成加载),因此您可以恢复您想要对该按钮执行的操作(即,单击它),就在它出现之后。事实上,这也是最快的前进方式。

你怎么看?如果您需要更多帮助或指导,请告诉我您的情况。此外,如果您可以让我们知道 DC 事件是否绝对没有被触发,或者只是您的 IF 语句阻止 DC 在 DC 事件中运行代码,那将很有帮助,因为如果 DC 事件正在触发但内部的代码由于其中的 If 语句而没有运行,这与 DC 完全不同,甚至根本没有被触发。

让我们知道,谢谢。

于 2012-09-13T14:18:22.487 回答