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 :

Capture de lien [RegEx]


Sujet :

Langage PHP

  1. #1
    Membre averti
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2011
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Mai 2011
    Messages : 12
    Par défaut Capture de lien
    Bonjour ,

    Je bute sur une regex et je n'arrive pas à continuer mon boulot sans elle, alors après quelques recherches infructueuses je me permet de vous solliciter pour trouver mon bonheur :p.

    En bref à partir du code HTML d'une page je souhaite obtenir un lien qui contient un mot clé et capturer différentes partie de ce lien, exemple (ici le mot clé sera "contact") :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <a href="presse/nous-contacter/"  >Nous contacter</a>
    Ici j'aimerais tout d'abord trouver ce lien et capturer '<a href="' , 'presse/nous-contacter/' , et '" >Nous contacter</a>', jusque la pas de problème j'y parviens grâce à cette regex :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    (<a [^>]*href=["']{1})([^"']*)(["']{1}[^>]*>[^<]*?contact[^<]*?</a>)
    Je n'avais pas réfléchi à un cas qui pourrait se présenter, parfois le lien est de la forme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <a ...><strong>*contact*</strong></a>
    et dans ce cas la... ma regex ne capture pas puisque j'utilisais [^<]* pour ne pas avoir plusieurs liens capturés en même temps.

    Ce que je cherche à faire c'est capturer un lien peu importe ce qu'il y a comme balises (sauf </a> balise fermante du lien..) entre <a> et </a> , mais je n'y parviens pas si je vire les [^<]* de chaque coté de contact je me retrouve avec des matchs de plusieurs liens, et je ne sais pas comment faire pour dire "n'importe quel caractère tant qu'il n'y a pas cette chaine (</a>).

    Un petit coup de main ne serait pas de refus
    J'espère que je ne vous ai pas perdu en route, je ne suis pas très doué pour les explications...
    Merci

  2. #2
    Expert confirmé

    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    7 920
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 7 920
    Par défaut
    pour parser du HTML c'est DOMDocument et grace a XPath tu pourras faire une recherche sur le mot désiré

  3. #3
    Membre averti
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2011
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Mai 2011
    Messages : 12
    Par défaut
    Re, merci de ta réponse,

    Je suis au courant qu'il existe des library pour parser du HTML j'utilise simple_html_dom pour une autre partie de mon script.
    Ici vu que mon critère de recherche est entre les balises et non un attribut des balises, cela reviendrait à parser tous les liens puis faire une recherche dans chacun d'eux... je ne sais pas si cela serait efficace niveau perf.

    J'ai regardé un peu la doc XPath (que je ne connaissais pas au passage, merci) mais je ne vois pas trop comment cette lib pourrait m'aider... Il me semble que le problème soit le même on peut trier en fonction des attributs mais pas du contenu, si ?

    Je me trompe peut-être, j'ai juste regardé vite fait XPath mais des exemples que j'ai vu aucun ne présente la possibilité de faire ce que je souhaite.

    Je passerais par la méthode du parser + recherche individuelle si rien de mieux ne se présente en attendant si quelqu'un à une autre solution...

  4. #4
    Expert confirmé

    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    7 920
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 7 920
    Par défaut
    tu peux faire ça avec la fonctions contains de xpath :
    http://support.microsoft.com/kb/304265

  5. #5
    Membre averti
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2011
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Mai 2011
    Messages : 12
    Par défaut
    Hum.. ça parait bien, merci je met résolu si je réussi à l'implémenter

  6. #6
    Membre averti
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2011
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Mai 2011
    Messages : 12
    Par défaut
    Encore moi, il doit y avoir un truc qui m’échappe...

    J'ai fait ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    $doc = new DOMDocument();
    @$doc->loadHTML($corps);
     
    $xpath = new DOMXPath($doc);
    $elements = $xpath->query("//a[contains(.,'contact')]");
    while(list( , $node) = each($elements)) {
    	echo $node->asXML();
    }
    Mais ça ne me renvoie rien... pourtant j'ai vérifié à la main et il y a bien des liens qui contiennent "contact" : /

    cf php.net

    Edit :
    En fait si je met un echo "test"; dans ma boucle ça n'affiche toujours rien donc je suppose que c'est ma requête xpath qui ne renvoie pas de résultat, y aurait-il une erreur de syntaxe ?

  7. #7
    Expert confirmé

    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    7 920
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 7 920
    Par défaut
    il faut toujours mettre le niveau d'erreur au maximum quand tu développes,
    asXML c'est du SimpleXML pas du DOMDocument

  8. #8
    Membre averti
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2011
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Mai 2011
    Messages : 12
    Par défaut
    Mon niveau d'erreur est à E_ALL | E_STRICT et j'ai mis le "@" devant le load parce que certaines pages que je scan sont tellement mal faites qu'elles génèrent des warning lors du chargement du genre :

    Warning: DOMDocument::loadHTML() [domdocument.loadhtml]: error parsing attribute name in Entity, line: 29 in C:\wamp\www\getContact\lib.php on line 12

    J'ai test saveHTML() mais nada...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    $xpath = new DOMXPath($doc);
    //$elements = $xpath->query("//a[contains(.,'contact')]");
    $elements = $xpath->query('//a');
    while(list( , $node) = each($elements)) {
         echo $node->saveHTML();
    }
    J'ai fait une requête plus simple avec juste les liens mais pas de résultats...

  9. #9
    Expert confirmé

    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    7 920
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 7 920
    Par défaut
    pour ne pas afficher les erreurs c'est libxml_use_internal_errors

    saveHTML() ne marche que sur un DOMDocument, si tu veux voir le contenu du node c'est nodeValue

    t'as boucle n'est pas bonne non plus, utilise un foreach sur $elements

  10. #10
    Membre averti
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2011
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Mai 2011
    Messages : 12
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    $doc = new DOMDocument();
    @$doc->loadHTML($corps);
     
    $xpath = new DOMXPath($doc);
    //$elements = $xpath->query("//a[contains(.,'contact')]");
    $elements = $xpath->query('/html/body/a');
    foreach($elements as $element){
    	echo $element->nodeValue."<br/>\n";
    }
    Ça match un truc mais euh... rien a voir avec ce que j'ai demandé il me choppe un lien en bas de page, et entre les balises de ce lien il y a du JS, enfin bref bizarre qu'il ne trouve pas les autres liens qui sont tout simple comme <a href="contact/">Contact</a> ...

    Je sens que je vais passer sur une autre solution
    Par contre pour nodeValue c'est pas tout à fait ce que je veux, je souhaite récupérer le code html pas le contenu de la balise.

  11. #11
    Expert confirmé

    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    7 920
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 7 920
    Par défaut
    je comprend pas ta mis 3 code et t'as fait 3 requêtes différentes... pourquoi ?
    si tu veux récupérer le lien il faut faire un getAttribute avec href, ou directe le faire dans ta requete xpath ( @href)

  12. #12
    Membre averti
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2011
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Mai 2011
    Messages : 12
    Par défaut
    Oui désolé, c'est que j'ai fait quelques test et j'ai pas fait gaffe à ce que je copiais, en gros ce que je veux c'est trouver les liens qui contiennent "contact" entre leurs balises et récupérer l'adresse qu'ils pointent.
    Ex :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <a href="pouet/">contact</a>
    Il n'y a pas contact dans le href mais on s'en fou on veut juste que ce soit dans les balises donc on choppe "pouet/" comme adresse.

    Pensant que le problème venait du contains j'avais test sur n'importe quel lien mais même résultat.

    Sinon bah j'ai contourné le problème avec une autre méthode plus lente... :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    $html = new simple_html_dom();
    $html->load($corps);
    $resultA=$html->find("a");
    foreach($resultA as $current){
    	if(preg_match("#>.*contact.*<#i",$current)){
    	         echo htmlentities($current)."<br/>";
            }
    }
    mais la solution m’intéresse toujours

  13. #13
    Expert confirmé

    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    7 920
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 7 920
    Par défaut
    la requete xpath c'est : //a[contains(.,'contact')]/@href

  14. #14
    Membre averti
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2011
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Mai 2011
    Messages : 12
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    $doc = new DOMDocument();
    @$doc->loadHTML($corps);		
    $xpath = new DOMXPath($doc);
    $elements = $xpath->query("//a[contains(.,'contact')]/@href");		
    foreach($elements as $element){
    	echo $element->nodeValue."<br/>\n";
    }
    Ne renvoie rien alors que :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    $html = new simple_html_dom();
    $html->load($corps);
    $resultA=$html->find("a");
    foreach($resultA as $current){
    	if(preg_match("#>.*?contact.*?<#i",$current)){
    		echo htmlentities($current)."<br/>";
    	}
    }
    me renvoie un lien... le principe est le même mais pas le résultat

  15. #15
    Expert confirmé

    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    7 920
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 7 920
    Par défaut
    tu vérifies même pas les valeurs de retour, le @href te reverras un DOMAttr, y'a pas de nodeValue

  16. #16
    Membre averti
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2011
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Mai 2011
    Messages : 12
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    echo $element->value."<br/>\n";
    ? Nothing new

  17. #17
    Expert confirmé

    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    7 920
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 7 920
    Par défaut
    Bizarre la page n'est pas valide ?

  18. #18
    Membre averti
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2011
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Mai 2011
    Messages : 12
    Par défaut
    Re, désolé de ne pas avoir répondu plus tôt, les pages ne sont pas toujours valides en effet, la solution que j'ai proposée au dessus est correcte niveau performance et répond à mes attentes donc je pense que je vais laisser tel quel.

    Merci de ton aide

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Une capture d'écran sur ce cours a un lien cassé
    Par [ZiP] dans le forum Evolutions du club
    Réponses: 4
    Dernier message: 20/08/2011, 12h50
  2. Capturer le retour vers mon site aprés avoir visité des liens externes
    Par ammouna24 dans le forum Général Conception Web
    Réponses: 3
    Dernier message: 12/06/2009, 14h57
  3. Réponses: 4
    Dernier message: 26/02/2008, 17h57
  4. [Kylix] Création d'un fichier lien
    Par DrQ dans le forum EDI
    Réponses: 2
    Dernier message: 14/05/2002, 21h30
  5. Tutoriels et liens pour le Borland Database Engine
    Par Community Management dans le forum Paradox
    Réponses: 0
    Dernier message: 25/03/2002, 10h23

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