[Perl] projet téléchargement pages WEB

Bonjour,
svp, j'ai un projet qui sert à realiser un programme d'aspirateur d'un site en langage perl, et je veux que vous m'aidiez pour le réaliser, car j'ai pas encore maitrisé ce langage.
meci bien d'avance
Configuration: Windows XP
Internet Explorer 6.0

2 réponses

  1. Salut miss_info,

    Pour faire ça, y'a déjà wget sous Linux.

    Et l'aide :
    wget --help


    Ou encore :
    man wget


    Ou même :
    http://ubunblox.blogspot.com/2007/04/tutos-wget-et-ses-options.html

    Alors, pourquoi s'en priver !

    0
    1. Bon,

      comme j'aime bien faire du Perl je l'ai codé quand même...

      #!/usr/bin/perl
      use warnings;
      use strict;
      use LWP::UserAgent;
      use HTTP::Cookies;
      
      if (@ARGV != 1) {
      	die "Usage: $0 url_de_base\n";
      }
      my $url_de_base = shift; # recuperation du premier argument du programme
      
      my @liste_urls = ($url_de_base);
      
      my $ua  = LWP::UserAgent->new(
      		agent => 'Mozilla/4.73 [en] (X11; I; Linux 2.2.16 i686; Nav)',
      		cookie_jar =>
      		HTTP::Cookies->new( file => 'cookies.txt', autosave => 1 )
      		);
      
      # Expressions régulières pour extraire les liens contenus dans les 
      # pages web récoltées
      my @expressions = (
      		qr/(?:src|href)\s*=\s*('[\']+'|"[\"]+"|[^\s>]*)/i);
      my $re = '(?:'. join('|', @expressions) . ')';
      print "Expression régulière : $re\n";
      my %urls_visitees = ();
      
      my $url;
      while($url = shift(@liste_urls)) {
      	print "Récupération de $url\n";
      
      	# crée un agent et une requête
      	my $req = HTTP::Request->new( GET => $url );
      
      	# récupère la réponse
      	my $res = $ua->request($req);
      	if (not $res->is_success) {
      		warn $res->status_line;
      		next;
      	}
      
      	my $contenu = $res->content;
      
      	sauve_contenu($url, $contenu);
      	$urls_visitees{$url} = 1;
      	
      	# On ne s'intéresse à l'intérieur du contenu que si c'est du HTML
      	# sinon, on passe à l'URL suivante
      	next if $res->header( 'Content-Type' ) =~ m#/^text/html#;
      
      	my @urls = $contenu =~ m/$re/go;
      
      	print "URLs récupérées : @urls\n", '-' x 40, "\n";
      	@urls = normalise_filtre($url, @urls);
      	print "URLs filtrées : @urls\n";
      
      	# On verifie qu'elles n'ont pas deja ete visitees ou ajoutees
      	# dans la liste des URLs a visiter
      	my @urls_a_ajouter = ();
      	foreach (@urls) {
      		push @urls_a_ajouter, $_ if !exists $urls_visitees{$_};
      	}
      	print "URLs à visiter : @urls_a_ajouter\n";
      
      	# Si on décommente la ligne on récupère tout internet
      	#push @liste_urls, @urls_a_ajouter;
      	
      	# Admettons qu'on s'intéresse uniquement aux documents plus 
      	# loin dans l'arborescence que l'URL de base
      	my ($url_repertoire) = $url_de_base =~ m#^(http://[^/]*(/([^?/]+/)*)?)#i;
      	print "Nouvelles URLs à visiter : ";
      	foreach (@urls_a_ajouter) {
      		if (index($_, $url_repertoire) == 0) {
      			push @liste_urls, $_;
      			print "$_ ";
      		}
      	}
      	print "\n";
      	
      }
      
      # Fonction sauve_contenu ($url, $contenu)
      # sauvegarde le contenu $contenu de l'URL $url
      sub sauve_contenu {
      	my ($url, $contenu) = @_;
      
      	my ($serveur, $reste) = $url =~ m#http://([^/]+)(/.*)?#i;
      	$serveur =~ s/:\d+$//;# On enlève le port dans le cas toto.com:8080
      	$serveur =~ s/.*@//; # On enlève l'utilisateur et le mot de passe dans le cas user:pass@toto.com
      
      	if(!-d $serveur) {
      		mkdir $serveur;
      	}
      
      	my (@repertoires) = split('/', $reste);
      
      	my $path = $serveur;
      	foreach my $rep (@repertoires[1 .. $#repertoires-1]) {
      		$path .= '/' . $rep;
      		mkdir $path if !-e $path;
      	}
      
      	my $fichier = $repertoires[ $#repertoires ];
      
      	if ( (!defined $fichier) or ($fichier eq '/') or ($fichier eq '') ) {
      		$fichier = 'index.html';
      	}
      	if (-d "$path/$fichier") {
      		$path .= "/$fichier";
      		$fichier = 'index.html';
      	}
      
      	open(OUT, ">$path/$fichier") or die "Ouverture en écriture de $path/$fichier : $!";
      	print OUT $contenu;
      	close OUT;
      }
      
      sub normalise_filtre {
      	my $base = shift; # Recuperation de l,URL de base pour les URLs relatives
      	my ($url_site) = $base =~ m#^(http://[^/]*)#i;
      	print "URL du site : $url_site\n";
      	my ($url_repertoire) = $base =~ m#^(http://[^/]*(/([^?/]+/)*)?)#i;
      	print "URL du répertoire : $url_repertoire\n";
      	$url_repertoire .= '/' if $url_site eq $url_repertoire;
      	my @urls = ();
      	foreach (@_) {
      		print "Normalisons $_ : ";
      		s/^(['"])(.*)\1$/$2/;
      		s/(#.*)$//;
      		print "après première moulinette : $_  ";
      		if (/^\s*javascript/i){# On saute les liens/scripts javascript
      			print "\n";
      			next;
      		}
      		if (/^\s*(.*?)\s*$/) {
      			my $url_fragment = $1;
      
      			if (m#^http://#io) {
      				push @urls, $url_fragment;
      				print "On pousse $url_fragment\n";
      				next;
      			} elsif (m#^/#o) {
      				push @urls, ($url_site . $url_fragment);
      				print "On pousse $url_site$url_fragment\n";
      			} else {
      				push @urls, ($url_repertoire . $url_fragment);
      				print "On pousse $url_repertoire$url_fragment\n";
      			}
      		} else {
      			print "Je ne comprends pas ce qu'il y a dans cette URL...";
      		}
      	}
      	return @urls;
      }


      0