samedi 24 novembre 2012

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)

samedi 10 novembre 2012

TRAITEMENT AUTOMATIQUE DE PLUSIEURS FICHIERS D'URLS

Nous allons voir comment modifier ce script pour traiter de manière automatique plusieurs fichiers contenant des listes d'URLS.

PRINCIPE GENERAL

Le but est donc toujours de construire un tableau au format html qui recense nos URLs à partir d'un fichier texte, mais cette fois-ci on veut obtenir dans le même fichier .html autant de tableau qu'il y a de fichier .txt !

En programmation, ce type d'action peut être exécuté au moyen d'une boucle.

On sait qu'en bash la boucle for permet de traiter un ensemble d'éléments unité par unité. On va donc pouvoir créer un pseudo ensemble listant le contenu du dossier où sont classés tous nos fichiers d'URL (`ls URLS`) pour créer ensuite une boucle for où une unité correspondra à une ligne de cette ensemble, c'est à dire à un nom de fichier (for fichier in `ls URLS`).

On pourra ensuite insérer à l'intérieur de cette boucle, la partie du script précédent qui permettait de créer une ligne de tableau pour chaque nouvelle ligne contenu dans un fichier texte. Il faudra juste faire attention au nom des variables et à l'emplacement des balises html. Nous allons voir cela dans le paragraphe suivant.  

MODIFICATION DU SCRIPT ETAPE PAR ETAPE

Il va falloir commencer par changer l'input. On ne donne plus le nom d'un fichier, mais le nom d'un dossier. On utilise toujours la fonction echo et la fonction read. Le nom du dossier saisi sera enregistré dans une variable qu'on appelle dossier. 

echo "Donnez l'emplacement et le nom du dossier contenant les fichiers d'URLs : "; 
read dossier; 

Rien ne change en ce qui concerne le fichier Output :

echo "Donnez l'emplacement et le nom du fichier html qui présentera les urls dans un tableau : "; 
read tablo;

On enregistre ensuite dans le fichier Output le début du code html. Attention, on ne garde qu'une partie du code précédent puisque toutes les balises qui concernent les tableaux html seront insérées dans les boucles for. (Au fait: on ajoute aussi au passage un "x" à "tableau" dans le titre de notre future page html ;) !)

echo "<html><head><title>tableaux de liens</title></head><body>" > $tablo;

On ouvre ensuite une première boucle selon le principe vu plus haut. On appelle fichier la variable correspondant à une unité de notre ensemble, c'est à dire à un nom contenu dans notre dossier de fichiers d'URLs.

for fichier in `ls $dossier`
{

Pour chacun de ces noms de fichier, on enregistre dans le fichier Output les balises html ouvrant un nouveau tableau. Pour plus de clarté dans le résultat, on en profite aussi pour insérer avant un titre. (Pour faire simple on reprend simplement le nom du fichier traité, mais on pourrait améliorer ce titre avec l'utilisation d'une nouvelle variable et d'une incrémentation dans la boucle) :

echo "<p>Tableau $fichier</p>" >> $tablo;
echo "<table border=\"1\" width=\"50%\">" >> $tablo;  

Maintenant que les balises d'un nouveau tableau sont créées, on peut y insérer autant de lignes qu'il y d'adresses dans le fichier d'URLs qui est en train d'être traité. Pour cela, on reprend la boucle de notre premier script en indiquant cette fois-ci le chemin relatif vers les fichiers textes (puisqu'ils ne se trouve pas au même emplacement que notre script !). 

Une petite astuce : pour écrire ce chemin, on peut justement réutiliser les valeurs de nos variables. Dans notre cas, on a : $dossier = "nom du dossier contenant les fichiers d'URLS" et $fichier = "nom d'un fichier d'URLS". Du coup, $dossier/$fichier est un chemin relatif correct.

i=1;
for nom in `cat $dossier/$fichier`
{
echo "<tr><td align=\"center\" width=\"20\">$i</td><td align=\"center\"><a href=\"$nom\">$nom</a></td></tr>" >> $tablo;
let "i+=1"; 
}

Une fois cette boucle terminée, on ferme la balise html du tableau correspondant au fichier qui a été traité dans la boucle :

echo "</table>" >> $tablo;

On est alors près pour reprendre la première boucle sur le fichier d'URLs suivant. Pour indiquer cela, on ferme  l'accolade correspondant à la première boucle :

}

Une fois que tous les fichiers d'URLs ont été traités, il ne manquera plus qu'à fermer les balises html restées ouvertes, c'est à dire <body> et <html> :

echo "</body></html>" >> $tablo; 

Notre fichier html en Output est alors valide. Notre script est terminé !


Voici maintenant ce que ça donne en images :

Le nouveau script avec #commentaires

Affichage de l'organisation des fichiers et exécution du script dans le terminal

Extrait du fichier HTML en Output

Affichage du résultat dans Safari


AUTRE SOLUTION POUR SUIVRE l'EXECUTION D'UN SCRIPT CONTENANT UNE BOUCLE

En reprenant comme base le script de la deuxième méthode vu en cours pour créer un tableau html à partir des lignes d'un fichier texte, la proposition d'utiliser les fonctions echo et read pour suivre étape par étape l'exécution d'une boucle est valable !

L'exemple en image :

Script de la deuxième méthode avec ajout des fonctions echo et read

Vu du terminal à l'exécution du script


ASTUCE POUR SUIVRE DANS LE TERMINAL L'EXECUTION D'UNE BOUCLE [PROBLEME!]

Aujourd'hui, nous sommes à la recherche d'un moyen qui nous permettrait de suivre l'exécution d'un script traitant un nombre important de données via une boucle.

Dans le cas de nos URLs, nous souhaitons par exemple savoir à chaque fois qu'une nouvelle ligne a bien été créée dans notre tableau.

Pour cela, nous pouvons ajouter une fonction echo dans la boucle, par exemple :

echo "L'URL $url a bien été traitée.";

De cette manière, la liste de toutes les URLs traitées s'affiche dans le terminal au moment de l'exécution du script.

Voici un exemple en image :

Exemple de script avec ajout d'une fonction echo


Vu dans le terminal après l'exécution du script


Pour créer une interaction avec l'utilisateur, on peut exploiter une des caractéristiques de la fonction read qui après avoir lu une donnée attend une validation par ENTER avant de poursuivre le script.

On pourrait donc enrichir le script précédent comme ceci :

echo "L'URL $url a bien été traitée. Appuyer sur ENTER pour continuer.";
read;

Voici ce qu'on obtient :

La liste d'URLs à traiter (test)


Le nouveau script

Exécution du script dans le terminal

Le tableau html en output


D'après ces captures d'écran, on voit que notre programme n'a pas fonctionné comme on l'aurait souhaité. On constate que :

- Il n'y a plus eu d'interaction dans le terminal avec l'utilisateur dès que le nom du fichier output a été saisi.
- Seules la première et la troisième ligne du fichier urls.txt ont été insérées dans le tableau !

Si vous avez une explication pour ce mystérieux résultat ou bien une autre solution, vous pouvez laisser un message aux Bras Cassés dans les commentaires :) !