Problèmes de fonction avec Pugixml

Pierre77777 Messages postés 2 Date d'inscription lundi 19 août 2024 Statut Membre Dernière intervention 21 août 2024 - 19 août 2024 à 17:01
mamiemando Messages postés 33363 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 16 novembre 2024 - 21 août 2024 à 13:46

Bonjour à tous,

Je me permets de poster ce message pour vous demander de l'aide s'il vous plaît.

Je code un script de scraping de données footballistiques (grâce à pugixml et libcurl) à partir de Visual Studio mais malgré les assistances, je n'arrive pas à résoudre mes problèmes :

E0312 : il n'existe aucune conversion définie par l'utilisateur appropriée de "const pugi::xpath_node" en "pugi::xml_node".   

 E0135    classe "pugi::xml_node" n'a pas de membre "node"

E0135    classe "pugi::xml_node" n'a pas de membre "node"

E0312    il n'existe aucune conversion définie par l'utilisateur appropriée de "const pugi::xpath_node" en "pugi::xml_node"

E0135    classe "pugi::xml_node" n'a pas de membre "node"

C2039    'node' n'est pas membre de 'pugi::xml_node'

C2039    'node' n'est pas membre de 'pugi::xml_node'

C2440    'initialisation' : impossible de convertir de 'const pugi::xpath_node' en 'pugi::xml_node'

C2039    'node' n'est pas membre de 'pugi::xml_node'

C2039    'node' n'est pas membre de 'pugi::xml_node'   

 
   
Ces erreurs interviennent uniquement sur cette partie du script :

void extractMatchData(const std::string& html) {
    pugi::xml_document doc;
    pugi::xml_parse_result result = doc.load_string(html.c_str());

    if (result) {
        for (pugi::xml_node match : doc.select_nodes("//div[contains(@class, 'matchTeam__name')]")) {
            MatchInfo matchInfo;
            matchInfo.teamName = match.node().child_value();
            matchInfo.datetime = match.node().parent().select_node("//time[contains(@class, 'datetime')]").node().attribute("datetime").value();
            matches.push_back(matchInfo);
        }
    }
    else {
        std::cerr << "Erreur lors du parsing HTML : " << result.description() << std::endl;
    }
}

// Fonction pour extraire les données du classement (général, domicile, extérieur)
void extractRankingData(const std::string& html, std::vector<RankingInfo>& ranking) {
    pugi::xml_document doc;
    pugi::xml_parse_result result = doc.load_string(html.c_str());

    if (result) {
        for (pugi::xml_node teamNode : doc.select_nodes("//div[contains(@class, 'rankingTable__team')]")) {
            RankingInfo rankInfo;
            rankInfo.teamName = teamNode.node().child_value();
            rankInfo.rank = std::stoi(teamNode.node().parent().select_node("div[contains(@class, 'rankingTable__rank')]").node().child_value());
            rankInfo.points = std::stoi(teamNode.node().parent().select_node("div[contains(@class, 'rankingTable__highlights')]").node().child_value());
            // Remplissez les autres champs avec les données correspondantes...
            ranking.push_back(rankInfo);
        }
    }
    else {
        std::cerr << "Erreur lors du parsing HTML : " << result.description() << std::endl;
    }
}

// Fonction pour extraire les données des meilleurs buteurs
void extractTopScorersData(const std::string& html, std::vector<PlayerStats>& scorers) {
    pugi::xml_document doc;
    pugi::xml_parse_result result = doc.load_string(html.c_str());

    if (result) {
        for (pugi::xml_node playerNode : doc.select_nodes("//div[contains(@class, 'personCardCell__description')]")) {
            PlayerStats playerStats;
            playerStats.playerName = playerNode.node().child_value();
            playerStats.goals = std::stoi(playerNode.node().parent().select_node("//div[contains(@data-value, 'Buts')]").node().attribute("data-value").value());
            // Remplissez les autres champs avec les données correspondantes...
            scorers.push_back(playerStats);
        }
    }
    else {
        std::cerr << "Erreur lors du parsing HTML : " << result.description() << std::endl;
    }
}

Google n'est pas mon ami pour ce coup là... Pouvez-vous m'aider s'il vous plaît ?

Merci par avance.

Cordialement


Windows / Edge 127.0.0.0

3 réponses

mamiemando Messages postés 33363 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 16 novembre 2024 7 801
19 août 2024 à 17:27

Bonjour,

Si je m'en tiens au message d'erreur, tu tentes de convertir un "const pugi::xpath_node" en "pugi::xml_node".

