[perl] récupéré le code source de plusieurs pages

récupéré le code source de plusieurs pages [perl] - Perl - Programmation

Marsh Posté le 13-08-2005 à 19:15:21    

bonjour.
je me lance dans le perl depuis quelque jour en lisant des ebook sur des sites internet.
et voici mon tout premier projet dont je bloque un peu.
(c'est de récupéré les page d'un site web (la source) toutes les information qui se trouve entre la balise <pre> </pre> sa fonctionne bien mais je n'arive pas a se qu'il m'afiche sa a toute les page du site cad de la page /proxy/index.php a /proxy/proxy-20.htm.
voila mon code (la il afiche la source de l'index entre la balise <pre> </pre> mais aps des autre page je ne sait pas comment faire j'ai esailler avec uen boucle for mais je n'y suis aps ariver)
 
#!usr/bin/perl -w
use IO::Socket;
$url = "www.samair.ru";
$socket = IO::Socket::INET->new( Proto => "tcp",
PeerAddr => "$url",
PeerPort => "80" );
print $socket "GET /proxy/index.php HTTP/1.1\nHost: $url:80\nConnection: Close\n\n";
while (my $ligne = <$socket> ){
if ($ligne =~ /(\d+).(\d+).(\d+).(\d+):(\S+)/gi) {
print ("ip: $1.$2.$3.$4 port: $5\n" );
}
else {
}
}
 
aidez moi svp, merci d'avance.


Message édité par K0rN111 le 13-08-2005 à 19:16:41
Reply

Marsh Posté le 13-08-2005 à 19:15:21   

Reply

Marsh Posté le 13-08-2005 à 22:04:04    

il faut que tu ferme et réouvre ton socket (connection close)
 
pourkoi n'utilise tu pas simplement LWP::simple?
 

Code :
  1. use LWP::Simple;
  2. for (@urls) {
  3.   my $source = get($_);
  4.   # regexp et autres traitement sur $source...
  5. }

Reply

Marsh Posté le 13-08-2005 à 22:59:40    

parce que je n'arive pas a se qu'il utilise ma regex avec lwp::simple regex + la boucle  :pt1cable:  
 
#!usr/bin/perl -w
use LWP::Simple;
$source = get("http://www.samair.ru/proxy/" );  
print "$source\n"

Reply

Marsh Posté le 13-08-2005 à 23:18:22    

tu veux recuperer koi exactement?

Reply

Marsh Posté le 13-08-2005 à 23:23:10    

j'aimerai récupéré tout les proxy ainsi que leur port présent entre la balisse <pre> </pre> (quand tu regard la source de la page) mais pas uniquement dans la page numéro 1 (proxy-0.1.htm) mais dans toute les page cad de la page proxy-01.htm a proxy-20.htm
 
merci.

Reply

Marsh Posté le 13-08-2005 à 23:23:55    

tiens, un exemple qui met les ips dans un tableau pour les pages de proxy-01 (index) à proxy-20 :
 

Code :
  1. use strict;
  2. use warnings;
  3. use LWP::Simple;
  4. my @ip_list;
  5. my @url_list = map {"http://www.samair.ru/proxy/$_"} ('index.htm', map{sprintf('proxy-%02d.htm', $_)} (2..20));
  6. for my $url (@url_list) {
  7. print "$url\n";
  8. push @ip_list, get($url) =~ /((?:\d{1,3}\.){3}\d{1,3})/g;
  9. }
  10. print join("\n", @ip_list);

Reply

Marsh Posté le 13-08-2005 à 23:25:42    

ha merde il manquait les ports!
 

Code :
  1. use strict;
  2. use warnings;
  3. use LWP::Simple;
  4. my @ip_list;
  5. my @url_list = map {"http://www.samair.ru/proxy/$_"} ('index.htm', map{sprintf('proxy-%02d.htm', $_)} (2..20));
  6. for my $url (@url_list) {
  7. print "$url\n";
  8. push @ip_list, get($url) =~ /((?:\d{1,3}\.){3}\d{1,3}(?::\d+)?)/g;
  9. }
  10. print join("\n", @ip_list);

Reply

Marsh Posté le 13-08-2005 à 23:27:59    

merci énormément  :)  
maitenant que je viend e tester je vai essailler de comprendre ton code sinon sa servirai a rien  :jap:  
merci encore si j'ai encore d'autre question je les posterai ici.
 
edit: esque tu pourait me comenter ceci stp :

Code :
  1. push @ip_list, get($url) =~ /((?:\d{1,3}\.){3}\d{1,3})/g;


Message édité par K0rN111 le 13-08-2005 à 23:31:43
Reply

Marsh Posté le 13-08-2005 à 23:36:07    

c'est equivalent à ca:

Code :
  1. my $source = get($url);
  2. my @ip_list_page = $source =~ /((?:\d{1,3}\.){3}\d{1,3})/g;
  3. push @ip_list, @ip_list_page;


 
et maintenant pour expliquer ca:
quand tu execute la regexp en contexte de liste (c'est à dire en l'assignant à une liste ou à un push), elle te retourne tous les bloques capturés (entre parenthese, si il n'y a pas un "?:" en debut de bloque).
le modifier 'g' (en fin de regexp) permet de capturer toutes les expression qui match, pas seulement la premiere, et donc de retourner une liste (cette list contient en fait $1, $2, etc...)


Message édité par pospos le 13-08-2005 à 23:37:03
Reply

Marsh Posté le 14-08-2005 à 12:44:20    

bonjour. voila mon programme est terminer.
il y a juste que pour pinger les proxy sa prend du temps quand meme.
 

Code :
  1. #!usr/bin/perl -w
  2. use strict;
  3. use warnings;
  4. use Net::Ping;
  5. use Time::HiRes;
  6. use LWP::Simple;
  7. print "\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n";
  8. print "# Proxy Pinger v.3 by K0rN111 #\n";
  9. print "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n";
  10. print "#Recherche des proxy : \n";
  11. print " ___________________ \n\n";
  12. sleep (2);
  13. my @ip_list;
  14. my @url_list = map {"http://www.samair.ru/proxy/$_"} ('index.htm', map{sprintf('proxy-%02d.htm', $_)} (2..20));
  15. my $nb = 1;
  16. my (%hpms,@read,@foo,$p,$line,$lin,$host,$rtt,$ip,$serv,$ms,$port);
  17. for my $url (@url_list) {
  18.     print "$url\n";
  19.     push @ip_list, get($url) =~ /((?:\d{1,3}\.){3}\d{1,3}(?::\d+)?)/g;
  20. }
  21. print " \n\n";
  22. print "#Proxy a pinger : \n";
  23. print " ______________ \n\n";
  24. sleep (4);
  25. print join("\n", @ip_list);
  26. print " \n\n";
  27.    print "#Execution des requetes ping\n";
  28.    print "____________________________\n\n";
  29.    print "Ceci peut prendre plusieurs minutes\n\n";
  30.    sleep 3;
  31. $p = Net::Ping->new("syn" );
  32. $p->{port_num} = getservbyname("http", "tcp" );
  33. $p->hires();
  34. foreach $line (@ip_list)
  35. {
  36. sleep 1;
  37.    if ($line =~ /(\S+):(\S+)/)
  38.    {
  39.    $host = $1;
  40.    $port = $2;
  41.  
  42.    print "~~~~~ Ping n°$nb ~~~~~~\n";
  43.  
  44.    $p->ping($host);
  45.        while (($host,$rtt,$ip) = $p->ack)
  46.    {
  47.  
  48.    $ms = $rtt * 1000;
  49.    $ms = int($ms);
  50.    print " [+] Done\n";
  51.    $hpms{"$host:$port"} = $ms;
  52.       }
  53.     $nb++;
  54.    }
  55. }
  56. @foo = sort {$hpms{$a}<=>$hpms{$b}} keys %hpms;
  57. print " \n\n";
  58. print "Enregistrement des proxy dans resultat_proxy.txt\n";
  59. print "________________________________________________\n\n";
  60. sleep (3);
  61. print "Enregistrement réussi\n";
  62. open FILE2,">>resultat_proxy.txt";
  63. foreach $lin (@foo)
  64. {
  65. print FILE2 "$lin ~~~~~~~~~~> $hpms{$lin}\r\n";
  66. }
  67. close(FILE2);


 
ps: il y a encore pas mal de chose a ajouter et a amélioré mais je les meterai dans uen prochaine version

Reply

Marsh Posté le 14-08-2005 à 12:44:20   

Reply

Marsh Posté le 14-08-2005 à 13:58:24    

pourkoi tu met des sleep (??! bizare comme phrase!) ?
 
pour tes ping, il doit y avoir moyen d'en faire plusieurs en //.
Il me semble que le sujet avait deja été abordé ici il y a kk temps.
Deja tu peu le faire avec POE:
http://search.cpan.org/~rcaputo/PO [...] 04/Ping.pm
 
mais bon POE n'est pas tres facile d'acces...
 
sinon tu peux te debrouiller en forkant (si t'es sous linux), mais faudra pouvoir recuperer le resultat apres...
le module Async pourrait t'etre utile (il est un peu buggué mais pour ce que tu veux ca devrait aller) :  
http://search.cpan.org/~mjd/Async-0.10/Async.pm
 
en gros tu te fais une dizaine d'objet Async et tu leur balance les Net::Ping, et ensuite tu regarde qui a fini => si tu a un resultat tu rebalance un autre async à la place (pour maintenir le pool) et ainsi de suite. Il y a meme un timeout il me semble sur ce module.
 
Et puis finalement en fait c'est pas vraiment le ping qui t'interesse: tu t'en fout qu'ils repondent à l'ICMP. Ce que tu veux en fait c'est savoir si tu va pouvoir te connecter en HTTP.
Dans ce cas tu peux remplacer tes ping par des ouvertures de connexion TCP et voila!
la c'est plus simple: tu utilise directement le module Socket (pas IO::Socket) et tu le met en mode nonbloquant (il y a des modules pour faire ca, mais sinon c'est assez simple de toutes facon) juste apres sa creation. Ensuite tu tente la connexion (non bloquante) et tu fais pareil pour une dizaine d'autre adresse la aussi. Ensuite tu utilise IO::Select pour voir quels socket sont connecté (writable)

Reply

Marsh Posté le 14-08-2005 à 14:02:23    

d'accord merci et les sleep ses comme les wait ses pour qu'il attente un peu lol sa sert a rien mais comme sa on a le temps de lire les print "..."
et j'utilise les ping pour en faite tester si les proxy sont dead ou aps et aussi pour voir le temps de réponse (ms) .
merci beaucoup en tout cas

Reply

Marsh Posté le 14-08-2005 à 14:23:07    

avec des connexions tcp tu aura aussi le temps de réponse, et ca sera bcp plus fiable: ce que tu veux c'est savoir si tu va pouvoir te connecter en HTTP ou pas, et en combien de temps.
 
un proxy peu tres bien repondre à un ping (tres vite) alors qu'il va refuser des connexions HTTP (ou etre tres lent) si il est chargé. A l'inverse, il peu refuser les ping et accepter des connexions HTTP.

Reply

Marsh Posté le 14-08-2005 à 15:26:03    

t'es sous windows ou linux?

Reply

Marsh Posté le 14-08-2005 à 16:24:22    

la windows j'ai acheter un nouveau pc il y a pas longtemps et je n'ai aps encore installer linux.
donc windows

Reply

Marsh Posté le 14-08-2005 à 16:46:17    

tiens cadeau (en ce moment je me fait chier, mais j'ai plein de travaux à faire chez moi, donc je prefere glander devant mon PC plutot que d'empiller des carreaux de platre...)
 

Code :
  1. use strict;
  2. use warnings;
  3. use LWP::Simple;
  4. use POSIX qw(fcntl_h);
  5. use Errno qw(EWOULDBLOCK EADDRNOTAVAIL EINPROGRESS EADDRINUSE);
  6. use IO::Select;
  7. use Socket;
  8. use Time::HiRes "time";
  9. $|=1;
  10. use constant TIMEOUT  => 5;
  11. use constant PARALLEL_CON => 50; # pas plus de 60 sous windows (voir moins, suivant que d'autres fichiers ou sockets sont déjà ouverts dans le process)
  12. my %hpms;
  13. my %sock2ip;
  14. my @ip_list;
  15. my @url_list = map {"http://www.samair.ru/proxy/$_"} ('index.htm', map{sprintf('proxy-%02d.htm', $_)} (2..20));
  16. print STDERR "\nGET\n";
  17. for my $url (@url_list) {
  18. print STDERR "get $url\n";
  19. push @ip_list, get($url) =~ /((?:\d{1,3}\.){3}\d{1,3}(?::\d+)?)/g;
  20. }
  21. print STDERR "\nCHECK\n";
  22. check(TIMEOUT, @ip_list);
  23. print STDERR "\nRESULT\n";
  24. for my $ip (sort _sort_sub @ip_list) {
  25. printf "%-21s - %-s\n", $ip, $hpms{$ip};
  26. }
  27. sub _sort_sub {
  28. my ($_a) = $hpms{$a} =~ /^(\d+)/;
  29. my ($_b) = $hpms{$b} =~ /^(\d+)/;
  30. (($_a||1_000_000_000) <=> ($_b||1_000_000_000))
  31.  ||
  32. ($a cmp $b)
  33. }
  34. sub check {
  35. my $timeout = shift || 0;
  36. my @ip_list = @_;
  37. while (@ip_list) {
  38.  my @current_ip_list;
  39.  if (@ip_list > PARALLEL_CON) {
  40.   @current_ip_list = splice(@ip_list, 0, PARALLEL_CON);
  41.  } else {
  42.   @current_ip_list = @ip_list;
  43.   @ip_list = ();
  44.  }
  45.  print STDERR "check ", scalar(@current_ip_list), " adresses IP (", scalar(@ip_list), " restantes)\n";
  46.  my @handles_to_check;
  47.  for my $ip (@current_ip_list) {
  48.   my ($host, $port) = $ip =~ /^([^:]+)(?::(\d+))?$/;
  49.   socket(my $sock, PF_INET, SOCK_STREAM, getprotobyname('tcp')) || die $!;
  50.   $sock2ip{$sock} = $ip;
  51.   if ($^O eq 'MSWin32') {
  52.    if (fileno($sock) > 63) {
  53.     die "fd trop grand pour select(2) sous windows => utiliser moins de connexions paralleles";
  54.    }
  55.   }
  56.   nonblock($sock);
  57.   my $adr = sockaddr_in($port, inet_aton($host)) || die;
  58.   unless (connect($sock, $adr)) {
  59.    if ($! and ($! != EINPROGRESS) and ($! != EWOULDBLOCK)) {
  60.     $hpms{$ip} = "failed";
  61.     printf STDERR "%-21s failed\n", $ip;
  62.     next;
  63.    }
  64.   }
  65.   $hpms{$ip} = time;
  66.   push @handles_to_check, $sock;
  67.  }
  68.  return unless @handles_to_check;
  69.  my $sel = IO::Select->new(@handles_to_check);
  70.  my $time_start = time;
  71.  while (time-$time_start < $timeout) {
  72.   for my $sock ($sel->can_write($timeout - (time-$time_start) )) {
  73.    my $ip = $sock2ip{$sock};
  74.    $hpms{$ip} = int(1000 * (time - $hpms{$ip})) . "ms";
  75.    printf STDERR "%-21s $hpms{$ip}\n", $ip;
  76.    $sel->remove($sock);
  77.    delete($sock2ip{$sock});
  78.    close($sock);
  79.    return unless $sel->handles;
  80.   }
  81.  }
  82.  # ceux qui restent sont en timeout
  83.  for my $sock ($sel->handles) {
  84.   my $ip = $sock2ip{$sock};
  85.   $hpms{$ip} = "timeout";
  86.   printf STDERR "%-21s timeout\n", $ip;
  87.   $sel->remove($sock);
  88.   delete($sock2ip{$sock});
  89.   close($sock);
  90.  }
  91. }
  92. }
  93. sub nonblock {
  94. my $sock = shift;
  95. if ($^O eq 'MSWin32') {
  96.  my $set_it = "1";
  97.  ioctl( $sock, 0x80000000 | (4 << 16) | (ord('f') << 8) | 126, $set_it) || return 0;
  98. } else {
  99.  fcntl($sock, F_SETFL, fcntl($sock, F_GETFL, 0) | O_NONBLOCK) || return 0;
  100. }
  101. 1
  102. }

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed