在不使用睡眠的情况下检测何时加载网页 [英] Detect when a web page is loaded without using sleep

查看:73
本文介绍了在不使用睡眠的情况下检测何时加载网页的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在Windows上创建一个VB脚本,该脚本在IE中打开一个站点。我想要的是:检测网页何时加载并显示一条消息。我通过使用sleep( WScript.Sleep )来实现这一点。网站加载的秒数。但是,站点在中途弹出用户名,密码。仅当用户输入凭据时,它才完成页面加载。因此,我不想在大约几秒钟内使用睡眠,而是要使用一种确切的功能或一种方法来检测页面是否已加载。我在线检查并尝试使用 Do While 循环, onload onclick 函数,但没有任何效果。为简化起见,即使我编写了一个脚本来打开雅虎之类的网站并进行检测,在加载页面时也会显示一条消息 Hi:如果不使用sleep,则无法正常工作( WScript.Sleep )。

I am creating a VB script on windows which opens a site in IE. What I want: Detect when the web page is loaded and display a message. I achieved this by using sleep (WScript.Sleep) for approx. seconds when the site gets loaded. However, the site pops up user name, password in the midway. Only when the user enter credentials, it finishes loading the page. So I don't want to use "sleep" for approx seconds, instead an exact function or a way to detect that the page got loaded. I checked on line and tried using Do While loop, onload, onclick functions, but nothing works. To simplify, even if I write a script to open a site like yahoo and detect, display a message "Hi" when the page is loaded: It doesn't work without using sleep (WScript.Sleep).

推荐答案

尝试常规方法:

Set objIE = CreateObject("InternetExplorer.Application")
objIE.Visible = True
objIE.Navigate "https://www.yahoo.com/"
Do While objIE.ReadyState <> 4
    WScript.Sleep 10
Loop
' your code here
' ...

UPD::这应该检查错误:

Set objIE = CreateObject("InternetExplorer.Application")
objIE.Visible = True
objIE.Navigate "https://www.yahoo.com/"
On Error Resume Next
Do 
    If objIE.ReadyState = 4 Then
        If Err = 0 Then
            Exit Do
        Else
            Err.Clear
        End If
    End If
    WScript.Sleep 10
Loop
On Error Goto 0
' your code here
' ...

UPD2:您写道,当登录弹出窗口进入时,IE断开连接,假设在那里是一种捕获断开连接,然后再次获取IE实例的方法。请注意,这是异常编程 :)希望对您有所帮助:

UPD2: You wrote that IE gets disconnected as the login pop-up comes in, hypothetically there is a way to catch disconnection, and then get IE instance again. Note this is "abnormal programming" :) I hope this helps:

Option Explicit
Dim objIE, strSignature, strInitType

Set objIE = CreateObject("InternetExplorer.Application") ' create IE instance
objIE.Visible = True
strSignature = Left(CreateObject("Scriptlet.TypeLib").GUID, 38) ' generate uid
objIE.putproperty "marker", strSignature ' tokenize the instance
strInitType = TypeName(objIE) ' get typename
objIE.Navigate "https://www.yahoo.com/"
MsgBox "Initial type = " & TypeName(objIE) ' for visualisation

On Error Resume Next
Do While TypeName(objIE) = strInitType ' wait until typename changes (ActveX disconnection), may cause error 800A000E if not within OERN
    WScript.Sleep 10
Loop
MsgBox "Changed type = " & TypeName(objIE) ' for visualisation

Set objIE = Nothing ' excessive statement, just for clearance
Do
    For Each objIE In CreateObject("Shell.Application").Windows ' loop through all explorer windows to find tokenized instance
        If objIE.getproperty("marker") = strSignature Then ' our instance found
            If TypeName(objIE) = strInitType Then Exit Do ' may be excessive type check
        End If
    Next
    WScript.Sleep 10
Loop
MsgBox "Found type = " & TypeName(objIE) ' for visualisation
On Error GoTo 0

Do While objIE.ReadyState <> 4 ' conventional wait if instance not ready
    WScript.Sleep 10
Loop

MsgBox "Title = " & objIE.Document.Title ' for visualisation

您可以从DOM获取所有文本节点,链接等,如下所示:

You can get all text nodes, links etc. from DOM, as follows:

Option Explicit
Dim objIE, colTags, strResult, objTag, objChild, arrResult

Set objIE = CreateObject("InternetExplorer.Application")
objIE.Visible = True
objIE.Navigate "https://www.yahoo.com/"