Premier problème, tu tentes de convertir un objet "const" (objet en lecture seule) en objet "non const" (objet en lecture écriture). Ce n'est pas cohérent, et en admettant que ce le soit (ce qui est peu probable) il faudrait faire un const_cast. Mais vu ce que tu veux faire, il faudrait simplement que le type de ton objet soit const.

Second problème, le type n'est pas le même. Il faudrait se demander si un tel cast est légitime et si on a de bonne raison de le faire, et si c'est le cas il faudrait sans doute plutôt faire un dynamic_cast. Ce cast ne semble pas légitime, car le type cible n'hérite pas du type source d'après ce que je vois ici.

Donc ta boucle devrait plus logiquement s'écrire :

for (const pugi::xpath_node & playerNode : doc.select_nodes("//div[contains(@class, 'personCardCell__description')]")) {
    ...
}

... ou si tu utilises un compilateur C++ moderne :

for (const auto & playerNode : doc.select_nodes("//div[contains(@class, 'personCardCell__description')]")) {
    ...
}

Les erreurs suivantes indiquent que l'objet xml_node n'a pas de méthode node.

Plusieurs questions :

  • T'es tu basé sur un tutoriel ? Si oui lequel ? Et sinon, as-tu essayé d'en chercher un ?
  • Utilises-tu un IDE (qui pourrait t'aider à voir quand tu commets des erreurs de développement) ?
  • As-tu un besoin technique qui justifie d'écrire ton programme en C++ ? Souvent pour faire du scraping, on utilise des langages moins performants mais plus pratique tel que python ?

Bonne chance

0
Pierre77777 Messages postés 2 Date d'inscription lundi 19 août 2024 Statut Membre Dernière intervention 21 août 2024
21 août 2024 à 12:18

Bonjour Mamiemando,

Je te remercie pour ta réponse.

Je m'aide de ChatGPT pour coder les fonctions complexes.

J'utilise Visual Studio qui possède un assistant mais sur certaines erreurs, il reste assez vague...

J'ai codé un algorithme en c++ donc je pensais que ce serait plus simple d'avoir le scraping en c++.

Merci encore 

0
mamiemando Messages postés 33363 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 16 novembre 2024 7 801
21 août 2024 à 13:46

Bonjour Pierre,

C++ or not C++ ? Effectivement si tu as commencé en C++, il est plus naturel de continuer en C++... sous réserve que le scraping s'intègre dans ce programme. Je ne sais pas à quel point tu es à l'aise en programmation, en C++, et quel est le but final de ton programme, mais si tu es néophyte, je ne recommande pas forcément de démarrer par du C++.

ChatGPT or not ChatGPT ? Je te déconseille de coder avec ChatGPT. À chaque fois que je vois des gens poser des questions sur le forum lié à du code produit par ChatGPT, le code qu'ils proposent (ou plutôt que ChatGPT leur propose) est catastrophique. Il vaut mieux apprendre le langage et/ou les librairies dont tu as besoin. En outre, ChatGPT va choisir une solution technique qui n'est pas forcément la meilleure selon tes besoins (voir ce lien pour voir un état de l'art des librairies pour parser du XML en C++), et probablement générer du code faux/mort/overkill.

Scraping or not scraping ? Ensuite, il faut voir quel site tu cherches à scraper. En effet, parser du contenu XML présuppose que l'architecture de la page web traitée ne changera pas significativement. Au contraire, si le site le propose, une API est supposée être stable permet de directement récupérer la donnée (par la suite mise en forme par le site). Du coup se pose les questions suivantes :

  • Avec quel site travailles-tu ?
  • Propose-t'il une API ?
  • Quelle donnée souhaites-tu extraire ?

En admettant que toutes ces questions te maintiennent dans le choix de pugixml, il faut idéalement s'entraîner sur un exemple, ou si tu es déjà l'aise avec la librairie, repartir d'un extrait de code fiable (par exemple une réponse fournie dans la documentation ou sur un forum spécialisé, par exemple stackoverflow) et broder autour de cet exemple. Dans ton cas, repartir de cette section de la documentation est sans doute un bon début.

Enfin, en programmation (et en particulier C++), c'est une mauvaise idée de vouloir tout coder d'un coup, il vaut mieux ajouter progressivement du code et vérifier les ajouts, puis itérer jusqu'à atteindre le but souhaiter.

  • As-tu compris grâce à mon message précédent, les erreurs de compilations que tu avais ?
  • Es-tu parvenu à les corriger (par exemple, en adaptant les exemples donnés dans la documentation) ?

Bonne chance

0