Detecta cuando se carga una página web sin usar sleep

Estoy creando un script VB en Windows que abre un sitio en IE. Lo que quiero: detectar cuando la página web está cargada y mostrar un mensaje. Lo logré usando sleep ( WScript.Sleep ) durante aprox. segundos cuando el sitio se carga. Sin embargo, el sitio muestra el nombre de usuario, la contraseña a mitad de camino. Solo cuando el usuario ingresa las credenciales, termina de cargar la página. Así que no quiero usar “reposo” durante unos segundos, sino una función exacta o una forma de detectar que la página se cargó. Comprobé en línea e intenté usar las funciones Do While loop, onload , onclick , pero nada funciona. Para simplificar, incluso si escribo una secuencia de comandos para abrir un sitio como Yahoo y detectar, muestro un mensaje “Hola” cuando la página está cargada: No funciona sin usar sleep ( WScript.Sleep ).

    Pruebe el método convencional:

     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: este debería verificar si hay errores:

     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: Usted escribió que IE se desconecta cuando aparece la ventana emergente de inicio de sesión, hipotéticamente hay una forma de atrapar la desconexión y luego obtener la instancia de IE nuevamente. Tenga en cuenta que esto es “progtwigción anormal” 🙂 Espero que esto ayude:

     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 

    Puede obtener todos los nodos de texto, enlaces, etc. de DOM, de la siguiente manera:

     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 

    También busque obtener datos de texto

    UPD3: Quiero colocar aquí una verificación adicional si se completan la carga e inicialización de la página web:

     ' ... ' 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: hay algunos casos en los que necesita rastrear si se ha creado un nodo de destino en el documento (por lo general, es necesario si se Object required error Object required al intentar acceder al nodo mediante .getElementById , etc.):

    Si la página utiliza AJAX (el código fuente de la página cargada no contiene el nodo de destino, el contenido activo como JavaScript lo crea dinámicamente), hay un ejemplo en el siguiente fragmento de página, que muestra cómo podría verse. El nodo de texto 5.99 podría crearse después de que la página se haya cargado completamente, y algunas otras solicitudes a un servidor para que se muestren datos adicionales han ocupado un lugar:

     ...   5.99   ... 

    O si está cargando, por ejemplo, aparece la página de resultados de búsqueda de Google y espera el botón Siguiente (especialmente si invocó el método .click en la página anterior) o cargando una página con el formulario web de inicio de sesión y esperando el campo de entrada de nombre de usuario como .

    El siguiente código permite realizar una verificación adicional si el nodo objective es accesible:

     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