Attendre la fin du chargement de page dans un Webbrowser [Résolu]

Messages postés
301
Date d'inscription
mercredi 22 septembre 2010
Dernière intervention
27 février 2018
- - Dernière réponse : CLeBeR_FR
Messages postés
301
Date d'inscription
mercredi 22 septembre 2010
Dernière intervention
27 février 2018
- 11 sept. 2013 à 21:01
Bonjour,
je suis sur un projet en VisualBasic.NET mais je suis obligé de faire une partie du code en C# car j'utilise une API. J'ai crée un thread et je voudrais que le code attende que mon Webbrowser ai fini de charger la page pour passer à la ligne suivante. Je suis tombé sur beaucoup de sujets traitant mon problème, mais je dois avouer que je suis un peu perdu avec toutes ces accolades ... Je m'embrouille dans le code.
        public void analyse()
                       {
                           try
                           {
                               listBox1.SelectedIndex = listBox1.Items.Count - 1;
                               string DernierLien = listBox1.SelectedItem.ToString();
                               string correctString = DernierLien.Replace(":443", "");
                               webBrowser1.Navigate(correctString);
//Je voudrais que mon webbrowser attende à partir d'ici.
                               List<string> ListeMot = new List<string>();
                               string source = this.webBrowser1.DocumentText;
                               ListeMot.AddRange(System.IO.File.ReadAllLines("C:\\Users\\Clément\\Documents\\ListeDeMots.txt"));
                               foreach (string s in ListeMot)
                               {
                                   if (source.ToLower().Contains("" + s.ToLower() + ""))
                                       MessageBox.Show("Un mot interdit a été détecté :" + s);
                                   
                               }
                           }
                           catch
                           {
                               
                           
                           }
        }

Je vous remercie de votre aide.
Afficher la suite 

Votre réponse

6 réponses

Messages postés
4269
Date d'inscription
samedi 8 septembre 2007
Dernière intervention
29 août 2018
0
Merci
salut,

regarde du côté webbrowser.readystate :

http://msdn.microsoft.com/fr-fr/library/system.windows.forms.webbrowser.readystate(v=vs.85).aspx

par exemple :

while(WebBrowser.ReadyState != Completed)
{
Application.DoEvents();
}


ainsi que l'évenement "documentcomplete" de ton webbrowser.

un petit exemple (pour me connecter) :

  private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
  {
   
    if (webBrowser1.Document.All["Ecom_User_ID"] != null && webBrowser1.Document.All["Ecom_Password"] != null)
    {
     webBrowser1.Document.All["Ecom_User_ID"].InnerText = TxtUser.Text;
     webBrowser1.Document.All["Ecom_Password"].InnerText = TxtPass.Text;
     webBrowser1.Document.GetElementById("portletlogin").InvokeMember("click");
    }    
  }


-> je vérirife que mes champs existent, si oui je suis sur la page de log dont je remplis user+pass et j'appel l'événement click sur le bouton de post.

naga
Commenter la réponse de nagaD.scar
Messages postés
301
Date d'inscription
mercredi 22 septembre 2010
Dernière intervention
27 février 2018
0
Merci
Salut nagashima,
je vais utiliser l'évènement DocumentCompleted, cependant je voudrais savoir comment le déclencher depuis ma fonction "analyse". Au moins je n'aurai pas à faire en sorte que la page ai fini de charger ça se fera tout seul (du moins je pense !).
        void FiddlerApplication_AfterSessionComplete(Fiddler.Session oSession)
        {
            listBox1.Invoke(new UpdateUI(() =>
                {
                    listBox1.Items.Add(oSession.url);

                    System.Threading.Thread newThread;

                    newThread = new System.Threading.Thread(analyse);
                    newThread.Start();

                }));
        }


        public void analyse()
        {

 // APPELER LA FONCTION WEBBROWSER DOCUMENTCOMPLETED
        }


        public void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
        {

            try
            {
                string DernierLien = listBox1.SelectedItem.ToString();
                string correctString = DernierLien.Replace(":443", "");

                webBrowser1.Navigate(correctString);

                {

                    List<string> ListeMot = new List<string>();
                    string source = this.webBrowser1.DocumentText;
                    ListeMot.AddRange(System.IO.File.ReadAllLines("C:\\Users\\Clément\\Documents\\ListeDeMots.txt"));
                    foreach (string s in ListeMot)
                    {
                        if (source.ToLower().Contains("" + s.ToLower() + ""))
                            MessageBox.Show("Un mot interdit a été détecté :" + s);
                    }
                }

            }
            catch
            {


            }
        }
