Perl, accéder facilement au WEB avec LWP
Le 12 décembre 2007, à 14:20 par Ulhume...

Perl est très pratique quant il s'agit de manipuler les pages HTML. Il m'a rendu de fiers services dans de nombreux domaine touchant à l'automatisation de connexion à des sites. L'objectif de ce petit tutorial est de montrer pas à pas comment se connecter sur la toile avec Perl et comment en extraire un contenu.

La gestion du protocole HTTP est pris en charge par le module LWP, tout commence donc par :

use LWP;

Fabrication d'un navigateur

On va tout d'abord fabriquer un navigateur. LWP appelle cet objet un UserAgent.

my $browser = new LWP::UserAgent;

Historique (tout afficher)
  • v2 - Ajout des proxies et timeout (2008-02-12 11:04)

Fabrication d'une requête

La fabrication d'une requête de type GET (l'équivalent d'un click sur un lien) procède comme suit :

my $request = new HTTP::Request( GET => "www.monsite.com/chemin/page.html" );

Cette requête peut être affinée pour permettre une meilleur simulation d'un "vrai" navigateur. Pour cela on modifie l'en-tête de la requête et ce qui est plus lié au protocole HTTP qu'à perl.

my $headers = $request->headers();

# Simulation d'un navigateur Konqueror. J'aurais pu mettre
#  'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)'
# Pour simuler un IE...
$headers->header( 'User-Agent','Mozilla/5.0 (compatible; Konqueror/3.4; Linux) KHTML/3.4.2 (like Gecko)');

# Ajoute une liste de contenu supporté (types mime)
$headers->header( 'Accept', 'text/html, image/jpeg, image/png, text/*, image/*, */*');

# Authorize le serveur à renvoyer des contenus compressés. Attention, vous devrez les décompresser vous même. A prendre avec précaution.
$headers->header( 'Accept-Encoding','x-gzip, x-deflate, gzip, deflate');

# Type d'encodage caractères accepté
$headers->header( 'Accept-Charset', 'iso-8859-15, utf-8;q=0.5, *;q=0.5');

# Type de langage accepté
$headers->header( 'Accept-Language', 'fr, en');

# Bien pratique, permet de faire croire au serveur que l'on vient du site www.sourceclick.com
$headers->header('Referer', 'www.sourceclick.com');

Lancer la requête et analyser le retour

Une fois construite, la requête se lance simplement comme suit

my $response = $browser->request($request);

Le retour est un objet de type Response. Il contient différent champs dont content contenant le texte de la page. is_success permet quant à lui de savoir si tout c'est bien passé et status_line contient le message d'erreur le cas échéant. Le résultat contient aussi un champs headers contenant différentes informations sur la page envoyée par le serveur.

if ($response->is_success) {
  my $headers = $response->headers();
  print "Encoding : ".$headers->header("Content-Encoding");                
  print "Content:\n".$response->content."\n";
} else {
  print "Erreur:".$response->status_line."\n";  
}

Si vous voulez accéder à un site sécurisé en SSL, vous devez installer le module urpmi perl-Crypt-SSLeay

Authentification

Il y a trois méthodes pour s'authentifier sur le serveur web. Soit on indique les logins/mot de passe à la requête AVANT de la lancer:

$request->authorization_basic("mon_login", "mon_mot_de_passe");

Sinon on peut aussi donner nos droits au navigateur (voir $browser plus haut). C'est un peu plus compliqué car le navigateur peut ainsi contenir une liste de droits (c'est pratique) mais il va savoir quel droit choisir pour un site en fonction du domaine (realm) de celui-ci. Et nom, le domaine n'est pas forcement la partie finale de l'url. C'est spécifique à chaque serveur. Du coup en général, soit on connaît le domaine, soit on doit faire une requête pour rien (et donc essuyer un refus), regarder dans le header de la réponse le champ WWW-Authenticate. Il contient : Basic realm="mon_domaine", c'est le domaine.

Une fois que vous avez le domaine, il suffit de l'injecter dans le navigateur comme suit

