pluriTAL – BLOG Master pluriTAL [ParisX, ParisIII, INALCO]

ME@HOME

Posted in Projet 2006-2007 by pluritaluser on 26 novembre 2006

EZZAT, Mani.

Bonjour à tous.

J’ai décidé de réaliser le projet en perl car finalement, d’une part le bash ressemble énormément au tcsh que j’ai déjà pratiqué, et d’autre part je suis complètement vierge en ce qui concerne Perl et c’est un bon moyen de m’y mettre. Lors des séances du jeudi, il ne nous restait plus qu’à copy/paste ce qui était écrit sur le tableau pour finir le projet, ce qui ne m’ammène pas tellement de satisfaction personnelle (évidemment, sans connotation négative sur les autres personnes bien entendu).

Je pense également que cela serait plus instructif de mettre en exergue les problèmes que nous pouvons rencontrer, plutôt que de vômir un code obscur qui fonctionne. En gros, je vais tenter de montrer ce qu’il ne faut pas faire (comment ça tout le monde s’en fou ?! :/)

Première remarque : Perl est facile d’accès, très puissant, et proche du C. Il suffit d’être un poil autodidacte et ça passe tout seul. Merci à Mr Fleury de m’avoir fourni ses cours. Je pense que tout le monde y trouvera son comptes dans ces dits cours (je les ai sur ma clé USB si il y a des interessés, pas trop envi de les mettre en ligne sans permission au préalable:/)

J’ai rapidement codé un script qui s’arrete à la 3eme colonne du tableau, c’est a dire aux pages lynxées. Perl comprend des outils extremement puissant concernant les regexp, surpassant de loin ce que grep peut nous fournir. J’y reviendrai donc plus tard.

Le script en question n’a pas de boucle imbriquée. Il va regarder la premiere url du fichier-liste (ligne par ligne), mettre le lien, wget ce lien, le lynxé, tout en écrivant le code html qui va bien pour notre tableau final, et recommencer pour la ligne suivante.

Une seule boucle est alors nécessaire.

Voici un exemple de code en perl, volontairement crados 😀 et examinons les problèmes que l’on peut rencontrer :


#!/usr/bin/perl
print « File le nom du fichier url AVEC LE PATH! \n »;
$url=<STDIN>;
print « $url »;
chomp($url);
print « File le nom du file pour le tableau en html! \n »;
$my_tab=<STDIN>;
print « $my_tab »;
chomp($my_tab);
open(LECTURE, « $url »);
open(ECRITURE, « >$my_tab »);
print ECRITURE « <html>\n<head>\n<title>tableau de liens</title>\n</head><body>\n<table border=\ »1\ »>\n » ;
$i=1;
while($ligne=<LECTURE>) #ma seule boucle
{
print $ligne;
chomp($ligne);
print ECRITURE « <tr><td><a href=\ »$ligne\ »>URL$i</a></td> »;
$wgett= »wget -O ../PAGES-ASPIREES/toto$i.html $ligne »;
system($wgett);
print ECRITURE « <td><a href= \ »
file:///E:/cygwin/home/Lalooz/plurital/projet/PROJET-MASTER/PAGES-ASPIREES/toto$i.html\ »>FILE$i</a></td> »;
$lynx= »lynx -dump ../PAGES-ASPIREES/toto$i.html > ../DUMP-TEXT/toto$i.txt »;
system($lynx);
print ECRITURE « <td><a href= \ »
file:///E:/cygwin/home/Lalooz/plurital/projet/PROJET-MASTER/DUMP-TEXT/toto$i.txt\ »>TEXT$i</a></td></tr> »;
$i++;
}
print ECRITURE « \n</table>\n</body>\n</html> »;
close(LECTURE);
close(ECRITURE);

Un peu dégueulasse, je vous l’accorde.

Premièrement, le problème de la portabilité du code s’impose. Lorsqu’on regarde les PATH, on s’aperçoit tout de suite que ce script ne fonctionnera QUE CHEZ MOI SUR MA MACHINE. Si je veux l’exporter ça coincera. En considérant l’arbo de notre projet, il faudra s’interesser aux chemins absolus/relatifs, pour ceux qui regarderont leur tableau avec un browser windows par exemple (bah ouais, on utilise cygwin, rien n’empeche d’utiliser un brower windows pour afficher notre tableau)

