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 Perl Discussion :

Récupérations d'informations sur une page html


Sujet :

Langage Perl

  1. #1
    Membre du Club
    Inscrit en
    Octobre 2007
    Messages
    99
    Détails du profil
    Informations forums :
    Inscription : Octobre 2007
    Messages : 99
    Points : 47
    Points
    47
    Par défaut Récupérations d'informations sur une page html
    Bonjour à tous,

    Je souhaiterai créer un programme Perl, pour :
    -prendre en entrée (Input) un fichier .html. Et grâce à ce programme .pl
    -créer un fichier texte en sortie (Output), pour récupérer des informations précises dans la page .html.

    Je m'explique dans un exemple :
    C'est une page .html qui concerne la liaison entre gênes, maladies et médicaments.
    Et je voudrais grâce au programme parcourir et ressortir dans un fichier texte que 3 informations : les noms du gêne, du médicament et de la maladie.

    Je suis débubante dans ce langage, donc si vous pouvez me donner quelques pistes...On m'a parlée de "parsage d'un fichier", "expressions régulières"...

    Je vous remercie

  2. #2
    Membre confirmé Avatar de iblis
    Inscrit en
    Janvier 2007
    Messages
    510
    Détails du profil
    Informations personnelles :
    Âge : 57

    Informations forums :
    Inscription : Janvier 2007
    Messages : 510
    Points : 570
    Points
    570
    Par défaut
    Bonjour.

    Parser un fichier signifie le parcourir à la recherche d'information.

    Les expressions régulières sont (comme leur nom l'indique presque) des expressions permettant de matcher (= trouver par appariement) des motifs dans des chaînes de caractères.

    Par exemple, le script suivant lit un fichier texte depuis l'entrée standard et affiche chaque ligne commençant par une majuscule.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    #!/usr/bin/perl
    use strict; use warnings;
     
    while (<>) {
        print if /^[A-Z]/;
    }
    Voici comment afficher le premier mot de chaque ligne commençant par une majuscule (par capture).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    #!/usr/bin/perl
    use strict; use warnings;
     
    while (<>) {
        print $1, "\n" if /^([A-Z]\w*)\b/;
    }
    Un fichier HTML est un fichier texte, tu peux donc le parcourir et y chercher le motif que tu veux avec des regex (regular expression). Cela signifie que tu sais ce que tu cherches en terme de contenu (ie, tu peux en identifier la forme).

    Mais les fichiers HTML sont structurés, tu peux donc chercher l'information en fonction de là où elle se trouve avec plus d'acuité que dans un texte non formaté. Par exemple, au lieu de chercher le premier mot des lignes d'un texte simple, tu peux chercher toutes les parties de texte entre telle et telle balise, etc etc.

    Il y a deux grandes techniques pour parcourir et extraire de l'information de fichier html et xml : avec un modèle arborescent ou par gestion de flot — par exemple avec XML::XPath ou HTML::Parser. Tu peux bien sûr combiner les deux approches (par exemple avec XML::Twig).

    Personnellement, je préfère avoir recours à un modèle arborescent des pages HTML (il suffit de connaître le chemin vers l'information pour la récupérer) mais XPath demande des fichiers bien formés, ce qui n'est souvent pas le cas sur Internet.

    Voici un exemple utilisant la gestion d'état qui imprime tous les liens contenus dans un fichier html.
    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
    #!/usr/bin/perl
    use strict; use warnings;
    use HTML::Parser;
     
     
    # read page from stdin
    my $page;
    do { 
         local $/; 
         $page = <>;
    };
     
    # set parser
    my $parser = HTML::Parser->new( api_version => 3,
                        start_h => [\&start,"tagname, attr"],
                        );
    # start handle (what should the parser do when it encouters a tag)
    sub start {
        my ($tag, $attr) = @_;
        print $attr->{href}, "\n" if ($tag =~ /^a$/ and defined $attr->{href});
    }
     
    # parse
    $parser->parse($page);
    # end the parser
    $parser->eof;
    Cela devrait t'aider à y voir plus clair.

  3. #3
    Membre du Club
    Inscrit en
    Octobre 2007
    Messages
    99
    Détails du profil
    Informations forums :
    Inscription : Octobre 2007
    Messages : 99
    Points : 47
    Points
    47
    Par défaut
    Merci beaucoup pour toutes ces informations !!!

    Avant de me lancer dans un gros truc, j'essaie tout d'abord de prendre des informations d'un simple texte, pour les renvoyé sur un autre texte...
    Par exemple:

    Test1.txt :
    /////
    voila un fichier exemple dont il faut extraire des choses,

    gene:LDLR,
    drug:atrovastatine,
    disease: hypecholesterolemia
    /////

    Et grâce à un programme Perl, je pourrai ressortir sur un autre fichier texte seulement :

    Test2.txt :
    /////
    LDLR
    astrovastatine
    hypecholesterolemia
    /////


    Cependant je ne manipule pas encore assez bien Perl, pourrai vous m'aider à commencer ce programme

    Merci

  4. #4
    Membre confirmé Avatar de iblis
    Inscrit en
    Janvier 2007
    Messages
    510
    Détails du profil
    Informations personnelles :
    Âge : 57

    Informations forums :
    Inscription : Janvier 2007
    Messages : 510
    Points : 570
    Points
    570
    Par défaut
    As-tu testé mes deux premiers exemples ?

    Il ne faut pas les modifier beaucoup pour faire ce que tu veux (et bien plus). Familiarise-toi avec la syntaxe des regex.

    Peux-tu deviner ce que font les deux exemples qui suivent ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    while (<>) {
        print if /^gene:/;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    while (<>) {
        print $1 if /^gene:(.+)/;
    }
    ^ est l'ancre de début de chaîne. . dénote n'importe quel caractère. + est un quantifieur (postposé) signifiant "au moins une fois".

    Sans regex tu ne peux faire aucune recherche ou extraction un tant soit peu puissante dans un texte. Tu dois donc apprendre à t'en servir, personne ne peut le faire à ta place. Cela te sera utile quelque soit le langage que tu utilises pour traiter du texte.

    Pour apprendre, il faut se jeter à l'eau. Teste ce que je t'ai montré, puis modifie les exemples et vois ce que cela donne.

    Tu peux poster tes essais et tes questions ici.

  5. #5
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    Pour t'initier aux expressions rationnelles, tu peux lire perlrequick et perlretut.

    --
    Jedaï

  6. #6
    Membre du Club
    Inscrit en
    Octobre 2007
    Messages
    99
    Détails du profil
    Informations forums :
    Inscription : Octobre 2007
    Messages : 99
    Points : 47
    Points
    47
    Par défaut
    Bonjour à tous,

    J'ai tenté quelques trucs...mais cependant j'ai un petit problème, je voudrais que l'on m'affiche les résultats dans le fichier text ExempleSimple_sor.txt
    Et je ne l'ai retrouve pas

    Voici mon code
    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
    #!/usr/bin/env perl
     
    #       ouvrir le fichier entree
    open(fichier_entre, "ExempleSimple_ouv.txt");
    #       ouvrir le fichier sortie
    open(fichier_sortie, ">ExempleSimple_sor.txt");
     
    #       lire le fichier ExempleSimple_ouv dans 
    @tableau_ouv = <fichier_entre>;
    #       fermer le fichier_entré
    close(fichier_entre);
    #       parcourir le tableau, en enregistrant
    #       les occurrences sur le scalaire $ligne
     
    $_1 = "gene : LDLR,";
    if (/(\S+) : (\S+),/){
    	print "le nom du gène est $2.\n";
    }
     
    $_2 = "drug : atrovastatine,";
    if (/(\S+) : (\S+),/){
    	print "le nom du médicament est $2.\n";
    }
     
    $_3 = "disease : hypecholesterolemia.";
    if (/(\S+) : (\S+)./){
    	print "le nom de la maladie est $2.\n";
    }
     
           #       ...et l'enregistrer sur
           #       le fichier_sortie
           print fichier_sortie "$_1\n $_2\n $_3\n";
     
    #       fermer le fichier_sortie
    close(fichier_sortie);
    #       FIN

    Si vous pouviez m'aider...m'expliquer ce qui ne va pas.

    Merci

  7. #7
    Membre du Club
    Inscrit en
    Octobre 2007
    Messages
    99
    Détails du profil
    Informations forums :
    Inscription : Octobre 2007
    Messages : 99
    Points : 47
    Points
    47
    Par défaut
    Enfaite j'ai trouvé mon erreur...

    De plus j'ai crée 2 programmes pour trouver le même résultat :

    Essai_1 :
    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
    #!/usr/bin/env perl
     
    #       ouvrir le fichier entrée
    open(fichier_entre, "ExempleSimple_ouv.txt") || die "Erreur E/S : $!\n";
     
    #       ouvrir le fichier sortie
    open(fichier_sortie, ">ExempleSimple_sor.txt") || die "Erreur E/S : $!\n";
     
    #       fermer le fichier_entré
    close(fichier_entre);
     
    #       parcourir le tableau
     
    $_ = "gene : LDLR";
    if (/(\S+) : (\S+)/){
    	print fichier_sortie "le nom du gene est $2.\n";
    }
     
    $_ = "drug : atrovastatine";
    if (/(\S+) : (\S+)/){
    	print fichier_sortie "le nom du médicament est $2.\n";
    }
     
    $_ = "disease : hypecholesterolemia";
    if (/(\S+) : (\S+)/){
    	print fichier_sortie "le nom de la maladie est $2.\n";
    }
     
    close(fichier_sortie);
    #       FIN

    Et Essai_2 :
    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
    #!/usr/bin/env perl
     
     
    print "Veuillez indiquer le nom du fichier à ouvrir\n"; 
       $input = <STDIN>; 
       chomp($input); 
       open ("fichier", $input) || die "Erreur E/S : $!\n";
     
     
    print "Indiquez dès maintenant le nom du fichier résultat:\n"; 
      $input = <STDIN>; 
      chomp($input); 
      #      ouvrir le fichier sortie
      open(fichier_sortie, ">$input");
     
     
    $_ = "gene : LDLR";
    if (/(\S+) : (\S+)/){
    	print fichier_sortie "le nom du gene est $2.\n";
    }
     
    $_ = "drug : atrovastatine";
    if (/(\S+) : (\S+)/){
    	print fichier_sortie "le nom du médicament est $2.\n";
    }
     
    $_ = "disease : hypecholesterolemia";
    if (/(\S+) : (\S+)/){
    	print fichier_sortie "le nom de la maladie est $2.\n";
    }
     
    #      fermer le fichier_sortie
    close(fichier_sortie);
    #      FIN

    Cependant je m'intéresse à une autre problématique :
    - Essayer de passer en paramètre les noms des fichiers :
    pour que ma commande soit du genre : perl Essai_3.pl ExempleSimple_ouv.txt ExempleSimple_sor.txt

    - Essayer aussi de modifier le fichier d'entrée pour avoir l'entête sur une
    ligne et le contenu sur une autre du genre :
    Gene:
    LDLR
    Disease:
    hypercholesterolemia
    Drug:
    astrovastatine


    Je demande vos aides, parce que je ne vois pas comment faire (quelles expressions régulières utilisées...)

    Merci d'avance pour vos réactions et informations

  8. #8
    Membre du Club
    Inscrit en
    Octobre 2007
    Messages
    99
    Détails du profil
    Informations forums :
    Inscription : Octobre 2007
    Messages : 99
    Points : 47
    Points
    47
    Par défaut
    Après plusieurs recherches sur le net, j'ai trouvé comment écrire (dans le fichier sortie) :

    Gene:
    LDLR
    Disease:
    hypercholesterolemia
    Drug:
    astrovastatine

    Cependant pour la première chose ;

    - Essayer de passer en paramètre les noms des fichiers :
    pour que ma commande soit du genre : perl Essai_3.pl ExempleSimple_ouv.txt ExempleSimple_sor.txt

    j'ai vu que je devais une entrée avec l'opérateur diamant et/ou utiliser l'argument d'invocation @ARGV.
    Malheureusement cela est compliqué à comprendre et surtout difficile à adapter à mon probléme..

    Aidez moi, merci

  9. #9
    Membre confirmé Avatar de iblis
    Inscrit en
    Janvier 2007
    Messages
    510
    Détails du profil
    Informations personnelles :
    Âge : 57

    Informations forums :
    Inscription : Janvier 2007
    Messages : 510
    Points : 570
    Points
    570
    Par défaut
    Voici comment traiter les arguments passés en ligne de commande.

    1. Dans les cas les plus simples, tu traites la liste des arguments que perl passe dans @ARGV toi-même.

    Exemple 1 (j'en profite pour te montrer comment ouvrir proprement des fichiers):
    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
     
    die "usage: $0 file1 file2\n" if scalar @ARGV !=2;
    (my $filename1, my $filename2) = @ARGV;
     
    open my $fh1, '<', $filename1
        or die "Could not open $filename1: $!\n";
    open my $fh2, '>', $filename2
        or die "Could not open $filename1: $!\n";
     
    while (<$fh1>) {        # loop through lines of opened file
        s///;             # do whatever you want on each line
        print $fh2 $_;   # print to file (! no comma between arguments)
    }
     
    close $fh1;
    close $fh2;
    2. Tu peux aussi dans certains cas (beaucoup en fait) profiter de l'opérateur <> (diamond).


    Exemple 2:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    while (<>) {    # loop through lines of files passed as argument or of stdin if no files
        s///;     # do whatever you want on each line
        print;    # print to stdout
    }
    Là, deux cas se présentent: a) tu ne passes pas d'argument au script, perl lit alors l'entrée standard dans la boucle while. b) tu passes des arguments : ils sont interprétés comme des noms de fichiers que perl ouvre (et ferme) pour toi et dont il passe chaque ligne à la boucle (pour chaque fichier les uns à la suite des autres). Très pratique, n'est-ce pas? Tu n'as plus qu'à écrire sur la sortie standard, par exemple.

    Lire et écrire l'entrée et la sortie standards a un avantage majeur: tu peux utiliser la redirection et les pipes avec tes scripts.

    (suite au prochain épisode)

  10. #10
    Membre confirmé Avatar de iblis
    Inscrit en
    Janvier 2007
    Messages
    510
    Détails du profil
    Informations personnelles :
    Âge : 57

    Informations forums :
    Inscription : Janvier 2007
    Messages : 510
    Points : 570
    Points
    570
    Par défaut
    (suite et fin)

    3. Autre variante innattendue: tu peux aussi intégrer les données à lire dans le fichier du script. Très utile pour les tests notamment (mais pas seulement). Un exemple vaut mieux qu'un long discours.

    Exemple 3
    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
     
    #!/usr/bin/perl
    use strict; 
    use warnings;
     
    use Encoding "utf8";
     
    while (<DATA>) {
        chomp;
        my $flip = // ... //;
        print "Rien ne sert de $_, " if $flip == 1;
        print "il faut $_ à point\n" if $flip == 2;        
    }
     
    __DATA__
    courrir
    chérir
    fleurir
    mûrir
    guérir
    mourir
    quérir
    nourrir
    périr
    pourrir
    tarir
    sûrir
    Les opérateurs .. et ... en contexte scalaire font office de bascule (voir la contribution de Jedaï dans un fil récent), ce qui permet d'alterner les lignes.


    4. Pour traiter les options passées en argument de ligne de commande, plutôt que de le faire à la main, trois possibilités s'offrent à toi (du plus élémentaire au plus puissant) : -s, Getopt::Std, Getopt::Long.

    Exemple non numéroté
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    #!/usr/bin/perl -s
    warn "Option x is set" if $x;
    while (<>) {
        s/x//g if $x;
        print;
    }
    En fait l'usage du commutateur -s (pour switch) a beaucoup de défaut: la récupération de l'argument passé en option (-x=no) ne fonctionne pas sur tous les systèmes et les variables ne sont pas globales (donc ne ça ne passe pas avec le pragma strict). Mais c'est pas plus mal de savoir que ça existe.


    Getopt::Std est lui très bien pour gérer les switchs simples. Là encore, un exemple dit tout.

    Exemple 4
    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
     
    use Getopt::Std;
     
    my %opts;
    getopts('ae', \%opts);
    my $arg = shift;
    die "Usage: $0 [-a | -e] filename\n"
            if (not defined $arg or $opts{a} && $opts{r}); # allow either -a or -e
     
    open my $fh, '<', $arg
        or die "Could not open $arg: $!\n";
     
    while (<$fh>) {
        s/a/e/g if $opts{a};
        s/e/a/g if $opts{e};
    }
    Getopt::Long permet de gérer des configurations complexes d'options courtes et longues. Je te laisse explorer la doc.

  11. #11
    Membre du Club
    Inscrit en
    Octobre 2007
    Messages
    99
    Détails du profil
    Informations forums :
    Inscription : Octobre 2007
    Messages : 99
    Points : 47
    Points
    47
    Par défaut
    Merci Iblis pour toutes ces informations, jai ainsi pu réalisé mon programme...

    J'ai réussi a manipuler le tableau @ARGV

    Merci Beaucoup pour ta patience

    Je n'hésiterai à revenir pour exposer mes questions, quand je devrais récupérer des informations d'un fichier format html...(si j'ai des soucis)

    Encore merci

  12. #12
    Membre du Club
    Inscrit en
    Octobre 2007
    Messages
    99
    Détails du profil
    Informations forums :
    Inscription : Octobre 2007
    Messages : 99
    Points : 47
    Points
    47
    Par défaut Autre Problème
    Bonjour à tous,

    J'ai copié-collé un script html (code source) sur un fichier texte.

    Voici mon code :
    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
    #!/usr/bin/env perl
    use strict;
    use warnings;
     
    #       ouvrir le fichier entré
    open(fichier_entre, "Code_Source.txt") || die "Erreur E/S : $!\n";
     
    #       ouvrir le fichier sortie
    open(fichier_sortie, ">noms_alternatifs.txt") || die "Erreur E/S : $!\n";
     
    #       lire le fichier entré dans 
    #       le tableau_entrée
    my @tableau_entre = <fichier_entre>;
    my $ligne;
     
    #       fermer le fichier_entré
    close(fichier_entre);
     
     
    foreach $ligne (@tableau_entre) {
     
    	 if ($ligne =~ m/^"(<td>+\w+"Alternative Names:".*<\/td>{1})"$/) {
                     print fichier_sortie "$ligne\n";
            }
    	else {
    		exit;
    	}
    }
     
    # fermer le fichier_sortie
    close(fichier_sortie);
    Je dois récupérer dans la page html :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    <td class="fieldName">Alternate Names:</td>
            <td class="fieldValue">
     
     
    LDL receptor; LDLR precursor</td>
    les mots LDL receptor et LDLR precursor...Il y a surement un problème dans mes expressions régulières !!
    Je voudrais que ma phrase commence par <td et se termine par <\td>, qu'il y ai des caractères entre, mais dès qu'il voit "Alternate Names:" il recopie le reste de la phrase dans le fichier de sortie.


    De plus je ne sais pas remplaçer un fichier texte comme "fichier_entre", par un lien http://...

    Pouvez vous m'aider?
    Merci

  13. #13
    Membre confirmé Avatar de iblis
    Inscrit en
    Janvier 2007
    Messages
    510
    Détails du profil
    Informations personnelles :
    Âge : 57

    Informations forums :
    Inscription : Janvier 2007
    Messages : 510
    Points : 570
    Points
    570
    Par défaut
    Pourquoi n'ouvres-tu pas un nouveau fil, tu auras plus de réponses

    Ce n'est pas une très bonne idée de mettre ton fichier dans un tableau, pour au moins 2 raisons :
    1. La mémoire requise à l'exécution croit alors avec la taille du fichier. De plus tu n'en as pas besoin, puisqu'ensuite tu ne fais que lire les lignes séquentiellement.
    2. Si ton information est morcelée sur plusieurs lignes (fréquent dans du html) tu vas avoir du mal à la traiter. C'est le cas dans ton exemple.
    Concernant le point 1, je t'ai montré comment lire un fichier ligne par ligne. Mais ce n'est plus la question.

    Car le point 2 est plus délicat. Comme je te le disais dans le mon post pour parser du html, il vaut mieux ne pas le faire à la main. Il y a de très bon modules sur le CPAN qui gèrent cela très (très) bien. Regarde l'exemple que je t'ai donné dans mon premier post. Essaie de le comprendre (va voir la doc sur le CPAN en cas de besoin) et modifie-le pour qu'il réponde à ton problème.

  14. #14
    Membre du Club
    Inscrit en
    Octobre 2007
    Messages
    99
    Détails du profil
    Informations forums :
    Inscription : Octobre 2007
    Messages : 99
    Points : 47
    Points
    47
    Par défaut
    Dacc merci.

    Mais j'ai relu ton code parlant de HTML:arser .
    Je le comprend pas très bien enfaite : Pourrai tu me l'expliquer plus en détail ?

    Cependant je vais faire un tour sur le site de CPAN, pour me documenter.

    Merci

  15. #15
    Membre confirmé Avatar de iblis
    Inscrit en
    Janvier 2007
    Messages
    510
    Détails du profil
    Informations personnelles :
    Âge : 57

    Informations forums :
    Inscription : Janvier 2007
    Messages : 510
    Points : 570
    Points
    570
    Par défaut
    Reprenons rapidement l'exemple avec HTML::Parser (je parse cette fois le fichier lui-même)
    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
    #!/usr/bin/perl
    use strict; use warnings;
    use HTML::Parser;
     
    # get argument
    my $filename = shift || 'myfile.html'; 
     
    # open file
    open $fh, '<', $filename
        or die "$!\n";
     
    # set parser
    my $parser = HTML::Parser->new( api_version => 3,
                        start_h => [\&start,"tagname, attr"],
                        );
    # start handle (what should the parser do when it encouters a tag)
    sub start {
        my ($tag, $attr) = @_;
        print $attr->{href}, "\n" if ($tag =~ /^a$/ and defined $attr->{href});
    }
     
    # parse
    $parser->parse_file($fh);
     
    # end parser
    $parser->eof;
    A la création du parser, le hash d'option déclare le handler de start, c'est à dire indique quelle subroutine executer chaque fois que le parser rencontre un tag (un tag de début <>, donc pas un </>) et quel informations le parser va lui passer comme argument. On lui passe donc une référence vers la subroutine en question qu'on va écrire) et on lui indique grâce au mots clé tagname et attr que le parser devra lui passer 1. le nom du tag rencontré 2. une référence vers un hash contenant les attributs du tag.

    Ensuite on définit notre subroutine qui sera éxécutée à chaque rencontre de tag. Là, si le tag est <a> et qu'il a un attribut href on affiche cet attribut.

    Y a plus qu'à lancer le parser dans le corps du programme.

    C'était juste un exemple pour te montrer comment ça marche (sinon HTML::LinkExtor fait ça très bien). Bien sûr tu as a ta disposition une gestion de handlers de fin de tag, de texte contenu dans les tag etc. Regarde la doc.

    Si tu veux t'entraîner modifie l'exemple pour qu'il imprime le texte entre balise de liens.

Discussions similaires

  1. [PHP 5.3] Récupération d'information sur une page web avec identification.
    Par vindkald dans le forum Langage
    Réponses: 4
    Dernier message: 14/05/2011, 08h23
  2. Récuperer des informations sur une page html
    Par shibby1337 dans le forum Débuter avec Java
    Réponses: 2
    Dernier message: 22/11/2008, 15h32
  3. comment rediriger sur une page html en fonction de la langue
    Par pierrot10 dans le forum Balisage (X)HTML et validation W3C
    Réponses: 2
    Dernier message: 10/08/2005, 11h42
  4. Marge sur une page HTML
    Par wollverine dans le forum Balisage (X)HTML et validation W3C
    Réponses: 4
    Dernier message: 28/04/2005, 13h56
  5. Problème de chaine sur une page HTML
    Par Kerod dans le forum Général JavaScript
    Réponses: 8
    Dernier message: 23/11/2004, 16h23

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