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 :

Analyse de code html


Sujet :

Langage PHP

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 6
    Par défaut Analyse de code html
    Bonjour,

    Voila plusieurs heures que je test dans tout les sens et je commence a désespéré, je m'en remet donc au pro et me décide a poster.

    Je vous explique le problème :

    Je dois extraire la liste des adresses de toute les fromagers de france, pour ca j'utilise ce site :

    http://www.fromagersdefrance.com/fr/

    La fonction de recherche est assez simple, lorsqu'on fait une recherche, on récupère une url comme ca :

    http://www.fromagersdefrance.com/fr/...l_rech.asp?CP=37000&Dept=&Ville=&Service=&Etendue=

    CP étant le code postal.
    La fonction pour générer toute les url des codes postaux est déjà faite.

    Le problème étant au moment de récupérer la liste, ça n'a pourtant pas l'air compliquer, lors d'exemple, de tests tout ce passe bien mais au moment de tester sur un cas concret, ca bloque.

    Prenons l'exemple de cette url : http://www.fromagersdefrance.com/fr/...vice=&Etendue=

    Il y a 8 fromagers, ils sont tous sous cette forme :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    <td width="540" valign="top"> 
    <p><font size="2"><b>
    NOM<br>
    Adresse<br>CP&nbsp;VILLE<br>
    </b></font></p>
    </td>
    J'ai donc essayé avec ça :

    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
    <?php
    function http_fetch_url($url, $timeout = 10, $userpwd = ''){ // recupère le code source d'une page et le met dans $data
    	$ch = curl_init($url);
    	curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
    	curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
    	curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
    	curl_setopt($ch,CURLOPT_REFERER,""); 
    	if ($userpwd) {
    		curl_setopt($ch, CURLOPT_USERPWD, $userpwd);
    	}
    	$data = curl_exec($ch);
    	curl_close($ch);
     
    	return $data;
    }
     
    function supprimelien($texte){ // fonction pour supprimer les liens, ils ne me servent a rien
    $motif='`<a[^>]+?>(.*?)</a>`';
    $sortie='';
    return $texte=preg_replace($motif,$sortie,$texte); 
    }
     
            $test = http_fetch_url($url); // je stock le code html dans $test
    	$test = preg_replace('/\s\s+/', '', $test); // je supprime tout les espaces (plus simple pour preg_match_all)
    	$test = supprimelien($test); // les liens ne me servent pas
     
    	//echo $test;
    	if(!@eregi("Il n'y a aucun résultat pour votre recherche",$test)){ // si il y a bien des fromagers
     
    // et la j'ai testé toute les methodes suivante mais aucune ne marche
    	//preg_match_all("/\<td valign=\"top\" width=\"540\">\<p\>(.*)\<\/td\>/" , $test, $tab);
    	//preg_match_all("/\<tr\>(.*)\<\/tr\>/" , $test, $tab); 
    	//preg_match_all("/\<tr\>(.*)\<\/tr\>/" , $test, $tab); 
    	preg_match_all("/\<font size=\"2\"\>\<b\>(.*)\<\/b\>\<\/font\>\<\/p\>\<\/td\>\<\/tr\>/" , $test, $tab); 
     
    	echo "<pre>";
    	print_r($tab);
    	echo "</pre>";
    ?>
    A chaque fois je ne les récupère pas tous ou sinon ils sont 2 dans un même tableau..
    bref.. il y a un truc que je dois louper...
    Si quelqu'un peut m'aiguiller..
    J'ai mis la source pour que vous puissiez juste c/c pour tester

    Une idée ? une piste ? une solution ?

  2. #2
    Membre Expert
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 418
    Par défaut
    Il faut regarder de près le code source de la page en question. La forme

    <td width="540" valign="top">
    <p><font size="2"><b>
    NOM<br>
    Adresse<br>CP&nbsp;VILLE<br>
    </b></font></p>
    </td>
    sous laquelle tu dis que les adresses se présentent est bien trop simple. En examinant toutes les adresses on s’aperçoit qu’il y a des variations sur toutes les lignes:



    '\t\t\t <font color=#3200A4><a href="contenu_resul_fiche.asp?Fiche=676" target=contenu>LA MONTAGNE AUX FROMAGES</a></font><br>\r\n'

    et

    '\t\t\t LA CR\xc9ME DES FROMAGES<br>\r\n'





    '\t\t\t Halles Centrales<BR>Parking souterrain 600 places<br>37000&nbsp;TOURS<br>\r\n'

    et

    '\t\t\t Halles Centrales<BR>37000&nbsp;TOURS<br>\r\n'

    et aussi

    '\t\t\t Halles Centrales<BR>\nplace Gaston Pailhou<BR>37000&nbsp;TOURS<br>\r\n'



    ' T&eacute;l. : 02 47 37 75 33\r\n'

    ou

    ' T&eacute;l. : 02 47 37 75 33\r\n'




    J’ai trouvé la RE suivante pour attraper toutes les adresses, sauf FROMAGES.COM qui ne présente pas d’intérêt car il manque tout.

    La partie rues et autres précisions , avant le code postal, est attrapée d’un bloc => il y a les <BR> etc dans le groupe. Il faudra faire un traitement spécial pour séparer les sous-parties.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    RE = ('<p><font size="2"><b>\r\n',
          '\t\t\t  (?:<font color=[^>]+>',
          '<a href="contenu_resul_fiche\.asp\?Fiche=',
          '\d+" target=contenu>)?([^>]+)(?:</a></font>)?<br>\r\n',
          '\t\t\t  (((.+?)<[brBR]{2}>\r?\n?)+)',
          '(\d+)&nbsp;(.+?)<br>\r\n',
          '              (T&eacute;[^\r\n]+)?\r\n'
          '\t\t\t  </b></font></p>\r\n')
    Il faut concatener tous les éléments pour obtenir une seule chaine

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 6
    Par défaut
    Il faut regarder de près le code source de la page en question. La forme sous laquelle tu dis que les adresses se présentent est bien trop simple. En examinant toutes les adresses on s’aperçoit qu’il y a des variations sur toutes les lignes
    C'est pour ca que j'avais supprimer les espaces et les liens avec :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    $test = preg_replace('/\s\s+/', '', $test); // je supprime tout les espaces (plus simple pour preg_match_all)
    $test = supprimelien($test); // les liens ne me servent pas
    Je pensais que ca aurait été plus simple..

    J'ai plus ou moins compris ton bout de code et je ne serai jamais arrivé a pondre un truc aussi complet.. par contre je n'arrive pas a l'utiliser
    Tu va surement me prendre pour un charlatant qui attend que ca lui tombe tout cuit dans le bec mais ca va faire 30min que j'test toute les solutions possibles mais en vain :/

    Un dernier petit coup de pouce ?
    N'empêche, un gros merci a toi pour t'être penché sur mon problème

  4. #4
    Membre Expert
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 418
    Par défaut
    Bonjour,



    Tu vas sûrement me prendre pour un charlatan qui attend que ça lui tombe tout cuit dans le bec
    Non non. Il y a un code en PHP dans ton premier message qui montre bien que tu ne l’es pas.



    Le langage que je connais le mieux, c’est à dire un peu, est Python. Comme j’adore les regex, je réponds quelques fois à des questions sur ce sujet dans ce forum. Mais je connais très peu PHP. Quand un problème, comme le tien, me pose trop de problème pour faire tourner un code en PHP, je travaille en Python.

    J’ai posté cette nuit en vitesse parce qu’il était déjà tard. J’aurais dû prendre 2 mn de plus pour te donner la RE sous une forme correcte. En Python, à partir du tuple RE tel qu’il est dans mon précédent message, on fait "".join(RE) et hop on a la bonne chaîne qui est:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    '<p><font size="2"><b>\r\n\t\t\t  (?:<font color=[^>]+><a href="contenu_resul_fiche\.asp\?Fiche=\d+" target=contenu>)?([^>]+)(?:</a></font>)?<br>\r\n\t\t\t  ((?:.+?<[brBR]{2}>\r?\n?)+)(\d+)&nbsp;(.+?)<br>\r\n              (T&eacute;[^\r\n]+)?\r\n\t\t\t  </b></font></p>\r\n'
    En PHP il faudrait rajouter les delimiteurs

    AVec cette RE, j'obtiens le resultat 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
    ('LA MONTAGNE AUX FROMAGES', 'Halles Centrales<BR>Parking souterrain 600 places<br>', '37000', 'TOURS', 'T&eacute;l. : 02 47 38 64 07')
     
    ('FRANCE FROMAGE', 'Halles Centrales<BR>', '37000', 'TOURS', 'T&eacute;l. : 02 47 38 65 39')
     
    ('LA FERME DES VIGNES', 'Halles Centrales<BR>\nplace Gaston Pailhou<BR>', '37000', 'TOURS', 'T&eacute;l. : 02 47 38 60 19')
     
    ('LA CR\xc9ME DES FROMAGES', 'Place Gaston Pailhou<BR>', '37000', 'TOURS', '')
     
    ('TMTC', 'Place Gaston Pailhou<BR>\nHalles Centrales<BR>', '37000', 'TOURS', '')
     
    ('CR\xc9MERIE FROMAGERIE', '3, passage Walvein<BR>', '37000', 'TOURS', 'T&eacute;l. : 02 47 37 75 33')
     
    ('CR\xc9MERIE FROMAGERIE', '63 Rue Chalmel<BR>', '37000', 'TOURS', 'T&eacute;l. : 02 47 61 64 07')
    >>>


    En PHP j'écris la RE sous la forme suivante, pour éviter de se retrouver avec une chaîne qui déborde de l’écran. J’ai eu la flemme de le faire avant de poster.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    $RE = '#<p><font size="2"><b>\r\n'.
          '\t\t\t  (?:<font color=[^>]+>'.
          '<a href="contenu_resul_fiche\.asp\?Fiche='.
          '\d+" target=contenu>)?([^>]+)(?:</a></font>)?<br>\r\n'.
          '\t\t\t  ((?:.+?<[brBR]{2}>\r?\n?)+)'.
          '(\d+)&nbsp;(.+?)<br>\r\n'.
          '              (T&eacute;[^\r\n]+)?\r\n'.
          '\t\t\t  </b></font></p>\r\n#';



    Difficulté plus sérieuse que j’ai eue pour pouvoir faire faire tourner un code en PHP: obtenir le code source de la page du site concernée. J’ai compris qu’il faut un module curl pour télécharger la page. Mais je ne sais pas installer un module dans un programme PHP. Bref je n’ai pas pu faire tourner de programme PHP pour vérifier la validité de ma RE. En Python, c’est bon.





    Bon. J’ai mis un bout de la page à la main dans un code que voici:

    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
    <?php
     
    $ch = '\t\t  \r\n'.
    '\t\t  </td>\r\n'.
    '          <td valign="top" width="540"> \r\n'.
    '            <p><font size="2"><b>\r\n'.
    '\t\t\t  <font color=#3200A4><a href="contenu_resul_fiche.asp?Fiche=676" target=contenu>LA MONTAGNE AUX FROMAGES</a></font><br>\r\n'.
    '\t\t\t  Halles Centrales<BR>Parking souterrain 600 places<br>37000&nbsp;TOURS<br>\r\n'.
    '              T&eacute;l. : 02 47 38 64 07\r\n'.
    '\t\t\t  </b></font></p>\r\n'.
    '          </td>\r\n'.
    '        </tr>\r\n'.
    '\t\t\r\n'.
    '        <tr> \r\n'.
    '          <td width="80" valign="top">\r\n'.
    '\t\t  \r\n'.
    '\t\t  <a href="contenu_resul_fiche.asp?Fiche=672" target="contenu">\r\n'.
    '\t\t  <img src="../images/recherche/logo.gif" width="80" height="69" alt="Membre des Fromagers de France" border="0">\r\n'.
    '\t\t  </a>\r\n'.
    '\t\t  \r\n'.
    '\t\t  </td>\r\n'.
    '          <td valign="top" width="540"> \r\n'.
    '            <p><font size="2"><b>\r\n'.
    '\t\t\t  <font color=#3200A4><a href="contenu_resul_fiche.asp?Fiche=672" target=contenu>FRANCE FROMAGE</a></font><br>\r\n'.
    '\t\t\t  Halles Centrales<BR>37000&nbsp;TOURS<br>\r\n'.
    '              T&eacute;l. : 02 47 38 65 39\r\n'.
    '\t\t\t  </b></font></p>\r\n'.
    '          </td>\r\n'.
    '        </tr>\r\n'.
    '\t\t\r\n'.
    '        <tr> \r\n'.
    '          <td width="80" valign="top">\r\n'.
    '\t\t  \r\n'.
    '\t\t  <a href="contenu_resul_fiche.asp?Fiche=671" target="contenu">\r\n'.
    '\t\t  <img src="../images/recherche/logo.gif" width="80" height="69" alt="Membre des Fromagers de France" border="0">\r\n'.
    '\t\t  </a>\r\n'.
    '\t\t  \r\n'.
    '\t\t  </td>\r\n'.
    '          <td valign="top" width="540"> \r\n'.
    '            <p><font size="2"><b>\r\n'.
    '\t\t\t  <font color=#3200A4><a href="contenu_resul_fiche.asp?Fiche=671" target=contenu>LA FERME DES VIGNES</a></font><br>\r\n'.
    '\t\t\t  Halles Centrales<BR>\n'.
    'place Gaston Pailhou<BR>37000&nbsp;TOURS<br>\r\n'.
    '              T&eacute;l. : 02 47 38 60 19\r\n'.
    '\t\t\t  </b></font></p>\r\n'.
    '          </td>\r\n'.
    '        </tr>\r\n';
     
    $RE = '#<p><font size="2"><b>\r\n'.
          '\t\t\t  (?:<font color=[^>]+>'.
          '<a href="contenu_resul_fiche\.asp\?Fiche='.
          '\d+" target=contenu>)?([^>]+)(?:</a></font>)?<br>\r\n'.
          '\t\t\t  ((?:.+?<[brBR]{2}>\r?\n?)+)'.
          '(\d+)&nbsp;(.+?)<br>\r\n'.
          '              (T&eacute;[^\r\n]+)?\r\n'.
          '\t\t\t  </b></font></p>\r\n#';
     
    echo $RE;
    echo '<br/><br/>';
     
    $y = preg_match_all($RE,$ch,$matches);
    echo'<br/>$y = '.$y.'<br/><br/>';
    echo $matches[0];
     
    foreach($matches as $val){
    	echo'<br/>'.$val[0];}
     
    ?>


    Mais ça ne marche effectivement pas.
    $y ne vaut pas 1, il y a un problème de matching.



    Ce qui pose problème est le matching des caractères ’\r’ et ’\n’.

    Le code suivant ne marche pas:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    <?php
     
    $RE = '#AAA\\r#';
    $ch = 'amande AAA\r gertrude';
    $y = preg_match($RE,$ch,$matches);
    echo '$y = '.$y;
     
    ?>
    Avec $RE = '#AAA\r#'; non plus.



    En Python, je n’ai pas de problème avec ces caractères. En PHP, je ne comprends pas le problème.
    Est-ce que quelqu’un peut m’expliquer ?

    Je cherche de mon coté. Vois ce qu tu peux faire du tien avec la RE écrite correctement

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 6
    Par défaut
    Je viens de tester la nouvelle RE et bingo, c'est impec, je vais pouvoir passé a la suite du dev

    pour l'histoire du module curl, tu peux t'en passé en remplaçant ma fonction http_fetch_url() par file_get_contents($url) qui fait pratiquement la même chose..

    Sinon pour installé un module avec wamp, tu fais un clic sur l'icone dans le systray, PHP, PHP extensions puis tu coche php_curl, tu relance le service et voila ^^

    ca te servira peut-être pour une prochaine fois :p

    Encore merci pour ton aide , j'vais de suite me replongé dans l'code

  6. #6
    Membre Expert
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 418
    Par défaut
    OK. Merci pour les renseignements.




    Méfie toi: avec les regex, ça marche tant que ça ne foire pas.

    Je veux dire que s’il y a un jour dans la page une adresse qui présente encore une variation supplémentaire par rapport au masque que définit la RE, elle ne sera pas attrapée.

    Par exemple, si le nombre devant le numéro de téléphone (numéro qui est d’ailleurs facultatif) devait ne pas être constant un jour, ça ne matcherait plus. Je propose donc de remplacer ces blancs par \s*

    Pour fignoler, je propose aussi de remplacer les 3 portions '\t\t\t ’ par \s*

    et tant qu’à faire de remplacer <font size="2"> par <font size="\d"> et un <br> qui reste par <[brBR]{2}>

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    $RE = '#<p><font size="\d"><b>\r\n'.
          '\s(?:<font color=[^>]+>'.
          '<a href="contenu_resul_fiche\.asp\?Fiche='.
          '\d+" target=contenu>)?([^>]+)(?:</a></font>)?<br>\r\n'.
          '\s((?:.+?<[brBR]{2}>\r?\n?)+)'.
          '(\d+)&nbsp;(.+?)<[brBR]{2}>\r\n'.
          '\s(T&eacute;[^\r\n]+)?\r\n'.
          '\s</b></font></p>\r\n#';
    Tu as bien noté aussi que cette regex n’attrape pas la ligne
    FROMAGERS.COM
    Si tu veux la capter aussi, il faut changer \s*((?:.+?<[brBR]{2}>\r?\n?)+) en \s*((?:.+?<[brBR]{2}>\r?\n?)+)?




    Il me reste à comprendre pourquoi mon malheureux petit code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    <?php
    $RE = '#AAA\r#';
    $ch = 'amande AAA\r gertrude';
    $y = preg_match($RE,$ch,$matches);
    echo '$y = '.$y;
     ?>
    ne marche pas.


    Et d’ailleurs
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    <?php
    $RE = '#AAA\s#';
    $ch = 'amande AAA\t gertrude';
    $y = preg_match($RE,$ch,$matches);
    echo '$y = '.$y;
    ?>
    ne marche pas non plus.

Discussions similaires

  1. [RegEx] Analyse de code HTML d'une liste déroulante
    Par sigmoun dans le forum Langage
    Réponses: 7
    Dernier message: 19/08/2009, 13h57
  2. [RegEx] Analyser du code html
    Par Invité dans le forum Langage
    Réponses: 1
    Dernier message: 05/08/2009, 20h38
  3. [MySQL] Analyse de code HTML
    Par safari25 dans le forum PHP & Base de données
    Réponses: 4
    Dernier message: 12/06/2009, 17h06
  4. Analyse de code HTML et simplification par l'XML
    Par Punky65250 dans le forum XML/XSL et SOAP
    Réponses: 3
    Dernier message: 10/11/2005, 10h24
  5. Analyse de code HTML en réponse a une requête post.
    Par ghost942 dans le forum Composants VCL
    Réponses: 2
    Dernier message: 04/06/2005, 21h40

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