./ .. voir meme le pwd (affiche le chemin dans lequel on est) peut s’avérer fort utile.

Deuxièmement, que se passe-t-il si un des sites a fermé entre temps ? ou leur serveurs sont en pannes? wget ne pourra rien d/l, lynx -dump ne transfomera rien, pire encore, lynx ne trouvera pas le ficher à transformer car wget n’a rien aspiré. Ce qui affichera surement des erreurs sur la console. Votre tableau se constituera quand même ceci dit:/

La solution paraît simple. Il suffit de rajouter une itération qui stipule : « si wget réussit, tu continues ton bordel, si il réussit pas, tu vas m’afficher -lien mort- ou autre sur mon tableau »

Avec Ivan, nous discutions d’une premiere solution un peu compliquée mais qui devrait marcher :

utiliser le fichier log de wget (-o il me semble), regarder dans ce fichier log, et voir si pour chaque fichier, on trouve un « file saved » quelque part. Si on le trouve, c’est que wget a reussi a aspiré le site, et le script peut continuer a faire son tableau. Si on le trouve pas, wget n’a pas réussi, et le script devra réagir en fonction (mettre « lien mort », changer de couleur ou n’importe quoi d’autre)

Une autre solution plus simple et « propre » (cad deja sans creer de fichier log tout dégueulasse sur le dur):

utiliser les variables d’environnement. Quezako ?

Un exemple simple, vous voulez savoir l’heure. Et bien votre OS comprend tout un tas de variables, dont l’heure qu’il est, auxquels vous pouvez accedez facilement.

Pour les voir, tappez sur votre console env et elles s’afficheront.

Ce qui m’interesse ici, c’est la variable $?. Lorsque j’appelle un programme, si le programme ne rencontre pas de problème, il retournera 0 dans cette variable, sinon il retournera un autre nombre.

Il suffit alors dans votre script apres votre wget, de voir si $? = 0 ou autre chose et voilà !

Mais tout n’est pas si rose, car env ne contient aucune variable s’appellant ?:/ En fait perl a déjà des variables « d’environnement »définies pour les gesitions d’erreurs dont $?, $@, $!. et je peux y acceder directement dans le script. (Cela m’a posé problèmes, j’ai cherché pendant longtemps dans env sans jamais rien trouver:/)

NB: je fonctionne d’une manière binaire ici. A savoir « 0 ou autre chose » seulement. Le man de wget ne dit pas ce que wget renvoie dans $? selon le type d’erreurs. Il peut y en avoir plusieurs, comme par exemple ne pas pouvoir se connecter au domaine, ou ne pas trouver le fichier etc… Il faudrait tester pour chaque cas ce que renvoie wget, mais j’ai la flemme:D. Donc je reste dans la logique « ca fonctionne ou ca fonctionne pas » sans m’interesser au « pourquoi ca fonctionne pas ».

En bash, vous pouvez accéder à ces variables facilement et intuitivement, comme sous la console. En revanche en Perl, c’est un peu plus différent. Perl crée de base un tableau associatif (pensez un tableau de char * en C par exemple, si vous savez ce qu’est un pointeur) qui permet d’acceder aux variables d’environnement sous la forme $env{ PATH} pour la variable des PATH par exemple.

Tout le reste va encore concerner la gestion d’erreur et l’optimisation.

Avec Nicolas, on discutait de faire un tableau de 20 lignes maximum, et d’ajouter des liens page1 page 2 etc… pour la suite. Car si on a 50 urls a mettre dans un tableau, ca va. Si vous en avez 1000, ca fait un peu lourd:/ La solution reste simple ceci dit. Lorsque vos compteurs boucle atteignent 20, vous passez sur une autre page (un autre fichier donc). C’est basique mais c’est un grand pas en avant pour la lisibilité.

Autre problemes, les sites en php (ou autre cgi et consorts)

