Nous avons, lors de notre
précédent billet, expliqué comment nous avions conçu un script Bash nous
permettant de construire un tableau donnant, pour chaque URL que nous avions
aspirée, son code retour HTML, son encodage ainsi que des liens vers la page
web correspondante et son code source.
Nous avons lors du dernier cours
amélioré ce tableau.
D’une part, lorsque le code
retour n’est pas « 200 », nous avons décidé de laisser vides les
colonnes suivantes, puisque cela signifie que la page n’est de toutes façons
pas exploitable. Pour cela nous avons utilisé la structure conditionnelle
suivante :
if [[ $coderetour == 200 ]]
then
encodage=$(curl
-SIL -o tmp.txt -w %{content_type} $ligne |cut -f2 -d"="|tr '[a-z]'
'[A-Z]' | tr -d '\r' | tr -d "\"");
curl
-L -o "./PAGES-ASPIREES/$numerotableau-$compteur.html"
"$ligne";
echo
"<tr><td>$compteur </td><td><a
href=\"$ligne\"target=\"_blank\">$ligne</a></td><td>CODE
RETOUR=$coderetour</td><td>ENCODAGE =
$encodage</td><td><a
href=\"../PAGES-ASPIREES/$numerotableau-$compteur.html\">$numerotableau-$compteur.html</a></td></tr>"
>> $2/tableau.html;
else
echo
"<tr><td>$compteur </td><td><a
href=\"$ligne\"target=\"_blank\">$ligne</a></td><td>CODE
RETOUR=$coderetour</td><td>-</td><td>-</td>td>-</td></tr>"
>> $2/tableau.html;
fi
Dans une structure
conditionnelle, if introduit la
condition, que l’on place entre doubles crochets (en n’oubliant pas les
espaces). Puis then, précédé d’une
indentation, introduit la commande que l’on veut voir effectuée si la condition
est remplie. Dans le cas où l’on souhaite qu’une autre commande soit effectuée
si la condition n’est pas remplie, on utilise else (puis une indentation mais, cette fois, sans then) On clôt la structure
conditionnelle avec fi (if à
l’envers).
Ensuite, nous avons ajouté une
colonne au tableau, dans laquelle nous avons placé un lien vers un fichier
contenant le texte de la page. Pour aspirer le contenu texte d’une page web,
nous avons utilisé la commande lynx
et ses fonctionnalités -dump pour
extraire le texte, -nolist pour ne
pas avoir l’indexation des url, assume-charset
pour préciser la nature de l’encodage à l’entrée, et enfin display-charset pour afficher la nature de l’encodage à la sortie. Un
fichier est ainsi créé pour chaque URL et placé dans le répertoire DUMP-TEXT,
puis un lien vers ce fichier est ajouté dans la dernière colonne du tableau.
Il convient de préciser que nous
utilisons la commande lynx non pas
directement sur l’URL, mais sur le fichier contenant le code source que nous
avons aspiré et se trouvant dans le répertoire PAGES-ASPIREES. Ainsi nous
passons outre d’éventuelles barrières qui nous empêcheraient de récupérer les
données de certains sites.
La commande est la
suivante :
lynx -dump
-nolist -assume-charset=$encodage -display-charset=$encodage
"./PAGES-ASPIREES/$numerotableau-$compteur.html" > ./DUMP-TEXT/$numerotableau-$compteur.txt;
echo
"<tr><td>$compteur </td><td><a
href=\"$ligne\"target=\"_blank\">$ligne</a></td><td>CODE
RETOUR=$coderetour</td><td>ENCODAGE =
$encodage</td><td><a href=\"../PAGES-ASPIREES/$numerotableau-$compteur.html\">$numerotableau-$compteur.html</a></td><td><a
href=\"../DUMP-TEXT/$numerotableau-$compteur.txt\">$numerotableau-$compteur.txt</a></td></tr>"
>> $2/tableau.html;
Nous avons également amélioré
notre commande permettant de trouver l’encodage de la page. En effet, nous
avions remarqué que la commande que nous avions trouvée n’était pas
satisfaisante car l’encodage ne se trouve pas toujours à la 2e ligne
du protocole html. Ainsi, sur le même modèle que la commande permettant
d’extraire le code source, existe la commande suivante : curl -SIL -o tmp.txt -w %{content_type}
Cette commande retournera tout ce
qui suit « Content-type », par exemple : text/html ; charset=UTF-8
Afin de n’extraire que l’encodage
(par exemple ici UTF-8), nous complétons la commande ainsi : curl -SIL -o tmp.txt -w %{content_type}
$ligne |cut -f2 -d"="|tr '[a-z]' '[A-Z]' | tr -d '\r' | tr -d
"\"")
Nous récupérons ainsi uniquement
ce qui suit le « = », le passons en majuscule et nous supprimons
d’éventuels guillemets et retour à la ligne. Le passage en majuscules a deux
motivations : pouvoir demander ensuite si « encodage == "UTF-8" » et, s’il ne s’agit pas d’UTF-8,
pouvoir le trouver dans la liste de la commande iconv (voir les explications qui suivent).
Nous souhaitons maintenant
convertir les fichiers du répertoire DUMP-TEXT en UTF-8 lorsqu’ils ont un
encodage différent, grâce à la commande iconv.
Nous avons pour cela encore besoin d’une structure conditionnelle (que nous
imbriquons dans la première puisque nous ne cherchons l’encodage que si le code
retour est égal à 200).
Tout d’abord, nous souhaitons
savoir si (if) l’encodage est en
UTF-8. Si c’est le cas, nous aspirons le texte de la page avec lynx et ajoutons
le lien dans le tableau comme vu plus haut. Sinon (else), il nous faut vérifier que l’encodage extrait avec notre
commande curl est bien un encodage
existant, et si ce n'est pas le cas trouver une autre manière de récupérer l’encodage de la page. Une
fois l’encodage trouvé, il nous faut convertir le texte en UTF-8. Nous
arrivons là au travail que nous devions effectuer seuls pendant les vacances de
la Toussaint. Voici la solution que nous proposons.
Nous commençons par vérifier que
l’encodage que nous avons extrait se trouve dans la liste des encodages pris en
charge par la commande iconv que nous souhaitons utiliser. Pour cela nous
affichons cette liste avec la commande iconv -l puis nous y cherchons notre
encodage avec la fonction egrep –oi (et comme certains encodages apparaissent
plusieurs fois dans la liste, nous ajoutons uniq). Nous enregistrons le
résultat dans une variable. Voici la commande pour cela :
encodage=$(iconv -l | egrep -oi $encodage | uniq)
Si cette dernière est vide (if [[ $encodage == "" ]]), cela
signifie que l’encodage que nous avions n’est pas valide (sinon nous pouvons
déjà le convertir comme nous le verrons plus loin). Nous essayons donc une 2e
technique pour trouver l’encodage. Cette seconde technique consiste à chercher
dans le code source si l’encodage a été spécifié. Nous cherchons donc dans le fichier
du répertoire PAGES-ASPIREES la ligne où se trouve la mention « charset »
(si elle existe). En ne récupérant dans cette ligne que ce qui suit le « charset= »
(pour cela nous utilisons la commande sed et remplaçons cette chaîne de
caractère par un simple caractère qui pourra ainsi servir de délimiteur avec
cut), puis dans cette sélection seulement ce qui précède le premier espace (et
en supprimant guillemets, balise fermante etc. comme précédemment), nous
obtenons un nouvel encodage que nous vérifions comme le précédent :
encodage=$(egrep "charset"
"./PAGES-ASPIREES/$numerotableau-$compteur.html"| sed –r "s/charset=/%/g"
| cut -f2 -d"%"|cut -f1 -d" "|tr '[a-z]' '[A-Z]' | tr -d
'(\r|\"|/>)');
encodage= $(iconv -l | egrep -oi $encodage | uniq)
if [[ $encodage == "" ]]
Si le résultat n’est toujours pas valide alors nous nous arrêtons là et
ne récupérons pas le texte de la page :
then
echo
"<tr><td>$compteur </td><td><a
href=\"$ligne\"target=\"_blank\">$ligne</a></td><td>CODE
RETOUR=$coderetour</td><td>ENCODAGE =
$encodage</td><td><a
href=\"../PAGES-ASPIREES/$numerotableau-$compteur.html\">$numerotableau-$compteur.html</a></td><td>-</td></tr>"
>> $2/tableau.html;
Sinon, nous récupérons le texte, et si l’encodage n’est pas en UTF-8,
nous le convertissons avec iconv -f
encodage_source -t encodage_cible fichier. Puis nous ajoutons le lien dans
la dernière colonne du tableau.
else
lynx
-dump -nolist -assume-charset=$encodage -display-charset=$encodage
"./PAGES-ASPIREES/$numerotableau-$compteur.html" > ./DUMP-TEXT/$numerotableau-$compteur.txt;
if
[[ $encodage != "UTF-8" ]]
then
iconv -f $encodage -t UTF-8 ./DUMP-TEXT/$numerotableau-$compteur.txt
fi
echo
"<tr><td>$compteur </td><td><a
href=\"$ligne\"target=\"_blank\">$ligne</a></td><td>CODE
RETOUR=$coderetour</td><td>ENCODAGE =
$encodage</td><td><a
href=\"../PAGES-ASPIREES/$numerotableau-$compteur.html\">$numerotableau-$compteur.html</a></td><td><a
href=\"../DUMP-TEXT/$numerotableau-$compteur.txt\">$numerotableau-$compteur.txt</a></td></tr>"
>> $2/tableau.html;
fi
Ce script ne semble pas parfait car nous constatons
encore quelques messages d’erreur lors du lancement du programme et, en effet,
il manque encore quelques encodages dans le tableau. La commande egrep sur le code source de l’URL ne
semble pas prendre en compte toutes les possibilités. De plus, en la testant
sur un des fichiers dont il manque l’encodage dans le tableau, nous remarquons
qu’elle retourne une chaîne de caractère avec un espace, ce qui ne devrait pas
être possible avec la fonction cut -d“ ”.
Il nous reste donc encore à trouver une solution à ce problème, lors d’un
prochain billet.
Commentaires
Enregistrer un commentaire