【问题标题】:Excel VBA: Wait for JavaScript execution in Internet ExplorerExcel VBA:在 Internet Explorer 中等待 JavaScript 执行
【发布时间】:2012-10-13 08:11:59
【问题描述】:

我正在尝试在 Excel VBA 中进行一些网页抓取。这是我遇到问题的代码部分:

IE.Navigate URL
Do
  DoEvents
Loop While IE.ReadyState <> 4 Or IE.Busy = True
Set doc = IE.document

运行此doc 后,其中包含的 html 中仍有未执行的 JavaScript。 这是尚未执行的脚本的签名:

<SCRIPT type=text/javascript>
        goosSearchPage.Initialize(...)...;
</SCRIPT>

我可以通过 Application.Wait(Now + TimeValue(x)) 等待执行,但这确实不能令人满意,因为脚本执行所花费的时间根据输入而变化很大。

有没有办法等待脚本完成评估或直接在 doc 对象中评估脚本?

【问题讨论】:

  • 脚本运行的结果是否可以检查?是否创建了页面元素,或者填充了某些表单值? AFAIK 没有“scriptfinishedrunning”事件,因此您必须检查脚本的输出或结果。如果不知道脚本的作用,很难说更多。
  • 谢谢蒂姆,这是一个好主意,虽然我觉得自己没有想出它有点愚蠢。我将检查 SearchPage.Initialize 是否仍在正文中。

标签: excel internet-explorer vba automation


【解决方案1】:

我找到了等待页面完成的代码。根据注释 here,它需要 Microsoft Internet Controls 作为代码中的参考。

此处复制代码,以防链接失效:

'Following code goes into a sheet or thisworkbook class object module
Option Explicit

'Requires Microsoft Internet Controls Reference Library
Dim WithEvents ie As InternetExplorer
Sub start_here()
  Set ie = New InternetExplorer
  'Here I wanted to show the progress, so setting ie visible
  ie.Visible = True
  'First URL to go, next actions will be executed in
  'Webbrowser event sub procedure - DocumentComplete
  ie.Navigate "www.google.com"
End Sub
Private Sub ie_DocumentComplete(ByVal pDisp As Object, URL As Variant)
  'pDisp is returned explorer object in this event
  'pDisp.Document is HTMLDocument control that you can use
  'Following is a choice to follow,
  'since there is no do-loop, we have to know where we are by using some reference
  'for example I do check the URL and do the actions according to visited URL

  'In this sample, we use google entry page, set search terms, click on search button
  'and navigate to first found URL
  'First condition; after search is made
  'Second condition; search just begins
  If InStr(1, URL, "www.google.com/search?") > 0 Then
    'Open the first returned page
    ie.Navigate pDisp.Document.getelementsbytagname("ol")(0).Children(0).getelementsbytagname("a")(0).href
  ElseIf InStr(1, URL, "www.google.com") > 0 Then
    pDisp.Document.getelementsbyname("q")(0).Value = "VB WebBrowser DocumentComplete Event"
    pDisp.Document.getelementsbyname("btnG")(0).Click
  End If
End Sub

【讨论】:

  • 感谢肖恩的回答。不幸的是,这不起作用,因为当 READYSTATE 更改为 READYSTATE_COMPLETE (=4) 时会触发 DocumentComplete 事件,这正是我在解决方案中所做的。来源:link
  • 此解决方案也仅在浏览器的可见性设置设置为 true 时才有效,这在我的情况下是不可接受的。
【解决方案2】:

您实际上可以使用 ie 窗口评估 javascript 函数。但是您必须设置一个回调,因为该函数将被异步评估。

【讨论】:

    【解决方案3】:

    这篇文章已经很老了,但我也将回答这个问题作为对自己的回复,因为我已经发现了如何做到这一点。

    只需指向您希望在 jQuery 脚本运行后出现的内容,使用通过 IE 自动化运行的 JavaScript 触发所需的事件,然后执行循环以等待所需的内容出现。

    'This will trigger the jQuery event.
    Doc.parentWindow.execScript "$('#optionbox').trigger('change')"
    
    'This is the code that will make you wait. It's surprisingly efficient
    Do While InStrB(Doc.getElementById("optionbox").innerHTML, "<desired html tag>") = 0
        DoEvents
    Loop
    

    【讨论】:

      猜你喜欢
      • 2013-11-24
      • 2012-06-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多