Do While objIE.ReadyState <> 4
    WScript.Sleep 10
Loop

Set colTags = objIE.Document.GetElementsByTagName("a")
strResult = "Total " & colTags.Length & " DOM Anchor Nodes:" & vbCrLf
For Each objTag In colTags
    strResult = strResult & objTag.GetAttribute("href") & vbCrLf
Next
ShowInNotepad strResult

Set colTags = objIE.Document.GetElementsByTagName("*")
arrResult = Array()
For Each objTag In colTags
    For Each objChild In objTag.ChildNodes
        If objChild.NodeType = 3 Then
            ReDim Preserve arrResult(UBound(arrResult) + 1)
            arrResult(UBound(arrResult)) = objChild.NodeValue
        End If
    Next
Next
strResult = "Total " & colTags.Length & " DOM object nodes + total " & UBound(arrResult) + 1 & " #text nodes:" & vbCrLf
strResult = strResult & Join(arrResult, vbCrLf)
ShowInNotepad strResult

objIE.Quit

Sub ShowInNotepad(strToFile)
    Dim strTempPath
    With CreateObject("Scripting.FileSystemObject")
        strTempPath = CreateObject("WScript.Shell").ExpandEnvironmentStrings("%TEMP%") & "\" & .gettempname
        With .CreateTextFile(strTempPath, True, True)
            .WriteLine (strToFile)
            .Close
        End With
        CreateObject("WScript.Shell").Run "notepad.exe " & strTempPath, 1, True
        .DeleteFile (strTempPath)
    End With
End Sub

也请查看获取文本数据

UPD3::我想在这里放置其他检查网页加载和初始化是否已完成:

UPD3: I want to place here additional check if webpage loading and initialization are completed:

' ...
' Navigating to some url
objIE.Navigate strUrl
' Wait for IE ready
Do While objIE.ReadyState <> 4 Or objIE.Busy
    WScript.Sleep 10
Loop
' Wait for document complete
Do While objIE.Document.ReadyState <> "complete"
    WScript.Sleep 10
Loop
' Processing loaded webpage code
' ...

UPD4:在某些情况下,您需要跟踪是否已在文档中创建目标节点(通常,如果得到<$ c尝试通过 .getElementById 等访问节点时,出现$ c>需要对象错误:

UPD4: There are some cases when you need to track if a target node have been created in the document (usually it's necessary if you get Object required error while attempting to access the node by .getElementById, etc.):

如果页面使用AJAX(加载的页面源HTML不包含目标节点,JavaScript等活动内容将动态创建它),则该页面的以下片段中提供了示例,展示了该示例的外观。文本节点 5.99 可能是在页面完全加载后创建的,并且已经向服务器发送了一些其他请求以显示额外的数据:

If the page uses AJAX (loaded page source HTML doesn't contain target node, active content like JavaScript creates it dynamically), there is the example in the below snippet of a page, showing how that could look like. The text node 5.99 might be created after the page was completely loaded, and some other requests to a server for extra data to be displayed have taken a place:

...
<td class="price-label">
    <span id="priceblock" class="price-big color">
        5.99
    </span>
</td>
...

或者如果您正在加载e。 G。出现Google搜索结果页面并等待 Next 按钮(特别是如果您调用了上一页的 .click 方法),或正在加载某些页面使用登录Web表单并等待用户名输入字段,例如< input name = userID id = userID type = text maxlength = 24 required = placeholder = Username autofocus =>

Or if you are loading e. g. Google search result page and waiting for Next button is appeared (especially, if you invoked .click method on the previous page), or loading some page with login web form and waiting for username input field like <input name="userID" id="userID" type="text" maxlength="24" required="" placeholder="Username" autofocus="">.

下面的代码允许对目标节点是否可访问进行附加检查:

The below code allows to make an additional check if the target node is accessible:

With objIE
    ' Navigating to some url
    .Navigate strUrl
    ' Wait for IE ready
    Do While .ReadyState <> 4 Or .Busy
        WScript.Sleep 10
    Loop
    ' Wait for document complete
    Do While .Document.ReadyState <> "complete"
        WScript.Sleep 10
    Loop
    ' Wait for target node created
    Do While TypeName(.Document.getElementById("userID")) = "Null"
        WScript.Sleep 10
    Loop
    ' Processing target node
    .Document.getElementById("userID").Value = "myusername"
    ' ...
    '
End With

这篇关于在不使用睡眠的情况下检测何时加载网页的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