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érer certaines lignes contenu dans un tableau


Sujet :

Langage Perl

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Février 2008
    Messages
    30
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 30
    Points : 16
    Points
    16
    Par défaut Récupérer certaines lignes contenu dans un tableau
    Bonsoir,

    Voilà j'aimerais savoir comment je pourrais m'y prendre pour récupérer certaines lignes (dont je connais le début et la fin) d'un tableau qui contiendrait le code source d'une page html.

    Merci d'avance pour vos réponses,

    ++

  2. #2
    Membre régulier Avatar de krieg
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    75
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 75
    Points : 92
    Points
    92
    Par défaut
    Bonjour,
    Pour réaliser cela en perl il n'y a rien de plus simple,
    tu fais un passage sur tous les elements en testant chaque element
    avec

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    if($tab[i] =~ /debut(.*)fin/)

    bye

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Février 2008
    Messages
    30
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 30
    Points : 16
    Points
    16
    Par défaut
    Bonjour,

    Tout d'abord merci pour ta réponse. Finalement j'ai préféré stocker le résultat de ma page source dans un fichier (je ne vois pas comment mettre une page source ligne par ligne).

    Cependant je suis bloqué lors du parcours du fichier. Je souhaite mettre des lignes contenu dans la balise <PRE> </PRE> dans un autre fichier, mais le problème c'est que je ne vois pas, dans la pratique, comment lui faire comprendre qu'il doit remplir le fichier que pour les lignes entre les balises <PRE>.

    Merci d'avance pour les conseils et l'aide.

    ++

  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
    Je te conseille vivement d'utiliser un parseur HTML. Par exemple HTML::TreeBuilder ou HTML::Parser (au choix selon la taille de ton HTML et surtout tes préférences).

    Sinon tu peux bien sûr lire le contenu de ton fichier ou de ta page html dans une variable et récupérer l'information qui t'intéresse avec des expressions régulière.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    open my $fh, '<', 'file.html' or die "$!\n";
    my $page = do { local $/; <$fh>};
     
    # ou lire la page en ligne avec :
    # use LWP::Simple;
    # my $page = get('http://www.yourpage.hmtl');
     
    while ( $page =~ m{<pre>(.*?)</pre>}gs ) {
    	# fais ce que tu veux  avec $1, par exemple:
    	print $1;
    }
    Mais tu vas rencontrer de nombreux problème, si tu parse à la main. Par exemple si tes tags pre ont des attributs. Utilise plutôt un des parseurs du CPAN.

    Si tu ne comprends pas une partie du code ci-dessus, n'hésite pas à demander

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Février 2008
    Messages
    30
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 30
    Points : 16
    Points
    16
    Par défaut
    Merci pour la réponse.

    En ce qui concerne le parser, je n'ai jamais vraiment cerné qu'est ce que c'était, et donc en quoi cela peut être utile.

    J'ai essayé ton code mais rien ne passe, je n'ai même pas de message d'erreurs. Pourrais-tu le détailler stp ?

    Merci !

    ++

  6. #6
    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
    Si rien ne se passe, c'est que soit tes tags pre sont en majuscule ;-) soit ils ont des attributs.

    Voilà ce que fait le code :

    (1) il ouvre un handler sur le fichier et le passe dans une variable $fh
    (2) lit tout le contenu du fichier et le passe dans $page (c'est un "slurp"; en modifiant localement la variable de fin d'enregistrement $/ pour lire tout le fichier d'un coup et pas ligne à ligne) (il y avait une faute de frappe à cette ligne je l'ai corrigé : il manquait les <>).
    (3) pour chaque match, capture ce qu'il y a entre <pre> </pre>

    Comme je te l'ai dit c'est une mauvaise idée de parser à la main.

    Il vaut mieux utiliser un parseur. Voilà un exemple.

    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
    #!/usr/bin/env perl
    use strict; use warnings;
     
    use HTML::TreeBuilder::XPath;
     
    open my $fh, '<', 'file.html'
    	or die "$!\n";
     
    my $page = do { local $/; <$fh>};
     
    my $tree= HTML::TreeBuilder::XPath->new;
    $tree->parse( $page );
     
    my $nodes = $tree->findnodes( '//pre');
    while ( my $node = $nodes->shift() ) {
    	print $node->as_text();
    }

  7. #7
    Membre à l'essai
    Profil pro
    Inscrit en
    Février 2008
    Messages
    30
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 30
    Points : 16
    Points
    16
    Par défaut
    Je te remercie sincèrement car ça marche maintenant, et ça va m'éviter bien des heures sombres devant mon pc...

    J'ai testé la première méthode que tu m'as énuméré et je ne comprends pas pourquoi il ne faut pas parser manuellement puisque le résultat que je souhaitais est exactement celui que j'obtiens.

    ++

  8. #8
    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
    Le problème apparaît dès qu'il y a des attributs dans le tag ou des tags à l'intérieur du tag.

    Dans les cas simples ça peut marcher en effet.

  9. #9
    Membre à l'essai
    Profil pro
    Inscrit en
    Février 2008
    Messages
    30
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 30
    Points : 16
    Points
    16
    Par défaut
    J'ai un problème lorsque j'essaie de faire une boucle sur la récupération d'adresse (..../index.php?id=1, id=2, etc... où je mets une variable à la place du chiffre).

    Il me renvoit :

    readline() on closed filehandle $fh at perl.pl line 62.
    Use of uninitialized value in pattern match (m//) at perl.pl line 64.

    Je suppose donc qu'il faudra que je ferme le fichier avant de relancer la boucle, mais je ne vois pas comment faire .

  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
    En fait tu n'as pas besoin de mettre tes pages dans un fichier, tu peux faire directement (je suppose qu'elle sont en ligne) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    foreach (1..10) {
    my $page = get ( 'http://qwertyop.php?id=' . $_);
    }
    Si tu as déjà les pages sur ta machine, tu fais pareil avec un open (voit posts précédents), fais simplement attention aux chemins (les chemins absolus valent toujours mieux).

    Si ça ne marche pas, poste ton code, j'ai du mal à voir comme ça.

    Autre chose, pourquoi n'utilises-tu pas le code avec HTML::TreeBuilder::XPath ? C'est vraiment plus efficace.

  11. #11
    Membre à l'essai
    Profil pro
    Inscrit en
    Février 2008
    Messages
    30
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 30
    Points : 16
    Points
    16
    Par défaut
    J'ai essayé avec le parseur, en vain !

    J'essayerai ta méthode demain, merci !

  12. #12
    Membre à l'essai
    Profil pro
    Inscrit en
    Février 2008
    Messages
    30
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 30
    Points : 16
    Points
    16
    Par défaut
    Bon comme tu me l'as demandé, je vais poster le source. Il n'est pas très bien commenté, mais il y a des parties qui fonctionne bien donc il n'est pas nécéssaire que j'en dise plus.

    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
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    #! /bin/perl
    use warnings;
    use LWP;
    use DBI;
     
    ##########
    # Cette première partie concerne une requête renvoyant un nombre d'id (ce chiffre 
    # correspond en fait à un nombre de graphes
    # Cette requête fonctionne très bien, pas la peine de s'attarder dessus
    my $database = "cacti";
    my $hostname = "localhost";
    my $dsn = "DBI:mysql:database=$database;host=$hostname";
    my $user = "...";
    my $password = "...";
     
    $dbh = DBI->connect($dsn, $user, $password,
                          { RaiseError => 1, AutoCommit => 0 });
     
    my $req = $dbh->prepare("select count(*) as nombreId from graph_local");
     
    $req-> execute || die "Problème de selection... : $DBI::errstr";
     
    my $nombre = $req->fetchrow_array;
     
    $req-> finish;
     
    #################
    # Normalement je fais une boucle sur le nombre de graphes, mais pour 
    # faciliter les tests, je ne vais que jusqu'a 5                     
    my $indice = 1;
     
    while ($indice <= 5)
    { 
     
    	# J'utilise ce module pour me connecter à ma page (qui nécéssite 
    	# une authentification)
    	my $browser = new LWP::UserAgent;
    	my $request = new HTTP::Request( GET => "http://10.5.210.58/cacti/graph.php?						action=properties&local_graph_id=".$indice."&rra_id=0&view_type=tree&graph_start=-8600&graph_end=-300" );
     
    	$request->authorization_basic("...", "...");
     
    	my $response = $browser->request($request);
     
    	#######################################################
    	# Ici je renvoie le code source de ma page dans un fichier temp
    	# Quand j'éxécute le programme, je peux bien voir que mes fichiers 
    	# temporaires sont bien crées, avec le code de la page à l'intérieur
    	open (FSOR, "> temp".$indice.".txt") || die "Problème : $!"; 
     
     
    	if ($response->is_success) 
    	{
      		my $headers = $response->headers();         
     
      		print FSOR $response->content;
     
    	} 
    	else 
    	{
      		print "Erreur:".$response->status_line."\n";  
      	}
     
    	close FSOR;
    	########################################################
    	# Arrive maintenant la partie que tu m'as indiqué
    	# Après éxécution du programme, je m'aperçois que les fichiers 
    	# graph.sh sont vides
    	# Je pense donc que le problème se situe à ce niveau là, mais 
    	# je n'arrive pas à voir ou exactement
     
    	open (GRAPH, "> graph".$indice.".sh") || die "problème : $!";
     
    	open TEST, '<', 'temp'.$indice.'.txt';
    	my $page = do { local $/; <TEST>};
     
    	while ( $page =~ m{<PRE>(.*?)</PRE>}gs ) 
    	{
    		print GRAPH $1;
    	}
     
    	close GRAPH;
    	close TEST;
     
    	# ici, j'éxécute les scripts 
    	system("chmod +x graph".$indice.".sh");
    	system("./graph".$indice.".sh > graph".$indice.".png");
     
     
    	# J'incrémente l'indice ici
    	$indice++;	
    }
    Merci pour ton aide.

    ++

    edit : Je viens de m'aperçevoir qu'il manque les balises PRE (et donc ce qui se trouve dedans) mes fichiers temp.txt (ceux qui contiennent les sources de la page) .

    edit2 : Bon le problème était tout con, il venait de l'espacement dans l'url dont je voulais récupérer le code source.

    edit 3: iblis, pourrais-tu m'indiquer, si tu le sais, comment je pourrais mettre directement le code de ma page dans la variable $page ? Vu que je passe par une authentification cela ne peut pas s'effectuer aussi simplement que je le souhaiterais (enfin je n'y arrive pas).
    Passer par un fichier est certes plus simple mais aussi terriblement plus long...

    Merci d'avance iblis !

  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
    iblis, pourrais-tu m'indiquer, si tu le sais, comment je pourrais mettre directement le code de ma page dans la variable $page ?
    Si tu gardes ton code tel quel (authentification avec HTTP::Request), déclare simplement $page dans ton while et passe le contenu de la page à $page comme suit (je reprends ton 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
    while ($indice <= 5)
    { 
    *
    	my $browser = new LWP::UserAgent;
    	my $request = new HTTP::Request( GET => "..." );
    *	$request->authorization_basic("...", "...");
    *	my $response = $browser->request($request);
    *
    	my $page;*
    	if ($response->is_success) 
    	{
     
      		$page = $response->content;
       	} 
     
    	# ...
    }*
    Pour l'authentification et la récupération des pages tu pourrais aussi utiliser WWW::Mechanize qui est un wrapper très pratique autour de LWP::UserAgent.

  14. #14
    Membre à l'essai
    Profil pro
    Inscrit en
    Février 2008
    Messages
    30
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 30
    Points : 16
    Points
    16
    Par défaut
    Ah yes ! Je te remerçie vraiment ! Bon ben on peut considérer ce topic comme clos !

  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
    De rien (tu peux passer le topic en résolu).

    Mais si j'étais toi, je ferais ça un peu plus proprement (avec un parseur).

    Je te montre un exemple (cela peut servir à d'autres). Je me suis conformé à ton besoin mais on peut aisément le transformer pour extraire le code de quelques fils du forum Perl de developpez.net ;-)

    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
    use strict; use warnings;
     
    use WWW::Mechanize;
    use HTML::TreeBuilder::XPath;
    use Encode;
     
    my @urls = map { 'http://10.5.210.58/cacti/graph.php?action=properties&local_graph_id='
    		. $_
    		. '&rra_id=0&view_type=tree&graph_start=-8600&graph_end=-300' 
    	} (1..5);
     
    my $browser = WWW::Mechanize->new;
    $browser->credentials('uname', 'passwd');
     
    foreach my $url (@urls) {
     
    	my $page; 
    	if ( $browser->get($url)->is_success() ) {
    		$page = $browser->content();
    	}
    	else {
    		warn "Skipping $url:\n$browser->status_line\n";
    		next;
    	} 
     
    	my $tree= HTML::TreeBuilder::XPath->new;
    	$tree->parse( $page );
     
    	my $nodes = $tree->findnodes( '//pre');
    	while ( my $node = $nodes->shift() ) {
    		print encode("utf8",$node->as_text());
    		print "\n";
    	}
    	print "\n" x 3;
    }

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

Discussions similaires

  1. [MySQL] problème pour récupérer toutes les lignes contenue dans un select
    Par Baleze dans le forum PHP & Base de données
    Réponses: 2
    Dernier message: 25/10/2012, 20h42
  2. Réponses: 2
    Dernier message: 17/09/2012, 14h57
  3. [PowerShell] Récupérer certaines lignes d'un fichier txt dans un autre
    Par TanKer dans le forum Scripts/Batch
    Réponses: 7
    Dernier message: 16/11/2011, 21h31
  4. récupérer une valeur contenue dans une balise TD d'un tableau
    Par Himotep dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 16/06/2011, 22h48
  5. Réponses: 8
    Dernier message: 30/11/2006, 18h32

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