Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Username: Password: oppure
C# / VB.NET - [C#] aspettare caricamento pagina
Forum - C# / VB.NET - [C#] aspettare caricamento pagina

Avatar
Metal (Normal User)
Newbie


Messaggi: 16
Iscritto: 04/04/2011

Segnala al moderatore
Postato alle 21:47
Giovedì, 18/08/2011
Sono ancora qui con sto bot.

Posto il codice che uso per fare il login (funzionante, il login lo fa), così si capisce meglio:
Codice sorgente - presumibilmente C++

  1. private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
  2.         {
  3.             if (stage == 0)
  4.             {
  5.                 webBrowser1.Navigate("indirizzo1");
  6.  
  7.                 txtState.Text = "State " + stage;
  8.                 stage++;
  9.             }
  10.             else if (stage == 1)
  11.             {
  12.                 webBrowser1.Document.GetElementById("contact_username").SetAttribute("value", txtUser.Text);
  13.                 webBrowser1.Document.GetElementById("contact_password").SetAttribute("value", txtPass.Text);
  14.  
  15.                 HtmlElementCollection allElements = webBrowser1.Document.All;
  16.  
  17.                 foreach (HtmlElement webPageElement in allElements)
  18.                 {
  19.                     if (webPageElement.GetAttribute("value") == "Login")
  20.                         webPageElement.InvokeMember("click");
  21.                 }
  22.                
  23.                 txtState.Text = "State " + stage;
  24.                 stage++;
  25.             }
  26.             else if (stage == 2)
  27.             {
  28.                 webBrowser1.Navigate("indirizzo2");
  29.                
  30.                 txtState.Text = "State " + stage;
  31.                 stage++;
  32.             }
  33.             else if (stage == 3)
  34.             {
  35.                 webBrowser1.Navigate("indirizzo3");
  36.                
  37.                 txtState.Text = "State " + stage;
  38.                 stage++;
  39.             }
  40.             else if (stage == 4)
  41.             {
  42.                 oBot.WriteToTxt(webBrowser1.DocumentText);
  43.  
  44.                 txtState.Text = "State " + stage;
  45.                 stage++;
  46.             }
  47. }



indirizzo1 = pagina di login
indirizzo2 = dopo il login, devo navigare a questo indirizzo (finita di caricare la pagina, l'url diventa indirizzo2.5)
indirizzo3 = pagina della quale mi serve il sorgente
WriteToTxt = funzione che mi crea sul desktop un file di testo contenente il sorgente della pagina

Il problema è che nel file che mi crea sul desktop c'è il sorgente della pagina "indirizzo2.5" anziché quello della pagina "indirizzo3". E' come se non aspettasse il caricamento della pagina "indirizzo3" prima di eseguire lo stage == 4

Ho provato anche a mettere il tutto in una funzione separata, chiamata dalla pressione di un bottone nella GUI, fatta così:
Codice sorgente - presumibilmente C#

  1. web.Navigate("indirizzo1");
  2.             while (web.ReadyState != WebBrowserReadyState.Complete)
  3.                 Application.DoEvents();
  4.  
  5.             web.Document.GetElementById("contact_username").SetAttribute("value", user.Text);
  6.             web.Document.GetElementById("contact_password").SetAttribute("value", pass.Text);
  7.  
  8.             HtmlElementCollection allElements = web.Document.All;
  9.  
  10.             foreach (HtmlElement webPageElement in allElements)
  11.             {
  12.                 if (webPageElement.GetAttribute("value") == "Login")
  13.                     webPageElement.InvokeMember("click");
  14.             }
  15.             while (web.ReadyState != WebBrowserReadyState.Complete)
  16.                 Application.DoEvents();
  17.  
  18.             web.Navigate("indirizzo2");
  19.             while (web.ReadyState != WebBrowserReadyState.Complete)
  20.                 Application.DoEvents();
  21.  
  22.             web.Navigate("indirizzo3");
  23.             while (web.ReadyState != WebBrowserReadyState.Complete)
  24.                 Application.DoEvents();
  25.             oBot.WriteToTxt(webBrowser1.DocumentText);



ma il risultato non è cambiato...

Ultima modifica effettuata da Metal il 18/08/2011 alle 21:51
PM
Avatar
()
Newbie


Messaggi:
Iscritto:

Up
1
Down
V
Segnala al moderatore
Postato alle 19:24
Venerdì, 19/08/2011
Semplicemente perché prima di cambiare pagina il controllo si muove su about:blank e quindi sfasa completamente l'ordine che volevi.

Potresti risolvere mettendo un if su WebBrowserDocumentCompletedEventArgs.Url (e.Url nel tuo caso).
Questa proprietà restituisce l'URL dove si trova al momento il browser, quindi puoi evitare di appoggiarti su stage.

@Qwertj considerando un caso dove il tuo snippet sia utile, non sarebbe meglio scrivere un Do Until Loop rispetto al Do Loop Until?

Ultima modifica effettuata da il 19/08/2011 alle 20:02
e' difficile che carichi una pagina completamente in meno di 100ms - Qwertj - 19/08/11 20:17
ma non dovrebbe essere uguale? Il programma parte, viene invocata la DocumentCompleted perché il browser carica about:blank, e inizia a navigare per i vari link. Comunque proverò a usare e.Url - Metal - 19/08/11 20:47
perchè sarebbe una perdita di tempo scusa? .-. - Qwertj - 19/08/11 21:30
ah ._. avevo capito, ma mi sembrava assurdo e quindi ho preferito far finta di non aver capito. Giusto perché sono curioso, perché mai dovrebbe passare da about:blank ogni volta che uso navigate? Se non me lo dicevi tu, non ci sarei mai arrivato. Su mdsn non ne parla... - Metal - 19/08/11 21:52
Si ma se non lo eviterai mai il problema non sussiste. E se proprio capitasse che fa la pausa, di sicuro non sono 100ms che ne riducono le prestazioni irrimediabilmente, anzi, se proprio danno un po' di respiro - Qwertj - 19/08/11 23:18
Se non ci metterà mai meno di 100ms, che tu metta la condizione sopra o sotto rimane uguale - Qwertj - 20/08/11 10:07
ok va bene, hai ragione - Qwertj - 20/08/11 10:16
mi potete confermare che usare e.Url oppure webBrowser1.Url è uguale? Perché così posso creare una funzione per il login che viene richiamata al click di un bottone (in questo caso, non avrei idea di come passare WebBrowserDocumentCompletedEventArgs alla funzione...) - Metal - 20/08/11 16:59
PM
Avatar
Qwertj (Dev Team)
Guru


Messaggi: 678
Iscritto: 30/05/2011

Up
0
Down
V
Segnala al moderatore
Postato alle 9:12
Venerdì, 19/08/2011
Devi aspettare il caricamento della pagina in un ciclo Do-Loop da cui esci in caso di caricamento che puoi verificare con la proprietà ReadyState di WebBrowser

Codice sorgente - presumibilmente C# / VB.NET

  1. Do
  2.     Threading.Thread.Sleep(100)   'per non appensatire
  3.     Application.DoEvents()            'il processo
  4. Loop Until WebBrowser1.ReadyState = WebBrowserReadyState.Complete


avevo provato anche questo, ma in un ciclo do...while (che dovrebbe essere uguale) e senza il thread.sleep. Il risultato era lo stesso. - Metal - 19/08/11 17:05
do while è il contrario, si ferma quando la condizione è falsa mentre questo si ferma quando è vera - Qwertj - 19/08/11 18:57
scusa, ho visto il sorgente e l'hai fatto equivalente - Qwertj - 19/08/11 18:58
PM