VBS万无一失的方法来检查网站是否已加载

时间:2014-11-25 13:22:49

标签: internet-explorer if-statement vbscript

我在加载网站的脚本时遇到了一些问题。基本上,它很难检测到网站何时被完全加载,然后它开始出错,因为它无法找到指定的对象。

有没有办法,而不是使用ie.readystate或ie.busy来检查网站是否已完全加载?在设置它之前,可能通过类似循环来检查对象是否在那里?

像:

For Each wnd In CreateObject("Shell.Application").Windows
  If InStr(1, wnd.FullName, "iexplore.exe", vbTextCompare) > 0 Then
    Set IE = wnd
    Exit For
  End If
 Next

IE.navigate2 "xxxx" 
 IE.Visible = 1   

Do Until IE.document.getElementByID("username").Value = "xxxx"

 Set Helem = IE.document.getElementByID("username") 
 Helem.Value = "xxxx"    
 Set Helem = IE.document.getElementByID("password")
 Helem.Value = "xxxx"   
 Set Helem = IE.document.forms("signupForm")
 Helem.Submit

Loop

ie.busy和ie.readystate(任何组合)在加载表单时似乎非常不稳定..

我可以使用wscript.sleep来确保网站完全加载,但执行之间的等待时间可能超过10秒或更多。

有什么想法吗? :)

编辑: 如要求:

我尝试过的一件事,就像有人声称他们成功地做到了这一点,如下:

Do while ie.readystate <> 4 wscript.sleep 200 Loop
Do while ie.busy wscript.sleep 200 Loop

另一个是:

Do while ie.readystate <> 4 wscript.sleep 200 Loop
Do Until ie.readystate = 4 wscript.sleep 200 Loop

当然也是单独尝试它们。

问题是,一旦网站被标记为已加载(readystate = 4),它就不会真正100%加载。所以当我尝试做的时候,例如:

 Set Helem = IE.document.getElementByID("username") 
Helem.Value = "xxxx" 

然后我会收到一个错误,因为它无法找到该对象。

2 个答案:

答案 0 :(得分:1)

根据我的经验,您需要检查3个就绪状态。

  1. InternetExplorer对象(ie.ReadyState = 4)
  2. 文件readystate(ie.document.readyState =“complete”)
  3. 并且它完全是万无一失的:

    1. 文档框架的readystate(如果页面有框架,这可能需要进行递归检查)
    2. 这是我用于此任务的VBA sub的VBScript改编。

      ' web page load timeout in 10ths of a second
      Const WAIT_TIMEOUT = 300
      Const ERR_TIMEOUT = 1000
      Const READYSTATE_COMPLETE = 4
      
      Sub WaitUntilLoaded(ie)
          Dim i, j, ready
      
          ' wait for page to connect
          i = 0
          Do Until ie.readyState = READYSTATE_COMPLETE
              WScript.Sleep 100
              i = i + 1
              If i > WAIT_TIMEOUT Then
                  Err.Raise ERR_TIMEOUT, , "Timeout"
              End If
          Loop
      
          ' wait for document to load
          Do Until ie.document.readyState = "complete"
              WScript.Sleep 100
              i = i + 1
              If i > WAIT_TIMEOUT Then
                  Err.Raise ERR_TIMEOUT, , "Timeout"
              End If
          Loop
      
          ' wait for frames to load
          Do
              ready = True
              For j = 0 To ie.document.frames.Length - 1
                  If ie.document.frames(j).document.readyState <> "complete" Then
                      ready = False
                      WScript.Sleep 100
                      i = i + 1
                      If i > WAIT_TIMEOUT Then
                          Err.Raise ERR_TIMEOUT, , "Timeout"
                      End If
                  End If
              Next
          Loop Until ready
      End Sub
      

答案 1 :(得分:0)

到目前为止,我能想到的最好的方法是下面的代码。它依靠捕获Internet Explorer的 DocumentComplete 事件来检测页面何时完全加载。

功能:

  • 脚本将等待所有元素加载,包括子框架,然后报告页面已加载。
  • 避免不必要的延迟等待检查各种属性,例如 使用睡眠 ReadyState
  • LoadPage函数具有超时安全功能,以防止 无限循环,可以调整。

享受:)

Option Explicit

'Sub Main
'--------
 Dim DocumentComplete
 Dim objIE : Set objIE = WScript.CreateObject("InternetExplorer.Application", "IE_")
 objIE.Visible = True

 If LoadPage("https://stackoverflow.com") Then
    MsgBox "LoadPage completed."
 Else
    MsgBox "LoadPage timed out."
 End If

 Function LoadPage(ByVal strURL) 'As Boolean
'-------------------------------------------
 Const TimeOut = 10 'Seconds
 Dim StartTime : StartTime = Now()
 DocumentComplete = False
 objIE.Navigate strURL

 Do While Not DocumentComplete
    WScript.Sleep(1)
    If DateDiff("s", StartTime, Now()) > TimeOut Then
       LoadPage = False
       Exit Function
    End If
 Loop

 LoadPage = True

End Function 'LoadPage

 Sub IE_DocumentComplete(pDisp, URL)
'-----------------------------------
' Fires when a document is completely loaded and initialized.
' https://docs.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/platform-apis/aa768282(v=vs.85)

 If (pDisp Is objIE) Then
    DocumentComplete = True
 End If

End Sub 'IE_DocumentComplete