Commenter la réponse de CLeBeR_FR
Messages postés
4269
Date d'inscription
samedi 8 septembre 2007
Dernière intervention
29 août 2018
0
Merci
salut,
ce que tu demande est un peu ... incohérent :
l'évènement "documentcomplete" est appelé par ton webBrowser au moment ou une page à terminée de se charger. Donc appeler la fonction appelée par cet événement (pour toi : webBrowser1_DocumentCompleted) est, dans l'absolu, possible, mais aura un comportement auquel tu ne peux pas t'attendre (parfois tu fera l'appel de la fonction alors que le flux ne sera peu être pas amorcé, parfois le flux aura terminé de se charger => dans ce cas là ton webBowser déclenchera l'évènement "DocumentComplete" et tu fera 2 fois le traitement, ... il y a une infinité de possibilité).

Si le rôle de ta fonction analyse est par exemple d'analyser le contenu de ton webBrowser, c'est l'inverse que tu dois dois faire, c'est a dire appeler analyse depuis ton wb.
Dans le temps, voilà ce qui se passe (c'est totalement transparent pour toi, ton webBrowser est dans un thread que tu n'a pas besoin de gérer) :

appel d'un page dans le wb  
TANTQUE la page se charge 
        attendre
FINTANTQUE

déclencher évènement DocumentComplete 


Quand l'évènement est déclenché, ton application appelera la fonction que tu aura paramétré, c'est à dire : webBrowser1_DocumentCompleted. Il faut garder à l'esprit que webBrowser1_DocumentCompleted n'est qu'une fonction, le webBrowser en dépend mais pas l'inverse.

C'est un peu difficile d'expliquer, mais ce qu'il faut se dire c'est que un événement est une action effectué à un instant t, et la fonction appelée par cette événement est un traitement à faire dans le cas à l'événement se produit.

Demande si je suis pas clair ^^

naga
Commenter la réponse de nagaD.scar
Messages postés
301
Date d'inscription
mercredi 22 septembre 2010
Dernière intervention
27 février 2018
0
Merci
Oui j'ai compris, (je savais quand même un peu comment fonctionne le DocumentCompleted mais j'essaye toute les solutions car je suis vraiment bloqué ^^
J'ai suivi tes conseils et j'ai modifié le code :
   
void FiddlerApplication_AfterSessionComplete(Fiddler.Session oSession)
        {
            listBox1.Invoke(new UpdateUI(() =>
                {
                    listBox1.Items.Add(oSession.url);

                }));
        }
     public void analyse()
        {
            try
            {
                  listBox1.SelectedIndex = listBox1.Items.Count - 1;
               string DernierLien = listBox1.SelectedIndex.ToString();
                string correctString = DernierLien.Replace(":443", "");

                webBrowser1.Navigate(correctString);

                {

                    List<string> ListeMot = new List<string>();
                    string source = this.webBrowser1.DocumentText;
                    ListeMot.AddRange(System.IO.File.ReadAllLines("C:\\Users\\Clément\\Documents\\ListeDeMots.txt"));
                    foreach (string s in ListeMot)
                    {
                        if (source.ToLower().Contains("" + s.ToLower() + ""))
                            MessageBox.Show("Un mot interdit a été détecté :" + s);
                    }
                }
                            }
            catch
            {


            }
        }


        public void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
        {
            System.Threading.Thread newThread;

            newThread = new System.Threading.Thread(analyse);
            newThread.Start();

        }


Il faudrait une solution pour que à chaque nouvelle URL, le programme attende que le webbrowser ai fini de charger pour y aller, car en fait les URL se chargent très vite, et le webbrowser prend la dernière mais en ratent beaucoup car elle s'ajoutent plus vite que ce qu'il ne charge.
Merci de ton aide en tout cas !
nagaD.scar
Messages postés
4269
Date d'inscription
samedi 8 septembre 2007
Dernière intervention
29 août 2018
-
mais ces "chargements" sont fait à la suite d'appel que tu effectues non ?
Dans ce cas là tu peux utiliser "readystate" entre chaque appel (ou pour être sûr que lorsque tu veux appeler une page, ton wb ne soit pas déjà en train de charger => tu interromps le chargement, comme avec le navigateur, et donc tu "zappe" une page).

je te remets le code pour attendre :

