在不使用睡眠的情况下检测网页何时加载 [英] Detect when a web page is loaded without using sleep
问题描述
我正在 Windows 上创建一个 VB 脚本,它可以在 IE 中打开一个站点.我想要什么:检测网页何时加载并显示一条消息.我通过使用 sleep (WScript.Sleep
) 来实现这一点.网站加载时的秒数.但是,该站点在中途弹出用户名,密码.只有当用户输入凭据时,它才会完成加载页面.所以我不想在大约几秒钟内使用睡眠",而是使用精确的函数或检测页面是否已加载的方法.我在线检查并尝试使用 Do While
循环、onload
、onclick
功能,但没有任何效果.为简化起见,即使我编写了一个脚本来打开像 yahoo 这样的站点并进行检测,但在加载页面时会显示一条消息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
也看看 get文本数据
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: 在某些情况下,您需要跟踪是否在文档中创建了目标节点(通常,如果您在尝试时遇到 Object required
错误,则这是必要的)通过 .getElementById
等访问节点):
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.谷歌搜索结果页面并等待 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屋!