samedi 24 novembre 2012

SCRIPT 4 : URLS - PAGES ASPIREES - DUMPS - UTF-8

Voici venue l'heure de mettre à profit tous les tests effectués précédement pour créer un programme qui génère à partir d'un dossier contenant plusieurs fichier d'URLs un tableau à 5 colonnes avec :

1-Le numéro de l'URL
2-Le liens vers l'adresse URL
3-Le lien vers la page web aspirée
4-Le lien vers le texte extrait de la page web aspirée
5-Le lien vers le texte au format UTF-8 extrait de la page web aspirée

En plus de créer des liens, nous devons donc gérer la capture de pages web, l'extraction de contenu textuel, la reconnaissance et la convertion d'encodage. Tout un programme !!!

Pour mettre au point notre script, nous nous sommes appuyés sur le schéma présenté sur le site du cours à l'adresse suivante:


Pour chaque boucle nous n'avons fait que reprendre et adapter des portions de script vus précédemment.

Afin débugger plus facilement le programme, nous avons ajouté pas mal de commentaires dans le script et nous avons tirer profit au maximum de la commande echo pour suivre le déroulement du programme dans le terminal.

Vous pouvez télécharger notre nouveau script à l'adresse suivante :


Comme vous verrez, nous en avons aussi profité pour arranger un tout petit peu la présentation des tableaux.

Voici des caputres d'écran faites après un test sur quelques URLs seulement :

Tableaux pour 2 fichiers contenant 3 URLS

Vue du terminal pendant l'execution du script


Normalement, nous avons réussi à régler la plupart des problèmes. On constate juste un type d'erreur dans le terminal au moment de converstion d'encodage avec la commande iconv. On trouve par exemple :

iconv: (stdin):8:8: cannot convert

Pourtant, tous les fichiers présentés dans la dernière colonne du tableau semblent avoir été convertis en UTF-8 ?

Il faudra donc éclaircir ce problème un autre jour... ou une autre nuit ;°) !

Parmi les améliorations possibles, on pourra encore :

- améliorer l'organisation des fichiers produits en output
- améliorer la présentation des tableaux
- ajouter une colonne aux tableaux pour les messages d'erreur (type: CURL, Erreur 404, encodage non reconnu...)
- prendre en compte plus d'erreurs que l'erreur 404 

RECUPERER ET CONVERTIR L'ENCODAGE D'UN FICHIER

Nous avons vu que pour récupérer l'encodage d'un fichier dans une variable, on pouvait utiliser la commande file avec ses options -I et -d suivie de la commande cut et de ses options -d et -f.

En bash, il est également possible de convertir le format d'encodage d'un fichier à condition de préciser dans les options de la fonction iconv l'encodage d'entrée (-f) et l'encodage de sortie (-t).

Voici un exemple à partir d'un fichier texte encodé en ISO-8859-1. On veut convertir son encodage en UTF-8. On peut donc saisir la commande suivante dans le terminal :

iconv -f iso-8859-1 -t utf-8 < kamikaz.txt > kamikaz-UTF-8.txt

Rappel : "<" signifie qu'on donne en entrée le fichier kamikaz.txt et ">" qu'on veut obtenir en sortie le fichier kamikaz-UTF-8.txt

Il existe beaucoup de formats d'encodage différents et pour obtenir la liste de ceux disponibles depuis le terminal, on peut saisir la commande iconv -l. Les conversions ne sont possibles qu'entre des types d'encodage apparenant à cette liste.

Grâce à la fonction egrep, on va donc pouvoir tester si l'encodage d'un fichier appartient à la liste disponible depuis le terminal. 

Voici une proposition de script :

#!/bin/bash
echo "Donnez le nom et l'emplacement du fichier";
read fichier;
encodage=$(file -I $fichier | cut -d= -f2);

detection=$(iconv -l | egrep -i $encodage);

if [[ $detection != "" ]]
then
echo "L'encodage est a été reconnu";
else
echo "L'encodage ne fait pas parti de la liste";
fi