Si votre lien n’est pas en html, il y a de fortes chances que vous ne récupériez qu’un script bidon, sans aucune information relative à barrage. Comment régler ce problème? Simple, en utilisant GET http:// au lieu de wget. Par ce biais, vous récupererez ce qui est AFFICHE sur votre browser (donc ce qui nous interesse) et non pas le fichier cible de wget avec les scripts php par exemple. Il suffira de faire encore une itération qui va regarder l’extension de votre fichier et qui agira en fonction. Mais cela implique de pouvoir trier les fichiers html php et autres:/ et donc de faire appel aux regexp. ATTENTION, c’est plus compliqué que cela paraît. Car un script php peut etre sous forme domaine.com/script.php, ou alors le lien peut contenir des valeurs correspondantes à la base SQL par exemple, ou encore les différents « case » d’un fichier php (quand c’est codé un peu cochon) et ce n’est donc pas forcément facile de repérer ce genre de chose automatiquement via regexp.

Pour ce qui est des redirections, je ne trouve pas de solutions malheureusement:/

Ni même pour tous les sites php sur base sql, dans lesquels vous devez vous identifier pour avoir accès au content. Les options user password de wget ne fonctionnent que sur les log/pass style corpus le monde. Un simple forum de discussion, pour la majorité d’entre eux (95% peut-être?) utilisent le format php sur BDD mySQL.

Il serait aussi interessant de pouvoir pomper ce qu’on trouve sur newsgroup (en passant par des servers de type news.domaine.truc). Je suis persuadé que c’est possible, je lisais des ng avec emacs, mais je ne sais pas trop comment on pourrait l’automatiser. Il doit sûrment exister un outil quelque part permettant de le faire :/ Je sais bien que maintenant c’est un repère de warez et de binaires, plutot que de textes, mais des « vieux de la veille » doivent encore utiliser ce machin.

… to be continued (comment ça « non c’est pas la peine?!! » T_T )

Publicités

4 Réponses