while(webBrowser1.ReadyState != Completed)
{
Application.DoEvents();
}
CLeBeR_FR
Messages postés
301
Date d'inscription
mercredi 22 septembre 2010
Dernière intervention
27 février 2018
-
Salut,
non ces chargements se font tout seul en "temps réel", j'ai déjà essayé d'utiliser ton code mais je ne m'en sors pas. :/
Je pense que tant pis je vais abadonner cette fonction car je trouve très compliqué. C'est dommage car j'y suis presque il faut juste que j'arrive à stopper le webbrowser...
nagaD.scar
Messages postés
4269
Date d'inscription
samedi 8 septembre 2007
Dernière intervention
29 août 2018
-
salut !
tu peux essayer :
public void analyse()
                       {
                           try
                           {
                               listBox1.SelectedIndex = listBox1.Items.Count - 1;
                               string DernierLien = listBox1.SelectedItem.ToString();
                               string correctString = DernierLien.Replace(":443", "");
                               webBrowser1.Navigate(correctString);
//Je voudrais que mon webbrowser attende à partir d ici.
while(webBrowser1.ReadyState != Completed)
{
Application.DoEvents();
}
                               List<string> ListeMot = new List<string>();
                               string source = this.webBrowser1.DocumentText;
                               ListeMot.AddRange(System.IO.File.ReadAllLines("C:\\Users\\Clément\\Documents\\ListeDeMots.txt"));
                               foreach (string s in ListeMot)
                               {
                                   if (source.ToLower().Contains("" + s.ToLower() + ""))
                                       MessageBox.Show("Un mot interdit a été détecté :" + s);
                                   
                               }
                           }
                           catch
                           {
                               
                           
                           }
        }


de cette manière, ta fonction attendra que que le webbrowser soit "libre" (qu'il a fini son chargement, redirection etc.) avant de continuer le traitement.
La différence avec l'évènement est que l'évènement est appelé à chaque fin de chargement (c'est à dire qu'en cas de redirection, il est appelé 2 fois normalement : fin de chargement de la première, fin de chargement de la redirection).

Dis moi si tu essaye.
naga
Commenter la réponse de CLeBeR_FR
Messages postés
301
Date d'inscription
mercredi 22 septembre 2010
Dernière intervention
27 février 2018
0
Merci
Salut nagashima,
j'avais déjà essayé un code similaire, j'ai essayé le tiens mais il ne fonctionne pas non plus, ce n'est pas grave j'ai réussi à utiliser l'API Fiddler en VB.NET grâce au forum du site de Fiddler.
Je suis confronté au même problème en VB.NET, je vais essayer de le résoudre mais c'est beaucoup plus simple pour moi.
Voilà je te remercie pour l'aide, je reviendrai faire un petit bilan une fois que j'aurai terminé ;)
@+
CLeBeR_FR
Messages postés
301
Date d'inscription
mercredi 22 septembre 2010
Dernière intervention
27 février 2018
-
Salut nagashima,
comme prévu, je te fais un retour ! J'ai réussi !!!! :D
Voici le code VB.NET :
Option Explicit On
Imports Fiddler
Imports System.Net
Imports System.IO

Public Class Form1

    Dim url As String = Nothing

    Public Sub New()
        ' This call is required by the designer.
        InitializeComponent()
        ' Add any initialization after the InitializeComponent() call.
        AddHandler FiddlerApplication.BeforeResponse, AddressOf FiddlerBeforeResponseHandler
        AddHandler FiddlerApplication.BeforeRequest, AddressOf FiddlerBeforeRequestHandler
        AddHandler Application.ApplicationExit, AddressOf ShutdownFiddlerApp
        Dim oFlags As FiddlerCoreStartupFlags = FiddlerCoreStartupFlags.Default
        FiddlerApplication.Startup(0, oFlags)
        MsgBox("Started proxy on port " & FiddlerApplication.oProxy.ListenPort)
    End Sub

    Private Sub ShutdownFiddlerApp()
        FiddlerApplication.Shutdown()
        MsgBox("Unloaded proxy")
        Threading.Thread.Sleep(1000)
    End Sub

    Private Sub FiddlerBeforeRequestHandler(ByVal tSession As Session)
        RichTextBox1.BeginInvoke(New AsyncMethodCaller(AddressOf AddText), tSession.fullUrl)
    End Sub

    Private Sub FiddlerBeforeResponseHandler(ByVal tSession As Session)
    End Sub

    Public Sub Verification()
        Try
            ListeMot.AddRange(IO.File.ReadAllLines("C:UsersClémentDocumentsListeDeMots.txt"))
            Dim found As Boolean = False
            For Each s As String In ListeMot
                If url.ToLower.Contains("-" & s.ToLower & "-") Or url.ToLower.Contains("." & s.ToLower & ".") Or url.ToLower.Contains("." & s.ToLower & "-") Or url.ToLower.Contains("-" & s.ToLower & ".") Then
                    MsgBox("Un mot interdit dans l'URL a été détecté :" & s)
                End If
            Next
        Catch
        End Try
        Try
            Dim webClient As New System.Net.WebClient
            Dim result As String = webClient.DownloadString(url)
            Dim client As WebClient = New WebClient()
            Dim data As Stream = client.OpenRead(url)
            Dim reader As StreamReader = New StreamReader(data)
            Dim Page As String = reader.ReadToEnd
            ListeMot.AddRange(IO.File.ReadAllLines("C:UsersClémentDocumentsListeDeMots.txt"))
            Dim found As Boolean = False
            For Each s As String In ListeMot
                If Page.ToLower.Contains(" " & s.ToLower & " ") Then
                    MsgBox("Un mot interdit a été détecté :" & s)
                End If
            Next
        Catch
        End Try
    End Sub

    Dim ListeMot As New List(Of String)

    Private Sub AddText(sText As String)
        Dim url2 As Uri
        url2 = New Uri(sText)
        If url2.AbsolutePath.EndsWith(".js") = False And url2.AbsolutePath.EndsWith(".jpg") = False And url2.AbsolutePath.EndsWith(".gif") = False And url2.AbsolutePath.EndsWith(".png") = False And url2.AbsolutePath.EndsWith(".css") = False And url2.AbsolutePath.EndsWith(".ico") = False And url2.AbsolutePath.EndsWith(":443") = False Then
            RichTextBox1.AppendText(sText & vbCrLf)
            url = sText
            Dim Thread As New Threading.Thread(AddressOf Verification)
            Thread.Start()
        End If
    End Sub

    Protected Overrides Sub Finalize()
        MyBase.Finalize()
    End Sub