Commentaires: 

- La commande file -I $fichier | cut -d= -f2 permet de récupérer l'encodage du fichier d'entré. On enregistre cette valeur dans la variable encodage.

- La commande iconv -l | egrep -i $encodage permet de rechercher une occurence de la valeur de la variable encodage dans la liste des encodages disponibles. L'option -i permet de ne pas prendre en compte la case. Si cette commande renvoie une valeur, c'est que l'encodage du fichier appartient à la liste des encodages disponibles. On a donc enregistré le résultat de cette commande dans la variable detection afin de pouvoir mettre en place un test sur la valeur de cette variable.

On réutilisera ce type de script dans une des boucles de notre programme traitant nos fichiers d'URLS. Si l'encodage d'une page web aspirée est reconnu, à la place d'afficher le message "L'encodage est a été reconnu", on pourra lancer une convertion avec la commande iconv et les options -f et -t.

CONNAITRE OU VERIFIER L'ENCODAGE D'UN FICHIER

La commande file suivi d'un nom de fichier permet d'afficher son type. On peut y ajouter l'option -i (ou -I sur Mac) pour plus d'informations sur l'encodage.

Voici un exemple sur le fichier texte.txt, contenant uniquement du texte :

file -I fichier.txt;


et voici la réponse dans le terminal :



fichier.txt: text/plain; charset=utf-8


A l'aide de la fonction cut et des options -d (qui permet de définir un délimitateur) et -f (qui permet de définir la zone à selectionner en fonction de ce délimitateur), on va pouvoir extraire de l'information obtenue par la commande file l'encodage d'un fichier.

En reprenant l'exemple ci-dessus, on saisira la commande :

file -I fichier.txt | cut -d= -f2

(Attention, sur PC il faudra peut-être remplacer -I par -i et | par ¦ )

Cette commande indique qu'on choisi comme délimitateur le symbole "=" qui sépare ici notre chaîne de caractère en deux parties :

fichier.txt: text/plain; charset     utf-8
           (1)                        (2)

Avec l'option -f2, on ne garde que le contenu de la deuxième partie, c'est à dire utf-8.

On peut capturer la valeur rendue par cette commande dans une variable qu'on appellera encodage :

encodage=$(file -I fichier.txt | cut -d= -f2)

A partir de cette variable, on pourra imaginer un script qui affiche ou test l'encodage d'un fichier. Voici deux petits exemple en bash qui fonctionnent sur Mac :

1) Script pour afficher l'encodage d'un fichier:

#!/bin/bash
echo "Donnez le nom et l'emplacement d'un fichier";
read fichier;
encodage=$(file -I $fichier | cut -d= -f2);
echo "Ce fichier est encodé en $encodage.";

2) Script pour déterminer si un fichier est encodé en UTF-8:

#!/bin/bash
echo "Donnez le nom et l'emplacement du fichier à tester";
read fichier;
encodage=$(file -I $fichier | cut -d= -f2);
if [[ $encodage == "utf-8" ]]
then
echo "Ce fichier est bien encodé en UTF-8.";
else
echo "Ce fichier n'est pas encodé en UTF-8. Il est encodé en $encodage.";
fi

TESTS SUR LA FONCTION CURL

Aujourd'hui, nous allons nous intéresser de plus près aux différents outputs produits par la fonction CURL.

On cherche notemment à détecter les erreurs possibles au moment de l'aspiration d'une page web afin de pouvoir prendre en compte ce facteur dans une des boucles de notre programme de traitement des URLS.

Pour cela, nous avons d'abord testé depuis le terminal différents cas :

    - Erreur de type "pas de connection possible !"
    - Erreur de type "adresse URL non valide !"

A) Erreur de type "pas de connection possible !"

On tape la commande suivante dans le terminal pour aspirer le contenu de la page web du cours :


curl http://www.tal.univ-paris3.fr/cours/masterproj.htm -o page-aspiree.html;


