IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

C# Html Agility Pack fait planter le programme


Sujet :

C#

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Inscrit en
    Février 2013
    Messages
    19
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Février 2013
    Messages : 19
    Points : 9
    Points
    9
    Par défaut C# Html Agility Pack fait planter le programme
    Bonjour,

    Je souhaite récupérer le contenu d'un tableau situé dans une page HTML.
    Après recherche, j'ai choisi d'utiliser HTML agility pack.

    Mon code pour récupérer la page est le suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
     
    public void lecture()
            {
                string url = "http://url_cible.fr";
     
                HtmlWeb web = new HtmlWeb();
                HtmlDocument doc = web.Load(url);
     
                var table = doc.GetElementbyId("tv2");
     
                var rows = table.Element("tbody").Elements("tr");
     
                var contacts = from r in rows
                               let values = r.Elements("td").Select(c => c.InnerText).ToArray()
                               select new donnees2
                               {
                                   C_noms = values[0],
                                   C_delais = values[1],
                                   C_ex= values[2],
                                   C_ec = values[3],
                                   C_ea = values[4]
                               };
     
            }
    J'ai utilisé un tuto trouvé ici : http://tlevesque.developpez.com/tuto...-agility-pack/ pour créer mon code. Je n'ai pas d'erreur du débugger, j'ai regardé avec Wireshark, et le programme télécharge bien le code source de la page... Mais il plante lamentable sur la ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    var rows = table.Element("tbody").Elements("tr");
    .
    Il m'affiche comme erreur :
    L'exception NullReferenceException n'a pas été gérée...
    Sachant qu'il me propose deux conseils pour y remédier :
    - Déterminer si l'objet est null avant d'appeler la méthode.
    J'ai donc essayé en rajoutant une condition :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if (table.Element("tbody").Elements("tr")) != null);
    Mais ca a fait planter le programme sur le if avec les même raisons...

    -Utilisez le mot clef "new" pour créer une instance d'objet.
    Mais je vois pas trop ce que je dois créer... J'ai fait comme dans l'exemple sur le tuto...

    Je ne vois pas trop d'où viens l'erreur, sachant que encore une fois le débugger ne trouve pas de faute... Si quelqu'un à une idée je suis preneur...

  2. #2
    Modérateur
    Avatar de DotNetMatt
    Homme Profil pro
    CTO
    Inscrit en
    Février 2010
    Messages
    3 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : CTO
    Secteur : Finance

    Informations forums :
    Inscription : Février 2010
    Messages : 3 611
    Points : 9 743
    Points
    9 743
    Billets dans le blog
    3
    Par défaut
    Etonnant. Si tu décomposes ton if comme suit :
    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    if (table != null)
    {
        if (table.Element("tbody") != null)
        {
            if (table.Element("tbody").Elements("tr") != null)
            {
                // Ton code
            }
        }
    }

    Est-ce que tu atteins la ligne où j'ai mis "// Ton code" ?
    Less Is More
    Pensez à utiliser les boutons , et les balises code
    Desole pour l'absence d'accents, clavier US oblige
    Celui qui pense qu'un professionnel coute cher n'a aucune idee de ce que peut lui couter un incompetent.

  3. #3
    Futur Membre du Club
    Homme Profil pro
    Inscrit en
    Février 2013
    Messages
    19
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Février 2013
    Messages : 19
    Points : 9
    Points
    9
    Par défaut
    Bonjour,

    Merci pour ta réponse !

    En faisant comme tu indique, ça ne plante plus, mais je n'entre pas dans le premier if... Il semblerait donc que table ne contient rien du tout...

    Pourtant comme dis précédemment, sur wireshark je vois que le programme télécharge le code source, donc web n'est pas sensé être vide...

    J'ai transféré ma class dans un petit projet pour pouvoir faire des tests facilement. J'ai donc le code suivant (il ne plante pas mais ne fonctionne pas non plus )
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
     
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using HtmlAgilityPack;
     
    namespace ConsoleApplication2
    {
        class Program
        {
            static void Main(string[] args)
            {
                donnees2 test = new donnees2();
                test.lecture();
            }
        }
     
        public class donnees2
        {
            public string C_noms { get; set; }
            public string C_delais { get; set; }
            public string C_ex { get; set; }
            public string C_ec { get; set; }
            public string C_ea { get; set; }
     
            public donnees2()
            {
     
            }
     
            public void lecture()
            {
                string url = "http://exemple.fr";
     
                HtmlWeb web = new HtmlWeb();
                HtmlDocument doc = web.Load(url);
     
                var table = doc.GetElementbyId("tv2");
     
                Console.WriteLine(table); //j'ai effectué mes tests ici
                if (table != null)
                {
                    Console.WriteLine("table != null");
                    if (table.Element("tbody") != null)
                    {
                        Console.WriteLine("table.Element(\"tbody\") != null");
                        if (table.Element("tbody").Element("tr") != null)
                        {
                            Console.WriteLine("table.Element(\"tbody\").Element(\"tr\") != null");
                            var rows = table.Element("tbody").Elements("tr");
     
                            var contacts = from r in rows
                                           let values = r.Elements("td").Select(c => c.InnerText).ToArray()
                                           select new donnees2
                                           {
                                               C_noms = values[0],
                                               C_delais = values[1],
                                               C_ex = values[2],
                                               C_ec = values[3],
                                               C_ea = values[4]
                                           };
                        }
                    }
                }
            }
        }
    }
    J'ai fait mes tests juste avant les if
    Si j'affiche table, effectivement il est vide.
    Si j'affiche doc j'obtiens HtmlAgilityPack.HtmlDocument
    Si j'affiche web j'obtiens HtmlAgilityPack.HtmlWeb

  4. #4
    Futur Membre du Club
    Homme Profil pro
    Inscrit en
    Février 2013
    Messages
    19
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Février 2013
    Messages : 19
    Points : 9
    Points
    9
    Par défaut
    En comparant avec ce que je trouve sur le tuto, je ne vois pas de différences...

    Et la j'ai mis ça dans un petit programme qui ne fait que ça pour ne pas être importuné par les autres fonctions... Mais ça ne change pas le problème.

    Pour moi, ça vient de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    var table = doc.GetElementbyId("page-bg");
    ou de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    HtmlDocument doc = web.Load(url);
    ...

    Mais je ne voie pas où est l'erreur.

  5. #5
    Modérateur
    Avatar de DotNetMatt
    Homme Profil pro
    CTO
    Inscrit en
    Février 2010
    Messages
    3 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : CTO
    Secteur : Finance

    Informations forums :
    Inscription : Février 2010
    Messages : 3 611
    Points : 9 743
    Points
    9 743
    Billets dans le blog
    3
    Par défaut
    Ok, si ta variable table est égale à null, ça signifie que tu n'as aucun élément HTML ayant pour ID "tv2" (ou "page-bg" dans ton dernier exemple).

    Si le site que tu vises a un mécanisme d'authentification, il faut vérifier que tu tombes bien sur la page que tu souhaites parser, et non sur la page d'identification. Tu peux vérifier cela en regardant la valeur de web.ResponseUri.
    Less Is More
    Pensez à utiliser les boutons , et les balises code
    Desole pour l'absence d'accents, clavier US oblige
    Celui qui pense qu'un professionnel coute cher n'a aucune idee de ce que peut lui couter un incompetent.

  6. #6
    Futur Membre du Club
    Homme Profil pro
    Inscrit en
    Février 2013
    Messages
    19
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Février 2013
    Messages : 19
    Points : 9
    Points
    9
    Par défaut
    Il n'y a pas de sécurité particulière sur la page...
    Elle est sur mon réseau d'entreprise et mon PC est déjà loggué.
    En utilisant ta commande je récupère bien l'URL de ma page.


    Je vais tenter en le faisant "à la main" voir ce que ça donne... Par ce que la page où je récupère des informations a été codée n'importe comment, et je pense que HTML Agility Pack perds ses repères (balises ouvertes mais pas fermées, etc.).

  7. #7
    Futur Membre du Club
    Homme Profil pro
    Inscrit en
    Février 2013
    Messages
    19
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Février 2013
    Messages : 19
    Points : 9
    Points
    9
    Par défaut
    Est-il possible de convertir la page qu'on récupère avec Html Agility Pack en string ?

    J'ai essayé une conversion explicite :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    string web_tmp = doc.ToString();
    ... Mais ça marche pas...

    Mon code ressemble donc à
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
            public void lecture()
            {
                string url = "http://exemple.fr";
     
                HtmlWeb web = new HtmlWeb();
                HtmlDocument doc = web.Load(url);
     
                string web_tmp;
             }
    Et je voudrais que mon string web_temp puis récupérer l'ensemble de la page web (je découperais après avec des fonctions de string). Je n'ai pas trouvé de fonctions pour ça, est-ce que vous en connaissez une ?

  8. #8
    Modérateur
    Avatar de DotNetMatt
    Homme Profil pro
    CTO
    Inscrit en
    Février 2010
    Messages
    3 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : CTO
    Secteur : Finance

    Informations forums :
    Inscription : Février 2010
    Messages : 3 611
    Points : 9 743
    Points
    9 743
    Billets dans le blog
    3
    Par défaut
    Oui tu peux récupérer l'ensemble du code HTML de la page cible en utilisant la méthode WriteContentTo() de la propriété DocumentNode de ton objet HtmlDocument :

    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    var web_tmp = doc.DocumentNode.WriteContentTo();
    Less Is More
    Pensez à utiliser les boutons , et les balises code
    Desole pour l'absence d'accents, clavier US oblige
    Celui qui pense qu'un professionnel coute cher n'a aucune idee de ce que peut lui couter un incompetent.

Discussions similaires

  1. tableau html + Html Agility Pack
    Par aymen8219 dans le forum Développement Web avec .NET
    Réponses: 12
    Dernier message: 03/04/2012, 21h35
  2. Réponses: 19
    Dernier message: 24/10/2009, 23h58
  3. Réponses: 3
    Dernier message: 01/03/2009, 18h09
  4. Réponses: 2
    Dernier message: 17/03/2007, 13h43
  5. Réponses: 1
    Dernier message: 08/06/2006, 11h01

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo