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

Langage PHP Discussion :

Récupération données site web


Sujet :

Langage PHP

  1. #1
    Membre éclairé
    Homme Profil pro
    Constructeur ossature bois
    Inscrit en
    Mars 2014
    Messages
    897
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Constructeur ossature bois
    Secteur : Associations - ONG

    Informations forums :
    Inscription : Mars 2014
    Messages : 897
    Points : 650
    Points
    650
    Par défaut Récupération données site web
    Bonjour à tous,

    J'aimerai récupérer des infos sur le web afin de remplir une Bdd, voici ce que j'ai récupérer comme script sur le forum, mais j'ai une erreur:
    Nom : Capture.PNG
Affichages : 313
Taille : 71,3 Ko

    Voici le code que j'utilise
    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
    <?php
     
    //La page qu'on veut utiliser
    $wikipediaURL = 'http://www.aroma-zone.com/info/fiche-technique/huile-vegetale-abricot-aroma-zone';
     
    //On initialise cURL
    $ch = curl_init();
    //On lui transmet la variable qui contient l'URL
    curl_setopt($ch, CURLOPT_URL, $wikipediaURL);
    //On lui demdande de nous retourner la page
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    //On envoie un user-agent pour ne pas être considéré comme un bot malicieux
    curl_setopt($ch, CURLOPT_USERAGENT, 'Google');
    //On exécute notre requête et met le résultat dans une variable
    $resultat = curl_exec($ch);
    //On ferme la connexion cURL
    curl_close($ch);
     
    //On crée un nouveau document DOMDocument
    $wikipediaPage = new DOMDocument();
    //On y charge le contenu qu'on a récupéré avec cURL
    $wikipediaPage->loadHTML($resultat);
     
    //On parcourt les balises <div>
    foreach($wikipediaPage->getElementsByTagName('div') as $div){
        //Si l'id de la page est bodyContent
        if($div->getAttribute('id') == "bodyContent"){
     
            //On met le contenu du premier <p> dans une variable
            $premierP = trim($div->getElementsByTagName('p')->item(0)->nodeValue);
            //Si le premier <p> est vide ou ne contient pas du texte
            while($premierP == '<br>' || $premierP == '<br />' || $premierP == ''){
                //On le supprime
                $div->removeChild($div->getElementsByTagName('p')->item(0));
                //Et on passe au <p> suivant
                $premierP = trim($div->getElementsByTagName('p')->item(0)->nodeValue);
            };
     
            //Un joli try pour éviter les messages d'erreur
            try{
                //On parcourt toutes les tables
                foreach( $div->getElementsByTagName('table') as $table ){
                    //Et on les supprime
                    $div->removeChild($table);
                }
            } catch(Exception $e){
                //On censure :P
            }
     
            //On récupère le contenu de la fameuse balise <p> dans une variable
            $description = '<p>' . $div->getElementsByTagName('p')->item(0)->nodeValue. '</p>';
        }
    }
     
    //On enlève la syntaxe propre à Wikipedia
    $description = preg_replace('/\[[0-9]*\][,]|\[[0-9]*\]/', '', $description);
     
    //On affiche de résultat
    echo $description;
     
    ?>
    Merci à vous pour vos éclaircissements
    Seb

  2. #2
    Membre éclairé Avatar de Geoffrey74
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mars 2007
    Messages
    515
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2007
    Messages : 515
    Points : 760
    Points
    760
    Par défaut
    Salut,

    je crois avoir déjà rencontré ce soucis.

    De mémoire j'ai eu trois solutions:
    • exécuter htmlentitie($resultat) (pas testé)
    • mettre un @ ici : $wikipediaPage->@loadHTML($resultat); (méthode barbare)
    • passer par $resultat= file_get_contents($wikipediaURL ); au lieu de curl

  3. #3
    Expert éminent Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Justicier interdimensionnel

    Informations forums :
    Inscription : Mars 2009
    Messages : 2 858
    Points : 6 556
    Points
    6 556
    Par défaut
    Il peut arriver qu'une page html contienne des erreurs (balises non fermées, ou comme ici entités ne se terminant pas par un ; ou simplement un & littéral). Les warnings sont alors émis lorsque le code html est parsé à l'appel de la méthode DOMDocument::loadHTML ou DOMDocument::loadHTMLFile.

    Pour éviter l'affichage automatique de ces warnings, il faut utiliser le gestionnaire d'erreur de libxml en plaçant libxml_use_internal_errors(true); avant le chargement. Les erreurs seront alors stockées dans un buffer et consultables mais plus affichées. Pour vider ce buffer, il suffit d'appeler libxml_clear_errors().

    Au passage, une id est censée être unique, donc pas la peine de parcourir les div pour la trouver. Il suffit de faire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $maDiv = $wikipediaPage->getElementById('bodyContent');
    Plus généralement, l'utilisation de XPath simplifierai ton code.
    Brachygobius xanthozonus
    Ctenobrycon Gymnocorymbus

  4. #4
    Membre éclairé
    Homme Profil pro
    Constructeur ossature bois
    Inscrit en
    Mars 2014
    Messages
    897
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Constructeur ossature bois
    Secteur : Associations - ONG

    Informations forums :
    Inscription : Mars 2014
    Messages : 897
    Points : 650
    Points
    650
    Par défaut
    Bonjour et merci pour vos réponses,

    @Cosmo:
    Pour info d'habitude je fais ce genre de récup via excel macro, mais le PHP est vraiment un langage intéressant. Je souhaite extraire de cette page --ICI--, les infos dans la balise <div class="fiche-accordion-content"/> puis dans <table class="table-propriete .../>"

    Le code que j'ai fourni ne me semble pas adapté pour ce que je souhaite récupéré, je pense qu'il y a un moyen de cibler directement ce que je souhaite??

    Visiblement PHP reconnait bien "getElementByTagName" mais pas "getElementByClassName", ou je m'y prend mal.

    Je regarde car il y a certainement un moyen plus simple.

    Ici les balises <p>, ne m'intéressent pas en gros seule la <table> convient...
    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
    <?php
     
    //La page qu'on veut utiliser
    $URL = 'http://www.aroma-zone.com/info/fiche-technique/huile-essentielle-niaouli-aroma-zone?page=library';
     
    //On initialise cURL
    $ch = curl_init();
    //On lui transmet la variable qui contient l'URL
    curl_setopt($ch, CURLOPT_URL, $URL);
    //On lui demdande de nous retourner la page
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    //On envoie un user-agent pour ne pas être considéré comme un bot malicieux
    curl_setopt($ch, CURLOPT_USERAGENT, 'Google');
    //On exécute notre requête et met le résultat dans une variable
    $resultat = curl_exec($ch);
    //On ferme la connexion cURL
    curl_close($ch);
    //Pour éviter l'affichage automatique de ces warnings, il faut utiliser le gestionnaire d'erreur de libxml
    libxml_use_internal_errors(true);
    //On crée un nouveau document DOMDocument
    $Page = new DOMDocument();
    //On y charge le contenu qu'on a récupéré avec cURL
    $Page->loadHTML($resultat);
     
    //On parcourt les balises <div>
    foreach($Page->getElementsByTagName('div') as $div){
        //Si l'id de la page est bodyContent
        if($div->getAttribute('class') == "fiche-accordion-content"){
     
            //On met le contenu du premier <p> dans une variable
            $premierP = trim($div->getElementsByTagName('p')->item(0)->nodeValue);
            //Si le premier <p> est vide ou ne contient pas du texte
            while($premierP == '<br>' || $premierP == '<br />' || $premierP == ''){
                //On le supprime
                $div->removeChild($div->getElementsByTagName('p')->item(0));
                //Et on passe au <p> suivant
                $premierP = trim($div->getElementsByTagName('p')->item(0)->nodeValue);
            };
     
            //Un joli try pour éviter les messages d'erreur
            try{
                //On parcourt toutes les tables
                foreach( $div->getElementsByTagName('table') as $table ){
                    //Et on les supprime
                    $div->removeChild($table);
                }
            } catch(Exception $e){
                //On censure :P
            }
     
            //On récupère le contenu de la fameuse balise <p> dans une variable
            $description = '<p>' . $div->getElementsByTagName('p')->item(0)->nodeValue. '</p>';
        }
    }
     
    //On enlève la syntaxe
    $description = preg_replace('/\[[0-9]*\][,]|\[[0-9]*\]/', '', $description);
     
    //On affiche de résultat
    echo $description;
    //vider le buffer libxml
    libxml_clear_errors()
    ?>
    Il y a de l'idée dan ce code mais pas adapté à mes besoins

    Parcontre je veux bien que tu m'expliques "Xpath", je ne connais pas
    Seb

  5. #5
    Expert éminent Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Justicier interdimensionnel

    Informations forums :
    Inscription : Mars 2009
    Messages : 2 858
    Points : 6 556
    Points
    6 556
    Par défaut
    Pour faire simple XPath permet de désigner des éléments de l'arbre DOM en fonction de leur position dans cette arbre (ancêtres, descendants, voire "frères" pour les éléments au même niveau) et de leurs caractéristiques (nom, attributs, contenu). Ça évite de devoir passer par toutes ces étapes intermédiaires, c'est un langage de requête. Tu trouveras des tutoriels sur le site et partout sur le net. En php, on passe par la class DOMXPath pour l'utiliser.

    Il y a de l'idée dan ce code mais pas adapté à mes besoins
    Ne rêve pas, tu ne t'en tirera pas en bidouillant du code copié/collé. Construit le toi-même en avançant par étapes, tu perdras moins de temps et tu comprendras ce que tu fais. Commence par faire une requête simple avec XPath, puis quand tu as quelque chose de fonctionnel, tente plus difficile jusqu'à atteindre le ou les éléments que tu souhaites (var_dump est ton ami).
    Brachygobius xanthozonus
    Ctenobrycon Gymnocorymbus

  6. #6
    Membre éclairé
    Homme Profil pro
    Constructeur ossature bois
    Inscrit en
    Mars 2014
    Messages
    897
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Constructeur ossature bois
    Secteur : Associations - ONG

    Informations forums :
    Inscription : Mars 2014
    Messages : 897
    Points : 650
    Points
    650
    Par défaut
    Re,

    Bon une première approche avec Xpath...
    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
    <?php
    $oldSetting = libxml_use_internal_errors( true ); 
    libxml_clear_errors(); 
     
    $url = 'http://www.aroma-zone.com/info/fiche-technique/huile-essentielle-niaouli-aroma-zone?page=library';
    $html = new DOMDocument(); 
    $html->loadHtmlFile($url); 
     
    $xpath = new DOMXPath($html); 
    $elements = $xpath->query( "//table/tr/td" ); 
     
    foreach ( $elements as $item ) {
      $newDom = new DOMDocument;
      $newDom->appendChild($newDom->importNode($item,true));
     
      $xpath = new DOMXPath($newDom); 
     
      foreach ($item->attributes as $attribute) { 
     
        for ($node = $item->firstChild; $node !== NULL; 
             $node = $node->nextSibling) {
          if (($attribute->nodeName =='class') && ($attribute->nodeValue=='propriete-desc'))
          {
            print($node->nodeValue); 
          }
          else
          {
            print("<br>".$node->nodeValue);
          }
        }
        print("<br>");
      } 
    }
     
    libxml_clear_errors(); 
    libxml_use_internal_errors( $oldSetting ); 
    ?>
    Donc ici je récupère bien les valeurs contenues dans les balises <td>, bon certes sans mise en forme...

    A suivre....

  7. #7
    Expert éminent Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Justicier interdimensionnel

    Informations forums :
    Inscription : Mars 2009
    Messages : 2 858
    Points : 6 556
    Points
    6 556
    Par défaut
    Tu mets la charrue avant les bœufs, vire tout ce qui est en dessous de la ligne 10 et essaye d'obtenir directement ce que tu veux avec XPath. Pour l'instant ta requête renvoie tous les nœuds td. Essaye déjà d'obtenir uniquement ceux de la table avec la classe "table-propriete" en modifiant ta requête. (utilise les prédicats)
    Brachygobius xanthozonus
    Ctenobrycon Gymnocorymbus

  8. #8
    Membre éclairé
    Homme Profil pro
    Constructeur ossature bois
    Inscrit en
    Mars 2014
    Messages
    897
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Constructeur ossature bois
    Secteur : Associations - ONG

    Informations forums :
    Inscription : Mars 2014
    Messages : 897
    Points : 650
    Points
    650
    Par défaut
    De ce type, j'imagine:
    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
    <?php
    $oldSetting = libxml_use_internal_errors( true ); 
    libxml_clear_errors(); 
     
    $url = 'http://www.aroma-zone.com/info/fiche-technique/huile-essentielle-niaouli-aroma-zone?page=library';
    $html = new DOMDocument(); 
    $html->loadHtmlFile($url); 
     
    $xpath = new DOMXPath($html); 
    $elements = $xpath->query( '//table[@class=\'table-propriete\']/tr/td/text()'); 
    foreach ($elements as $element) {
    	echo $element->previousSibling->nodeValue;
    }
    libxml_clear_errors(); 
    libxml_use_internal_errors( $oldSetting ); 
    ?>
    Mais j'ai des erreurs entrelacées avec le résultats:
    Nom : Capture.PNG
Affichages : 234
Taille : 72,6 Ko

    Seb

  9. #9
    Expert éminent Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Justicier interdimensionnel

    Informations forums :
    Inscription : Mars 2009
    Messages : 2 858
    Points : 6 556
    Points
    6 556
    Par défaut
    Voilà, c'est l'idée, idée qu'il faut poursuivre en affinant encore la requête jusqu'à obtenir une liste de nœuds (DOMNodeList) la plus proche possible des informations que tu souhaites extraire. Tu ne devrais pas avoir à utiliser quelque chose comme previousSibling, la requête XPath doit amener directement à bon port. Et si par la suite tu souhaites séparer des éléments pour chaque nœud (objet DOMNode) de ta liste, tu peux éventuellement te servir d'un nœud comme point de départ pour une autre requête XPath (en utilisant le deuxième paramètre de DOMXPath::query).

    Attention à ne pas te faire bloquer ton IP en sollicitant trop le site d'où provient la page, pour tes essais je te conseille de travailler sur une copie locale.
    Brachygobius xanthozonus
    Ctenobrycon Gymnocorymbus

Discussions similaires

  1. Récupération de données site web
    Par yeti7984 dans le forum Macros et VBA Excel
    Réponses: 64
    Dernier message: 12/05/2014, 18h44
  2. [Généralités] Données site web
    Par mike92 dans le forum WinDev
    Réponses: 6
    Dernier message: 21/12/2011, 16h51
  3. [XL-2003] VBA possibilité extraction données site web
    Par Paul75 dans le forum Macros et VBA Excel
    Réponses: 1
    Dernier message: 29/01/2011, 18h54
  4. [XL-2007] Importer données site web en direct
    Par Fenix01 dans le forum Excel
    Réponses: 5
    Dernier message: 26/05/2010, 13h07
  5. Réponses: 11
    Dernier message: 01/09/2005, 18h59

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