Subscribe to comments with RSS.

  1. pluritaluser said, on 28 novembre 2006 at 12:57

    Bonsoir ou Bonjour Mani.
    Je crois que les scripts php ou cgi ne posent pas de problème. En effet ce que le navigateur web et wget récupère c’est la même chose. L’URL contient bien une demande de page php, mais le serveur web voyant que c’est un script php ou cgi qui est demandé exécute ce script, le script lui affiche ce qui deviendra la page web.
    Ce n’est pas comme si on téléchargé le script php. J’imagine si c’était le cas le scandale de vol de propriété intellectuelle (IP) qui aurait eu lieu.
    Tu peux essayer sur le site paris-pencak-silat.net c’est un site écrit en php et tu verras que ce n’est pas le script php que tu obtiens mais bien la page (en plus il y a une redirection, que tu ne verras même pas). J’en profite pour faire de la pub pour le site de l’association dont je suis le webmaster ;-).
    A part ça, tu as eu une super idée sur le fractionnement en plusieurs pages html, et sur la vérification d’erreur de wget.
    A+
    Christian.

  2. pluritaluser said, on 30 novembre 2006 at 2:52

    EZZAT Mani.
    On vient de tester en live.
    1. wget va pas aspirer le bon content
    2. GET marchera que dans certains cas, et ses options sont limités.

    Conclusion: Avec ces outils, il est impossible d’être exhaustif, en tout cas sur les fichier php. Et on loupera bcp d’infos

  3. pluritaluser said, on 30 novembre 2006 at 7:52

    Bonjour Mani.

    D’un point vue du protocol http, je n’arrive pas à comprendre que GET puisse faire des choses que wget ne puisse pas faire. En tapant GET / après t’être connecté sur le serveur sur le port 80, tu émets une requête définie par le protocol HTTP 0.9 à partir de HTTP 1.0 tu devrais taper GET / HTTP/1.0 en fait / c’est la racine du serveur web, /.

    wget est obligé d’utiliser la commande GET / ([HTTP/1.0] probablement) pour récupérer les pages (c’est HTTP qui veut ça). Donc si tu peux récupérer une page avec GET / que tu ne peux pas avec wget, je ne vois qu’une solution, c’est dans l’entête du message qu’envoie wget au serveur web. Si les pages que tu n’arrives pas à récupérer avec wget ou GET mais que tu y arrives avec ton navigateur web, alors peut-être que l’option suivante de wget peux marcher :

    –user-agent=agent-string
    S’identifier sous le nom agent-string pour le serveur HTTP.

    Le protocole HTTP autorise les clients s’identifier eux-mêmes en
    utilisant le champ User-Agent dans l’en-tête. Ceci permet de
    distinguer les logiciels WWW, le plus souvent pour des buts statis-
    tiques ou pour tracer des violations de protocole. Wget s’identifie
    normalement sous le nom Wget/version, version tant la numéro de la
    version courante de Wget.

    Cependant, certains sites sont connus pour imposer une politique de
    filtrage sur des clients en fonction de User-Agent . Si, con-
    ceptuellement, ce n’est pas une trop mauvaise ide, ça se traduit
    souvent par le refus de servir les clients autres que Mozilla ou
    Microsoft Internet Explorer. Cette option vous permet de falsifier
    la valeur de User-Agent envoye par Wget. L’utilisation de
    cette option n’est pas recommandée, à moins que vous ne sachiez
    vraiment ce que vous êtes en train de faire.

    Si tu veux, tu peux m’envoyer le lien d’une page qu’on ne peut pas télécharger avec wget, et qu’on peut avec GET.

    J’ai vraiment envie de résoudre ce problème, cela me rappelle mon passé de mes 20 ans, mes livres de chevets étaients : TCP/IP ILLUSTRATED vol1 The protocols, et TCP/IP ILLUSTRATED vol3 : TCP for Transaction, HTTP, NNTP, and the UNIX Domain Protocols de feu W.Richard Stevens. Les livres je les ai toujours, rangés entre UNIX Network Programming du même auteur et « La sagesse du Bouddha », suivi par Gunm Last Order (on fait avec la place qu’on a ;-)). Une fois le problème résolu, je me ferais une joie d’écrire à l’administrateur du site en question …

    Tu ne peux pas savoir, l’émotion que j’ai ressenti en rouvrant ces livres, ça me rappelle l’âge d’or de ma carrière professionnelle, jeune, dynamique, peur de rien, le marchand de nouille encore ouvert à 3heures du matin par une nuit de 30° en plein coeur de Bangkok. C’était le bon temps, et pourtant je sents cette flamme encore en moi qui brûle encore et qui ne demande qu’à être ravivée, comme un ancien champion ne demandant qu’à remonter sur le ring, « one more time on the track ». Bon je vais lire le texte de Pierre Dac pour demain, plus efficace que de l’eau pour réteindre tout ça.

    Christian.

  4. pluritaluser said, on 1 décembre 2006 at 1:34

    En fait il y a déja quiproquo.

    il s’agit de la commande GET, et non pas d’établir un telnet/ssh sur 80 par défaut et d’envoyer une requete get /machin.
    Premièrement, sous cygwin, si tu tentes d’utiliser GET, il va te chercher celui de perl:/ On a essayé ensuite d’établir une communication avec telnet, mais le problème c’est que cela marche pas tout le temps. Sur le site du Crim avec le port 80, ca passe, mais pas sur le site de Le monde par exemple.

    On a donc utiliser la commande GET via DOS. Cela fonctionnait pour certains sites, et d’autres non, va savoir pourquoi, on ne peut que spéculer sans les sources.

    Après il faudrait avoir les sources de wget et de GET pour confirmer tout ça.

    Pour moi le plus simple, c’est de pouvoir accéder au buffer du browser avant qu’il affiche son truc, et de récupérer tout ca. Ca doit etre difficile de faire un prog qui va marcher pour tous les browsers, et je n’en connais pas qui propose cette option (J’avoue c’est pas comme si j’avais cherché).

    La conclusion, aussi frustrante que cela puisse être, est qu’on ne peut pas etre exhaustif avec les outils que l’on a actuellement. Peut-etre qu’il en existe quelque part…


Laisser un commentaire

Choisissez une méthode de connexion pour poster votre commentaire:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion / Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion / Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion / Changer )

Photo Google+

Vous commentez à l'aide de votre compte Google+. Déconnexion / Changer )

Connexion à %s

%d blogueurs aiment cette page :