$browser->credentials('www.monsite.com:80', 'mon_domaine', 'mon_login', 'mon_mot_de_passe');

Le www.monsite.com:80 correspond à l'url sans le chemin et du port (80 par défaut)

Enfin, si vous utiliser windows comme serveur (une bien drôle d'idée), il est possible que l'authentification utilisé ici ne marche pas (sans blagues ? Wink ), il faut donc passer le credentials comme suit :

$browser->credentials('www.monsite.com:80', '', 'mon_domaine\\mon_login', 'mon_mot_de_passe');

Accès par proxy

Le paramétrage du proxy est porté par le navigateur ($browser), un peu comme les accréditations.

$browser->proxy (['http'], 'http://monProxy:8080');

Cette ligne indique donc que, concernant les requêtes HTTP, le proxy à utiliser se trouve sur la machine monProxy au port 8080. Il est bien sur possible de rajouter une authentification au proxy lui-même :

$browser->proxy (['http','https'], 'http://monUser:monMotDePasse@monProxy:8080');

Même chose que l'exemple précédent donc, mais pour les deux protocoles HTTP et HTTPS, et cette fois avec une authentification.

Il est enfin possible d'ajouter des domaines d'exception, qui n'utilisent pas le proxy :

$browser->no_proxy(['monDomaineLocal.com', 'monIntranet.com']);

Quelques astuces en vrac

Debuggage

Lorsque tout va mal, un truc pratique pour imposer à LWP de tracer toutes ses transactions. A mettre après le use LWP

use LWP::Debug qw(+);

Ajouter un timeout

Il est possible de limiter le temps d'attente à un serveur. Par exemple ici, 5 secondes :

$browser->timeout(5);

Conclusion

LWP est sans aucun doute une excellente librairie d'accès au web. Elle est relativement intuitive, souple, et pourtant ne laisse sous silence aucun aspect des divers protocoles qu'elle prend en charge. ET ce tutorial n'est qu'un petit aperçu de ce qu'il est possible d'en faire.

Commentaires

Dab, le 5 April, 2006 - 17:35

As tu tenter l'installation de Perl sur pdaxrom ?
Et un lien sympa pour la route ...
http://articles.mongueurs.net/magazines/

voir notamment : Construire des robots pour le web

Ulhume, le 5 April, 2006 - 17:45

Je bookmark Smiling Non, je n'ai pas encore essayé, juste fait du Java pour l'instant Wink

Dab, le 5 April, 2006 - 18:00

Si tu t'interesse au Perl + Web: jette un oeil a Catalyst. Tu connais peut-être ?
J'ai commencer une p'tite doc http://dab.free.fr
Très prometteur ...
@+ goto chez moi Smiling

Dab, le 5 April, 2006 - 20:57

Yes j'ai trouver un package Perl qui fonctionne Smiling
dead://mail.pdaxrom.org/contrib/voider_feed/

# perl -e 'print "Yep Perl sur Zaurus C1000 Smiling\n"'
Yep Perl sur Zaurus C1000 Smiling

Ulhume, le 5 April, 2006 - 23:04

Y'a le binding gtk qui va avec ? Wink

Ulhume, le 5 April, 2006 - 23:07

Je vas lire cela Smiling Ceci dit, pour le web j'ai mon propre framework ajax en java... C'est tout de même (avec feu Delphi) mon langage maître. J'utilises surtout perl pour bidouiller des trames ou contruire des maquettes que j'implémente ensuite en java.

Poster un nouveau commentaire

Le contenu de ce champ est gardé secret et ne sera pas montré publiquement.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • To highlight piece of code, just surround them with <code type="language"> Your code &tl;/code>>. Language can be java,c++,bash,etc... Everything Geshi support.
  • Les lignes et les paragraphes vont à la ligne automatiquement.
  • Textual smileys will be replaced with graphical ones.
  • Les adresses de pages web et de messagerie électronique sont transformées en liens automatiquement.

Plus d'informations sur les options de formatage

Connexion utilisateur
Les derniers bavardages...