2010-07-18 81 views
14

Estoy usando el control WebBrowser en mi aplicación VB.NET para cargar algunas URL (~ 10-15) y guardar su fuente HTML en un archivo de texto. Sin embargo, mi código no escribe el origen de la página actual en lugar de la fuente inicial porque se desencadena incluso antes de que se cargue la página.¿Cómo esperar hasta que WebBrowser esté completamente cargado en VB.NET?

¿Cómo puedo esperar hasta que la página esté completamente cargada antes de llamar a un evento?

He intentado con el siguiente código pero no funciona.

Do Until WebBrowser1.ReadyState = WebBrowserReadyState.Complete 
    Application.DoEvents() 
Loop 
+1

Quiero saber eso también. ReadyState a menudo llega a 4 en el medio de la carga. Solo necesitamos saber cuándo está completo. Eso es todo. –

+0

@shubham si todavía tiene problemas con esto, hágamelo saber, ya que he desarrollado técnicas para resolver este problema a lo largo de los años, métodos que no se conocen y que no se han publicado.Este problema es el más importante y más difícil con todo el control WebBrowser. Lea algunos de mis mensajes recientes sobre el control del navegador web (he realizado muchos en los últimos días) y especialmente la publicación sobre las limitaciones del control de WB, que se encuentra en mi próximo comentario. Básicamente, he resuelto todos los problemas, si aún necesitas ayuda (ya que tu publicación es anterior) avísame y te puedo ayudar. –

+0

Mi explicación de las limitaciones del control de WB, encuentre mi respuesta aquí: http://stackoverflow.com/questions/1495944/webbrowser-control-limitations/9245591#9245591 –

Respuesta

7

Suena como que se desea capturar el evento DocumentCompleted de su control navegador web.

MSDN tiene un par de buenos artículos sobre el control WebBrowser - WebBrowser Class tiene un montón de ejemplos, y How to: Add Web Browser Capabilities to a Windows Forms Application

+0

En la declaración de WebBrowser sí estoy usando Private Sub WebBrowser1_DocumentCompleted ¿Cómo puedo poner en práctica lo que sucede cuando la página se ha cargado completamente en el interior del declarion del navegador web? – Shubham

+0

@Shubham: http://msdn.microsoft.com/en-us/library/k2kt7a7y.aspx (MSDN: "Cómo: Escribir controladores de eventos"), o eche un vistazo al ejemplo de Hans. No olvide la palabra clave 'Handles' al final de la declaración del método. – Heinzi

+0

** Espera ... ** Déjame sugerirte un ejemplo preciso de 'DocumentCompleted' desde mi punto de vista (mira mi respuesta) – JCM

19

Salvete! Necesitaba, simplemente, una función que podía llamar para que el código esperara a que la página se cargara antes de continuar. Después de buscar en la web respuestas y juguetear durante varias horas, se me ocurrió esto para resolver por mí mismo el dilema exacto que presentas. Sé que llego tarde al juego con una respuesta, pero deseo publicar esto para cualquier otra persona que aparezca.

uso: a llamarlo WaitForPageLoad() justo después de una llamada a la navegación

whatbrowser.Navigate("http://www.google.com") 
WaitForPageLoad() 

otro ejemplo no combinamos la función de navegar con la carga de la página, ya que a veces hay que esperar para una carga sin navegar también, por ejemplo, es posible que tenga que esperar que se cargue una página que se inició con un evento invokemember

whatbrowser.Document.GetElementById("UserName").InnerText = whatusername 
whatbrowser.Document.GetElementById("Password").InnerText = whatpassword 
whatbrowser.Document.GetElementById("LoginButton").InvokeMember("click") 
WaitForPageLoad() 

Aquí está el código: Necesita dos subs más la variable accesible, pageready. En primer lugar, asegúrese de fijar la variable llamada whatbrowser ser su control WebBrowser

Ahora, en algún lugar de su módulo o clase, colocar esto:

Private Property pageready As Boolean = False 

#Region "Page Loading Functions" 
    Private Sub WaitForPageLoad() 
     AddHandler whatbrowser.DocumentCompleted, New WebBrowserDocumentCompletedEventHandler(AddressOf PageWaiter) 
     While Not pageready 
      Application.DoEvents() 
     End While 
     pageready = False 
    End Sub 

    Private Sub PageWaiter(ByVal sender As Object, ByVal e As WebBrowserDocumentCompletedEventArgs) 
     If whatbrowser.ReadyState = WebBrowserReadyState.Complete Then 
      pageready = True 
      RemoveHandler whatbrowser.DocumentCompleted, New WebBrowserDocumentCompletedEventHandler(AddressOf PageWaiter) 
     End If 
    End Sub 

#End Region 
+2

He usado tu código para implementar la solución C# aquí http://stackoverflow.com/questions/11845123/fatal-execution-error-on-browser-readystate/13497611 # 13497611 ¡Gracias! –

+2

¡De nada! Me alegro de que ayudó a alguien. – bgmCoder

+2

He encontrado que esta es una de las publicaciones más útiles. – MonkeyDoug

3