End Class

Public Delegate Sub AsyncMethodCaller(sText As String)
nagaD.scar
Messages postés
4269
Date d'inscription
samedi 8 septembre 2007
Dernière intervention
29 août 2018
-
salut !
Je m'était un peu documenté sur l'API de fidler, mais j'avoue ne pas avoir tout suivit ^^ (j'ai pas énormément de temps et dans mon utilisation ca ne semblerai pas m'être utile pour le moment).

Pour ton cas en fait tu recherches un mot contenu dans un stream (un flux web dans ton cas), et tu l'entoures d'espace pour délimiter le mot (si j'ai bien compris ^^). Si je peux me permettre, il faudrai que prenne aussi en compte d'autres éléments, comme par exemple si un mot interdit est entouré de balises, tu ne le captera pas, par exemple :

<h1>mot</h1>


Faut juste avoir en tête cela ^^ (pour la vérif, tu peux aussi t'appuyer sur les expression régulières ;] )

Si ca peu t'intéresser, j'ai surchargé la classe WebClient histoire de simplifier un peu la communication avec le serveur (en c#).

Bon dev et merci pour les infos !
naga
CLeBeR_FR
Messages postés
301
Date d'inscription
mercredi 22 septembre 2010
Dernière intervention
27 février 2018
-
Salut nagashima !
J'avais pensé aux balises, mais je dois avouer que je ne me suis pas penché sur le sujet, j'ai ajouté la détection même si le mot est entouré de balise. Si tu connais le HTML et que des mots peuvent être entourés dans d'autres balises, je suis preneur !
Je suis obligé de délimiter le mot car aussi non, il me détecte un mot dans un autre, par exemple le mot "plus" peut être détecté dans "plusieurs".
Que veux-tu dire par "expressions régulières" ?
Tu peux m'envoyer ta classe surchargée (même si je ne comprends pas trop le terme) ça peut me servir !
CLeBeR_FR
Messages postés
301
Date d'inscription
mercredi 22 septembre 2010
Dernière intervention
27 février 2018
-
PS: Je posterai encore mon code modifié car je suis en train de le modifier afin de l'optimiser, et il faut surtout que je trouve un moyen de filtrer les URL's des vidéos car c'est un flux qui arrive en masse et me fait planter le programme.
nagaD.scar
Messages postés
4269
Date d'inscription
samedi 8 septembre 2007
Dernière intervention
29 août 2018
-
tu peux trouver la source ici :

http://codes-sources.commentcamarche.net/forum/affich-10005114-surcharge-webclient-simplification#p10005162

à savoir que je n'ai pas respecté la convention de code qui est de commencer le nom d'une classe par une majuscule.

Pour les expressions régulières, regarde ici :
http://msdn.microsoft.com/fr-fr/library/system.text.regularexpressions.regex.aspx

Pour tester tes expressions régulières, regarde ici :
http://www.myregextester.com/

tu as des options pour afficher le code c# par exemple.

bon dev.
naga
Commenter la réponse de CLeBeR_FR
Messages postés
301
Date d'inscription
mercredi 22 septembre 2010
Dernière intervention
27 février 2018
0
Merci
Bonjour,

j'ai optimisé encore une fois le code, le programme plantait lors de la lecture de vidéos, trop grand nombre d'URLs...
Option Explicit On
Imports Fiddler
Imports System.Net
Imports System.IO
Imports Microsoft.Win32

Public Class Form1

    Dim ListeMots As New List(Of String)
    Dim url As String = Nothing
    Public Delegate Sub AsyncMethodCaller(sText As String)

   

    Private Sub ShutdownFiddlerApp()
        FiddlerApplication.Shutdown()
        MsgBox("Unloaded proxy")
        Threading.Thread.Sleep(1000)
    End Sub

    Private Sub FiddlerBeforeRequestHandler(ByVal tSession As Session)
        RichTextBox1.BeginInvoke(New AsyncMethodCaller(AddressOf AddText), tSession.fullUrl)
    End Sub

    Private Sub FiddlerBeforeResponseHandler(ByVal tSession As Session)
    End Sub

    Public Sub VerificationPage()
        Try
            Dim webClient As New System.Net.WebClient
            Dim result As String = webClient.DownloadString(url)
            Dim client As WebClient = New WebClient()
            Dim data As Stream = client.OpenRead(url)
            Dim reader As StreamReader = New StreamReader(data)
            Dim Page As String = reader.ReadToEnd
            ListeMots.AddRange(IO.File.ReadAllLines("C:Users\" & System.Environment.UserName & "DocumentsListeDeMots.txt"))
            Dim found As Boolean = False
            For Each s As String In ListeMots
                If Page.ToLower.Contains(" " & s.ToLower & " ") = True Or Page.ToLower.Contains("<h1>" & s.ToLower & "</h1>") = True Then
                    RichTextBox1.Clear()
                    MsgBox("Un mot interdit a été détecté :" & s)

                End If
            Next
        Catch
        End Try

    End Sub
    Public Sub VerificationURL()
        Try
            Dim found As Boolean = False
            For Each s As String In ListeMots
                If url.ToLower.Contains("-" & s.ToLower & "-") = True Or url.ToLower.Contains("." & s.ToLower & ".") = True Or url.ToLower.Contains("." & s.ToLower & "-") = True Or url.ToLower.Contains("-" & s.ToLower & ".") = True Then
                    RichTextBox1.Clear()
                    MsgBox("Un mot interdit dans l'URL a été détecté :" & s)

                End If
            Next
        Catch
        End Try
    End Sub
    Private Sub AddText(sText As String)
        RichTextBox1.SelectAll()
        Dim nbrligne As Integer = RichTextBox1.GetLineFromCharIndex(RichTextBox1.SelectionLength())
        If nbrligne > 40 Then
            RichTextBox1.Clear()
        End If
        Dim url2 As Uri
        url2 = New Uri(sText)
        If url2.AbsolutePath.EndsWith(".js") = False And url2.AbsolutePath.EndsWith(".jpg") = False And url2.AbsolutePath.EndsWith(".gif") = False And url2.AbsolutePath.EndsWith(".png") = False And url2.AbsolutePath.EndsWith(".css") = False And url2.AbsolutePath.EndsWith(".ico") = False And url2.AbsolutePath.EndsWith(".jpeg") = False And RichTextBox1.Text.Contains(sText) = False And url2.ToString.Length < 200 = True Then
            RichTextBox1.AppendText(sText & vbCrLf)
            url = sText
            Dim ThreadVerificationPage As New Threading.Thread(AddressOf VerificationPage)
            ThreadVerificationPage.Start()
            Dim ThreadVerificationURL As New Threading.Thread(AddressOf VerificationURL)
            ThreadVerificationURL.Start()
        End If

    End Sub

    Protected Overrides Sub Finalize()
        MyBase.Finalize()
    End Sub

    Public Sub New()
        ' This call is required by the designer.
        InitializeComponent()
        ' Add any initialization after the InitializeComponent() call.
        AddHandler FiddlerApplication.BeforeResponse, AddressOf FiddlerBeforeResponseHandler
        AddHandler FiddlerApplication.BeforeRequest, AddressOf FiddlerBeforeRequestHandler
        AddHandler Application.ApplicationExit, AddressOf ShutdownFiddlerApp
        Dim oFlags As FiddlerCoreStartupFlags = FiddlerCoreStartupFlags.Default
        FiddlerApplication.Startup(0, oFlags)
        MsgBox("Started proxy on port " & FiddlerApplication.oProxy.ListenPort)

    End Sub
End Class
Commenter la réponse de CLeBeR_FR

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.