(l'option -o permet d'indiquer le fichier dans lequel sera enregistré le contenu aspiré par CURL)

Si tous se passe bien, le terminal affiche des informations sur l'aspiration de la page :


  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 99762  100 99762    0     0  1462k      0 --:--:-- --:--:-- --:--:-- 1709k


En revanche, si CURL rencontre un problème, il produit un message d'erreur. Par exemple, si on coupe notre connexion internet et qu'on reproduit l'expérience, on obtient le message suivant dans le terminal :

curl: (6) Could not resolve host: www.tal.univ-paris3.fr; nodename nor servname provided, or not known

Pour tester dans un script si CURL a fonctionné correctement, on peut donc enregistrer le message produit par CURL dans une variable qu'on appelera retourcurl: 


curl http://www.tal.univ-paris3.fr/cours/masterproj.htm -o page-aspiree.html;

retourcurl=$?;
echo "Voici la réponse de CURL : $retourcurl";


A partir de ce script, on constate donc que si $retourcurl vaut 0 alors, on peut dire que CURL a bien fonctionné. Si $retourcurl vaut 6 (ou une autre valeur?) alors il y a eu un problème. A partir de cela, on peut écrire un petit programme en bash testant cette condition sur un exemple :


#Aspiration d'une page web du cours
curl http://www.tal.univ-paris3.fr/cours/masterproj.htm -o page-aspiree.html;

#Capture du message produit par CURl dans une variable
retourcurl=$?;

#Test sur la valeur de cette variable
if [ $retourcurl == 0 ]
then 
echo "CURL a réussi à aspirer la page WEB.";
else 
echo "CURL a échoué.";
fi


Avec ce script, on obtientera dans le terminal un message nous indiquant si CURL a bien fonctionné sur la page web.

B) Erreur de type "l'adresse URL n'est pas valide !"