Técnicamente, hay dos problemas con el código publicado por BGM:

  1. la adición de los controladores en el método WaitForPageLoad es posiblemente demasiado tarde. La navegación se inicia antes de que se agreguen los controladores, lo que significa que en casos muy raros donde el navegador ya tiene la página puede completarse antes de que se agreguen los controladores, en cuyo caso se perderá el evento y se quedará esperando por siempre.

    La solución es añadir los controladores antes de que comience la navegación y eliminarlos después de la navegación completó

    Esto significa que el método WaitForPageLoad necesita ser dividido en dos métodos. Se llama a uno antes de iniciar la navegación. Debería configurar los controladores. La segunda parte hace la supervisión ReadyState y se limpia cuando está 'Listo'.

  2. buenas prácticas de programación es añadir un tiempo de espera para que un explorador perdido (o se haya estrellado, o bucle) no hace que su código de esperar por siempre para el documento completo, incluso

+0

¡Hola! Bueno, estaba intentando hacer una función que esencialmente "esperaría tanto como fuera necesario, si fuera necesario". Sin embargo, creo que tienes razón, es posible (rara vez) que la página termine de cargarse antes de que se agreguen los controladores. Todavía no lo he experimentado, pero es posible que eso suceda. +1 – bgmCoder

1

Luché con esta " totalmente cargado 'problema durante algún tiempo, pero encontró que la siguiente solución funcionó para mí. Estoy usando IE7, así que no estoy seguro de si esto funciona en otras versiones, pero vale la pena echarle un vistazo.

Dividí el problema en dos partes; primero necesitaba un mensaje del evento DocumentComplete;

Private Sub WebBrowser1_DocumentComplete(ByVal pDisp As Object, URL As Variant) 
    fullyLoaded = True 
End Sub 

Luego, en la parte del código donde tengo que esperar hasta que la página web se haya cargado por completo, llamo a otro sub que hace esto;

Private Sub holdBrowserPage() 
    fullyLoaded = False 
    Do While fullyLoaded = False 
     DoEvents 
    Loop 
    fullyLoaded = False 
End Sub 

Además, también tuve que hacer lo mismo mientras esperaba que se completara el código de JavaScript. Por ejemplo, en una página cuando seleccionas un elemento de una lista desplegable html, llenó la siguiente lista desplegable, pero tardó un poco en revelarse. En esa instancia encontré llamar esto;

Private Sub holdBrowser() 
Do While WebBrowser1.Busy Or WebBrowser1.ReadyState <> READYSTATE_COMPLETE 
    DoEvents 
Loop 
End Sub 

era suficiente para mantener el navegador. No estoy seguro de si esto ayudará a todos, ya que una combinación de IE7, el sitio web que estaba cargando y el javascript que la página estaba ejecutando solo podría haber permitido esta solución, pero ciertamente vale la pena intentarlo.

1

En los eventos de carga, use Me.Hide.

En WebBrowser1.DocuementCompleted, utilice Me.Show

0

En realidad es muy fácil, intente esto:

While WebBrowser1.ReadyState <> WebBrowserReadyState.Complete 
    Application.DoEvents() 
End While 
0

hice función similar (sólo que trabaja para mí) - lo siento es en C#, pero fácil de traducir ...

private void WaitForPageLoad () { 
while (pageReady == false) 
    Application.DoEvents(); 

    while (webBrowser1.IsBusy || webBrowser1.ReadyState != WebBrowserReadyState.Complete) 
    Application.DoEvents(); 
} 
1

Espera ...

Desde mi experiencia, DEBE asegurarse de que el DocumCompleted pertenece a SU URL y no a una subpágina de marco, guión, imagen, CSS, etc. Y eso sin importar que el IsBusy o el ReadyState hayan terminado o no, lo que a menudo son inexactos cuando la página es un poco compleja.

Bueno, esa es mi propia experiencia personal, en un programa de trabajo de VB.2013 e IE11. Permítanme mencionar también que debe tener en cuenta también el modo de compatibilidad IE7 que está activado por defecto en el webBrowser1.

' Page, sub-frame or resource was totally loaded. 
Private Sub webBrowser1_DocumentCompleted(sender As Object, _ 
    e As WebBrowserDocumentCompletedEventArgs) _ 
    Handles webBrowser1.DocumentCompleted 

    ' Check if finally the full page was loaded (inc. sub-frames, javascripts, etc) 
    If e.Url.ToString = webBrowser1.Url.ToString Then 
     ' Only now you are sure! 
     fullyLoaded = True 
    End If 

End Sub 
1

Algunas veces si utiliza JavaScript caso DocumentComplet no devuelven la respuesta correcta, que utiliza el evento ProgressChanged

Private Sub WebBrowser1_ProgressChanged(sender As Object, e As WebBrowserProgressChangedEventArgs) _ 
Handles WebBrowser1.ProgressChanged 

    Console.WriteLine("CurrentProgress: " + e.CurrentProgress.ToString) 
    If e.CurrentProgress = e.MaximumProgress Then 
     'The maximun progres is reached 
     load_stated = True 
    End If 
    'The page is confirmed downloaded after the pregres return to 0 
    If e.CurrentProgress = 0 Then 
     If load_stated Then 
      'the page is ready to print or download... 
      WebBrowser1.Print() 
      load_stated = False 
     End If 
    End If 
End Sub 
Cuestiones relacionadas