Lorsqu'on saisi une adresse URL qui n'est pas valide, le navigateur produit automatiquement un message d'erreur. Avec la commande CURL que nous avons tapé dans le terminal, si l'adresse n'existe plus ou bien qu'elle est incorrecte, on aura donc toujours une page HTML en sortie (affichant l'erreur 404). Du coup, dans notre script précédent, la condition $retourcurl == 0 sera bien remplie alors qu'il y a un problème !

Voici le résultat de la page asspirée lorsqu'on insère une erreur dans l'adresse URL du cours :


Et voici le code HTML de cette page :




Grace à la fonction egrep de bash, on peut donc parcourir le contenu du code HTML de la page aspirée afin d'y chercher une occurence de "Error 404" (caractérisitique d'un message d'erreur de ce type).

egrep -io "Error 404" page.html

(la fonction -i permet de ne pas prendre en compte la case et la fonction -o permet de chercher une occurence)

On va alors enregistrer la valeur produite par la fonction egrep dans une variable pour ensuite voir les valeurs qu'elle peut prendre.


#!/bin/bash
curl http://www.tal.univ-paris3.fr/cours/masterproj.htm -o page-aspiree.html;

error404=$(egrep -io "Error 404" page-aspiree.html);
echo "Voici le retour de la fonction egrep : $error404";


Lorsque l'adresse URL est correcte et que CURL fonctionne correctement, la variable error404 ne contient aucune valeur. Lorsque l'erreur 404 se produit, alors $error404 vaut "Error 404".

Voici un test en bash permettant de vérifier si la page aspriée contient une erreur de type 404 :

#!/bin/bash
curl http://www.tal.univ-paris3.fr/cours/masterpro.htm -o page-aspiree.html;

error404=$(egrep -io "Error 404" page-aspiree.html);

if [[ $error404 == "Error 404" ]]
then 
echo "La page aspirée contient une erreur de type 404.";
else 
echo "La page aspirée est valide.";
fi



Préparation d'un script test sur la fonction CURL

Grâce à ces petites expériences, on peut maintenant proposer un script testant le bon déroulement de l'aspiration d'une page web.

On veut d'abord tester s'il n'y a pas d'erreur de type A puis si c'est le cas, vérifier s'il n'y pas de problème de type B. On a donc le schéma de condition suivant :

Si A ne pose pas problème:
   alors on vérifie si B pose problème:
      si oui, on affiche que A fonctionne mais que B pose problème
      sinon, on affiche que tout fonctionne 
sinon on affiche que A pose problème

Pour mettre en oeuvre cela, on va simplement imbriquer les deux scripts test qu'on vient de présenter.

Voici une capture d'écran de notre nouveau script test :

On pourra maintenant reprendre ce script dans une des boucles de notre programme traitant nos fichiers d'URLS. On pourra aussi améliorer les performances de ce script en prenant en compte d'autres types d'erreurs que l'erreur 404...

jeudi 22 novembre 2012

INSTALLATION DE LYNX SUR MAC OS 10.8

Pour extraire les contenus textuels de nos pages web, nous avons utilisé un navigateur en ligne de commande : Lynx

La commande suivante permet par exemple de récupérer le contenu textuel de notre blog dans un fichier texte : 

lynx -dump -nolist http://les-manchots3.blogspot.fr > blog.txt


(L'option -dump sauvegarde le texte de la page visualisée dans le terminal et l'option -nolist permet de ne pas prendre en compte les références de liens)



Seulement, pour pouvoir utiliser cette superbe commande, il faut que Lynx soit installer sur votre ordinateur. Voici une manière de faire si vous travailler sur Mac. On a cherché pas mal de temps avant d'y arriver avec Mac Os 10.8 alors on espère que cette méthode pourra aider d'autres personnes...


Il faut d'abord télécharger et installer une version de Xcode qui soit compatible avec votre ordinateur. C'est gratuit sur Apple Store, si vous avez un compte. Ensuite, vous installerez Commande Line Tools for Xcode puis vous n'oublierez pas de signer la licence de Xcode en tapant dans votre terminal :

xcodebuild -license


(une fois que vous avez fait tout défiler, il faut taper 'agree' et valider)



Vous pouvez ensuite télécharger et installer la version de Macports dont vous avez besoin (pour Moutain Lion, Lion ou Leopard).


Une fois que vous avez fait tout ça, vous pouvez ouvrir votre terminal et taper cette commande pour installer Lynx :

sudo port install lynx

Normalment, si tout a bien fonctionné, vous devriez pouvoir accéder à notre blog depuis votre terminal avec la commande suivante :


lynx http://les-manchots3.blogspot.fr



Et voici ce que ça donne :




Magnifique n'est-ce pas ? Enfin, j'espère que vous préfèrez quand-même la mise en page de notre blog via votre navigateur !!!


mardi 20 novembre 2012

trois tableaux avec dump

Après de multiples tentatives et une patience qui nous surprend encore, nous sommes enfin parvenus à écrire un script contenant à la fois la boucle pour les différents fichiers d'urls, l'aspiration des pages et enfin le dump!!
Et oui, il fonctionne pour notre plus grand bonheur :)

Voici donc le script :




Et le résultat sur le web :




La prochaine fois nous essayerons de régler le problème de l'encodage qui sera très présent avec mes urls en arabe.
A bientôt donc, pour la suite de nos aventures!

Sofiane

dimanche 11 novembre 2012

Créer un tableau de liens avec des liens externes vers les pages visées et des liens internes vers les pages correspondantes aspirées

Nous voilà maintenant prêts pour la création d'un tableau d'URLs avec une colonne en plus contenant les pages aspirées de nos liens Urls.

Courageux que nous sommes, un dur labeur nous a donné ce résultat :

Voici le script amélioré :





On y a ajouté la commande Wget qui nous permet d'aspirer les liens de nos pages Urls. Les liens vers les pages aspirées sont ensuite mis dans une 3ème colonne !
Et ça marche :



Dans un prochain épisode : la même chose avec nos 3 fichiers d'URLs (français, anglais, arabe)