Le script Perl
Pour télécharger le script et ses ressources... : ici.
(à décompresser dans le répertoire contenant l'arborescence du script bash ; le script se trouve dans le dossier PROJET/PERL/PROGRAMMES, et le tableau sera créé dans le dossier PROJET/SITE).
Création du tableau
Lancement du script : déclaration des packages
#!/usr/bin/perl
# On se place initialement dans le répertoire contenant le programme via la commande cd (ici le dossier PROGRAMMES du dossier PERL : AxelKunMarjo/PERL/PROGRAMMES)
# Exécution du script dans l'invite de commande : perl traitementperl.pl
# Importation des modules utilisés dans le script
# pour utiliser des variables locales, precedees par 'my' lors de l'affectation d'une valeur
use
locale;# pour utiliser les urls, non pas comme des simples chaînes de caracteres, mais comme des ressources abstraites/physiques
use
URI::URL;# module permettant de recuperer simplement une page Web
use
LWP::Simple;# ce module connait de nombreux encodages et permet leur conversion
use
Encode;# module permettant l'encodage et le decodage des entites HTML
use
HTML::Entities;# module permettant d'afficher correctement les caracteres accentues dans la console
use
utf8;# module permettant de créer/supprimer des arborescences de dossiers par récursivité (commandes mkpath, rmtree)
use
File::Path;_______________________
Préparatifs
#########################
# Opérations diverses de préparation #
#########################
# Suppression de l'arborescence NUAGES (pour éviter la concaténation infinie lorsque l'on relance le script)
rmtree
( "../NUAGES/" );# Debut de la page HTML
# on ouvre en ecriture le fichier html qui contiendra le tableau final
open
(TABLEAU, ">:encoding(UTF-8)", '../../SITE/tabloperl.html');# pour ne pas surcharger le script, les informations sur l'en-tête de la page html (pour le site final) sont stockees dans un fichier html
# on declare le chemin de ce fichier (pour pouvoir l'utiliser dans la commande 'open')
my
$pathheader
= "./headerperl.html";# on ouvre le fichier html
# s'il y a un probleme lors de l'ouverture (chemin mal specifié, erreur de fichier, etc.), le programme s'arrête avec la commande 'die'
open
(HEADER, "<:encoding(UTF-8)",$pathheader
)||
die
"Impossible d'ouvrir $pathheader : $!\n";my
@header = <HEADER>;# grâce à la variable header, on imprime dans la page du tableau des resultats l'en-tête contenue dans le fichier html
# enfin, on ferme le fichier d'en-tête html
close
(HEADER);################
# Opérations terminées #
################
_______________________
Boucles et tableau
#######################
# Début des boucles et du tableau #
#######################
# declaration du chemin du dossier 'URLs' (contenant les repertoires par langue), que l'on stocke dans la variable '$pathdosURL'
my
$pathdosURL
= "../URLs/";# ouverture du dossier 'URLs' --> syntaxe de la commande 'opendir' : ( nom du contenu du dossier , chemin du dossier )
opendir
(DOSURL,$pathdosURL
);# on recupere le contenu du repertoire 'URL' dans la variable @dossierlangue (chaque repertoire de langue contenu dans le dossier sera liste dans cette variable)
my
@dossierlangue =opendir
(DOSURL);# Tout d'abord, on va traiter chacun des dossiers de langue du dossier 'URLs'
# "pour chacun des dossiers contenu dans la liste des dossiers de langue"...
foreach
my
$dossierlangue
(@dossierlangue) {# pour pouvoir par la suite nommer les tableaux par langue, on garde le nom de chaque dossier dans la variable $langue (avant que la variable $dossierlangue soit modifiee)
my
$langue
=$dossierlangue
;# on ne veut pas traiter les fichiers caches (dont le nom est sous la forme '.' ou '..') contenus dans le repertoire
# pour cela, on reduit le traitement seulement aux dossiers avec la commande 'next if' suivi d'une expression reguliere
next
if
$dossierlangue
=~/^\.\.?$/;# on declare, toujours dans la meme variable (dont le contenu precedent est alors ecrase), le chemin des dossiers de langue
# Remarque : il faut toujours preciser les chemins, car il n'est pas logique pour PERL que le fichier/dossier dont on parle se situe dans le meme repertoire qu'un autre fichier/dossier specifie precedemment
$dossierlangue
= "../URLs/$dossierlangue
";# on verifie que ce que contient à ce moment-là la variable $dossierlangue est bien un dossier : si c'est le cas, on peut continuer le traitement
if
(-d
$dossierlangue
) {# on ouvre chaque dossier, grâce au chemin stocke dans la variable $dossierlangue
opendir
(DOSLANGUE,$dossierlangue
);# pour verifier que tout fonctionne jusque là, on precise à l'utilisateur que le programme entre dans chaque repertoire au fur et à mesure
$dossierlangue
,"\n\n";# les informations lues dans chaque dossier (ici, les fichiers d'urls) sont stockees dans la liste '@fichierurl'
my
@fichierurl =readdir
(DOSLANGUE);# dans le fichier html final, on commence à ecrire l'en-tete du tableau pour chaque langue
<thead>
<tr>
<th id=\"
$dossierlangue
\" colspan=\"5\">$langue
</th> <!-- Regroupement des différentes colonnes (5 au total) par langue --></tr>";
# à l'interieur de la premiere boucle, on va traiter chacun des fichiers de chaque dossier de langue
foreach
my
$fichierurl
(@fichierurl) {# on stocke le nom du fichier d'urls dans $sens (puisque les fichiers sont organises par sens dans chaque dossier de langue)
# cela va nous permettre de nommer la colonne dediée et ranger les fichiers de resultats créés
my
$sens
=$fichierurl
;# on exclut les fichiers cachés de la liste des fichiers d'urls
next
if
$fichierurl
=~/^\.\.?$/;# on precise à l'utilisateur que chaque fichier d'urls est trouvé
$fichierurl
," trouvé !\n\n";# on specifie le chemin de chaque fichier, necessaire pour la commande 'open'
$fichierurl
="$dossierlangue
/".$fichierurl
;# si on a bien un fichier, le traitement peut continuer
if
(-f
$fichierurl
) {# on ouvre chaque fichier
open
(fichierurl,$fichierurl
);# on precise à l'utilisateur que la commande 'open' a bien fonctionne
$fichierurl
,"\n\n";# on commence la numerotation i, qui va servir à traiter chaque ligne des fichiers d'urls et egalement à nommer les fichiers de resultat crees
my
$i
=1;# on ecrit, toujours dans l'en-tete du tableau, les differentes colonnes qu'il y aura pour chaque resultat
<th> SENS
$sens
</th><th> Page aspiree </th>
<th>; Texte brut </th>
<th id=\" colspan=\"2\"> Contexte </th>
</th>
</thead>";
###############
# Fin des préparatifs #
###############
_______________________
Traitement des fichiers
#################
# Traitement des fichiers #
#################
# On commence le traitement des URLs contenues dans chaque fichier
# on lit chaque ligne du fichier d'urls et on l'affecte à la variable $URL
while
(my
$URL
=<fichierurl>) {# on precise à l'utilisateur quelle URL est en train d'etre traitee (on met cette ligne avant le traitement effectif)
$URL
,"Traitement en cours... Patience !\n\n";____________
Aspiration des pages
################
# Aspiration de la page #
################
my
$page
= get($URL
);# Si l'aspiration est impossible ('$page
' n'a alors pas de valeur), on en informe l'utilisateur et le programme passe à l'url suivante
if
(not
defined
($page
) ) {}
____________
Extraction du texte brut
#################
# Extraction du texte brut #
#################
# Decodage et nettoyage de la page pour le dump
# on definit un codage par defaut pour la page
my
$codage_page
= "latin1";# si la page possede dejà un ecodage
if
($page
=~ /\bcharset\s*=\s*([\w-]+)/i) {# alors on le stocke sous cette meme variable
$codage_page
=$1
;}
# encode la page en unicode, quelque soit le codage initial (grâce au module Encode)
my
$page_unicode
=decode
($codage_page
,$page
);# suppression des balises html (appel à la procedure)
my
$texte_unicode
= supprime_html($page_unicode
);# remplacement des points de codes par le caractere qui leur est normalement attribue (appel à la procedure)
my
$texte
= normalise_latin1($texte_unicode
);____________
Recherche des motifs
Le traitement des motifs étant plutôt laborieux et répétitif, nous ne présentons seulement une langue en tant qu'exemple (ici, l'allemand).
Seule la variable $motif change selon le sens recherché et la langue.
###############################
# Recherche des contextes dans le texte brut #
###############################
# Le dictionnaire contient les définitions de chaque sens, pour définir les sens recherchés dans chaque fichier de contexte
my
$pathdico
= "./definitions.txt";open
(DICO, "<:encoding(UTF-8)",$pathdico
)||
die
"Impossible d'ouvrir $pathdico : $!\n";my
@def = <DICO>;my
$def_direction
=$def
[0];my
$def_signification
=$def
[1];my
$def_capacitephysique
=$def
[2];my
$def_capacitementale
=$def
[3];close
(DICO);# Définition des chemins des dossiers par langue
my
@doslangue = ("../URLs/$langue/","../URLs/Allemand/","../URLs/Anglais/","../URLs/Espagnol/","../URLs/Francais/","../URLs/Portugais/");
# Définition des chemins des fichiers par langue (sens indéfini)
my
@ficlangue = ("../URLs/Allemand/$sens","../URLs/Anglais/$sens","../URLs/Espagnol/$sens","../URLs/Francais/$sens","../URLs/Portugais/$sens");
# Définition des chemins des fichiers d'urls par sens
my
@sens_direction = ("../URLs/Allemand/1_Richtung","../URLs/Anglais/1_Direction","../URLs/Espagnol/1_Direccion","../URLs/Francais/1_Direction","../URLs/Portugais/1_Direcao");
my
@sens_signification = ("../URLs/Allemand/2_Bedeutung","../URLs/Anglais/2_Meaning","../URLs/Espagnol/2_Significacion","../URLs/Francais/2_Signification",
"../URLs/Portugais/2_Significacao");
my
@sens_capacitephy = ("../URLs/Allemand/3_Korperlichesinne","../URLs/Anglais/3_Physical_Sense","../URLs/Espagnol/3_Capacidad_Fisica","../URLs/Francais/3_Capacite_physique",
"../URLs/Portugais/3_Capacidade_Fisica");
my
@sens_capacitemen = ("../URLs/Allemand/4_Geistigesinne","../URLs/Anglais/4_Mental_Sense","../URLs/Espagnol/4_Capacidad_Intelectual","../URLs/Francais/4_Capacite_intellectuelle",
"../URLs/Portugais/4_Capacidade_Intelectual");
# on definit la variable '$contexte' où seront stockées les lignes de contexte, et également les variables nécessaires aux indications des motifs et du sens recherchés
my
$contexte
="";my
$contextetxt
="";my
$contextesens
="";my
$contextelangue
="";my
$motif
="";my
$def
="";# Extraction de contextes des fichiers dump en allemand
if
($doslangue
[0]eq
$doslangue
[1] ) {if
($ficlangue
[0]eq
$sens_direction
[0] ) {# on définit le sens recherché pour l'afficher dans le fichier résultat de contexte
$def
=$def_direction
;# on définit le mot à chercher dans le texte brut, que l'on stocke sous la variable '$motif'
$motif
= "(Richtung|Einbahnstra(ß|ss)e|Uhrzeigersinn)";# on redefinit une variable pour pouvoir modifier le contenu de la variable '$motif'
my
$motif_requete
=$motif
;# pour prendre le mot seul et pouvoir le placer dans une expression régulière, on enleve les guillemets notes dans la variable
$motif_requete
=~ s/\"//g;# à chaque fois que le motif est trouve...
while
($texte
=~ /\w*$motif_requete
\w*/ig ){# definition du nombre de mots dans les contextes gauche et droit
my
$contexte_gauche
= substr($`
, ( length($`
)-20) , 20);my
$contexte_droit
= substr($'
, 0, 20);# on concatene dans la variable de resultat toutes les lignes contenant le motif voulu
$contexte
.=$contexte_gauche
."|<span style=\"color: \#FE7F0E\"><b>".$&
."</b></span>|".$contexte_droit
."<br />";# on garde une trace en texte brut qui servira aux fichiers contextes pour les nuages
$contextetxt
.=$contexte_gauche
."|".$&
."|".$contexte_droit
."\n";}
# on concatène les résultats par sens pour créer le fichier contexte général par sens et par langue
$contextesens
$contextetxt
."\n";}
elsif
($ficlangue
[0]eq
$sens_signification
[0] ) {$def
=$def_signification
;$motif
= "(Bedeutung|Sinngehalt|Fehl(ü|u)bersetzung|Nonsens|zweideutig|Sinn)";my
$motif_requete
=$motif
;$motif_requete
=~ s/\"//g;while
($texte
=~ /\w*$motif_requete
\w*/ig ){my
$contexte_gauche
= substr($`
, ( length($`
)-20) , 20);my
$contexte_droit
= substr($'
, 0, 20);$contexte
.=$contexte_gauche
."|<span style=\"color: \#FE7F0E\"><b>".$&
."</b></span>|".$contexte_droit
."<br />";$contextetxt
.=$contexte_gauche
."|".$&
."|".$contexte_droit
."\n";}
$contextesens
.=$$contextetxt
."\n";}
elsif
($ficlangue
[0]eq
$sens_capacitephy
[0] ) {$def
=$def_capacitephysique
;$motif
= "(Sinn|Gef(ü|u)hl)";my
$motif_requete
=$motif
;$motif_requete
=~ s/\"//g;while
($texte
=~ /\w*$motif_requete
\w*/ig ){my
$contexte_gauche
= substr($`
, ( length($`
)-20) , 20);my
$contexte_droit
= substr($'
, 0, 20);$contexte
.=$contexte_gauche
."|<span style=\"color: \#FE7F0E\"><b>".$&
."</b></span>|".$contexte_droit
."<br />";$contextetxt
.=$contexte_gauche
."|".$&
."|".$contexte_droit
."\n";}
$contextesens
.=$contextetxt
."\n";}
elsif
($ficlangue
[0]eq
$sens_capacitemen
[0] ) {$def
=$def_capacitementale
;$motif
= "(Sinn|Gesp(ü|u)r|Verst(a|ä)nd|Empfinden|Gef(ü|u)hl|Unziemlichkeit|Erfolgserlebnis|Organisationstalent)";
my
$motif_requete
=$motif
;$motif_requete
=~ s/\"//g;while
($texte
=~ /\w*$motif_requete
\w*/ig ){my
$contexte_gauche
= substr($`
, ( length($`
)-20) , 20);my
$contexte_droit
= substr($'
, 0, 20);$contexte
.=$contexte_gauche
."|<span style=\"color: \#FE7F0E\"><b>".$&
."</b></span>|".$contexte_droit
."<br />";$contextetxt
.=$contexte_gauche
."|".$&
."|".$contexte_droit
."\n";}
$contextesens
.=$$contextetxt
."\n";}
# on concatène les résultats par langue pour créer par la suite le fichier contexte général par langue
$contextelangue
.=$contextetxt
."\n";}
etc.
################
# Traitement terminé ! #
################
_______________________
Création des fichiers des résultats
#########################
# Création des fichiers des resultats #
#########################
# Création de l'arborescence des dossiers de résultat
my
@arbores=("../PAGES-ASPIREES/$langue
/$sens
","../DUMP-TEXT/$langue
/$sens
/","../CONTEXTES/$langue
/$sens
/","../NUAGES/CONTEXTES/$langue
/","../NUAGES/DUMP-TEXT/$langue
/");# Pour chaque chemin inscrit dans la table '@arbores', on créé l'arborescence si elle n'existe pas
foreach
(@arbores){(
-d
$_
) ||mkpath
$_
or
die
("Erreur lors de la création de l'arborescence de répertoires $_\n");}
# assignation des chemins ou chercher/placer les differents fichiers de resultat
my
$pageASP
="../PAGES-ASPIREES/$langue
/$sens
/pageaspiree".$i
.".html";my
$pageDUMP
="../DUMP-TEXT/$langue
/$sens
/dump".$i
.".txt";my
$pageCONTEXTE
="../CONTEXTES/$langue
/$sens
/contexte".$i
.".html";my
$pageCONTEXTEtxt
="../CONTEXTES/$langue
/$sens
/contexte".$i
.".txt";my
$contextegeneralsens
="../NUAGES/CONTEXTES/$langue
/contexte$langue
$sens
.txt";my
$dumpgeneralsens
="../NUAGES/DUMP-TEXT/$langue
/dump$langue
$sens
.txt";my
$contextegenerallangue
="../NUAGES/CONTEXTES/$langue
/contexte$langue
.txt";my
$dumpgenerallangue
="../NUAGES/DUMP-TEXT/$langue
/dump$langue
.txt";# Ouverture en ecriture des differents fichiers
open
(OUT1, ">$pageASP
");open
(OUT2, ">:encoding(UTF-8)",$pageDUMP
);open
(OUT3, ">:encoding(UTF-8)",$pageCONTEXTE
);open
(OUT4, ">:encoding(UTF-8)",$pageCONTEXTEtxt
);# impression des resultats dans ces fichiers
$page
;$texte
;$contextetxt
;<html xmlns=\"http://www.w3.org/1999/xhtml\">
<head>
<title>
$pageCONTEXTE
</title><meta http-equiv=\"Content-Language\" content=\"Français\" />
<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">
<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../SITE/style.css\" media=\"screen\" />
</head>
<body>
<div id=\"wrap\">
<div id=\"header\">
<h1><a href=\"../../../../SITE/index.html\">La vie du mot \"sens\" sur le Web</a></h1>
<h2>Master 1 PluriTAL - Projet encadré - Site de Jin Kun, Marjorie Seizou et Axel Court</h2>
</div>
<div id=\"top\"> </div>
<div id=\"content\">
<div class=\"unique\">
<div class=\"articles\">
<h4>Fichier de travail :</h4><ul><span style=\"color: #FF4800\"><b>../DUMP-TEXT/
$pageDUMP
</b></span></ul><br /><h4>Forme voulue :</h4><ul><span style=\"color: #FF4800\"><b>
$motif
</b></span></ul><br /><h4>Définition :</h4><ul><span style=\"color: #FF4800\"><b>
$def
</b></span></ul><br />_____________________________________________________________
<br />"
$contexte
;</div>
</div>
<div id=\"bottom\"> </div>
<div id=\"footer\">
Designed by <a href=\"http://www.free-css-templates.com/\">Free CSS Templates</a>
</div>
</div>
</body>
</html>";
# concaténation des fichiers contexte et dump par sens
open
(OUT5,">>$contextegeneralsens
");open
(OUT6,">>$dumpgeneralsens
");$contextesens
;$texte
;# concaténation des fichiers contexte et dump par langue
open
(OUT7,">>$contextegenerallangue
");$contextelangue
;open
(OUT8,">>$dumpgenerallangue
");$texte
;# fermeture des fichiers
close
(OUT1);close
(OUT2);close
(OUT3);close
(OUT4);close
(OUT5);close
(OUT6);close
(OUT7);close
(OUT8);############
# Fichiers créés ! #
############
_______________________
Ajout des liens
#################################
# Ajout des liens vers les fichiers dans le tableau #
#################################
# on imprime dans le tableau les liens renvoyant aux fichiers precedemment crees
<tr>
<td><a href=\"
$URL
\" target=\"_blank\">URL$i
</a></td>";
# Si tout s'est bien passé, on peut écrire les liens pointant vers les fichiers correspondants
# Sinon, il se peut qu'un traitement n'ait pas fonctionné et le fichier créé est donc vide : on imprime alors un message d'erreur
# Si le fichier pageaspiree.html est vide, tous les autres traitements n'ont pas pu fonctionner...
if
(-z
$pageASP
) {</tr>";
}
# Si le fichier pagedump.txt est vide... (et donc que le contexte n'a pas pu être récupéré)
elsif
((-s
$pageASP
)&&
(-z
$pageDUMP
)) {<td><a href=\"../PERL/PAGES-ASPIREES/
$langue
/$sens
/pageaspiree$i
.html\" target=\"_blank\">Page Aspirée</a></td><td colspan=\"3\">Oups ! Fichiers vides</td>
</tr>";
}
# Si seul le fichier pagecontexte.html est vide...
elsif
((-s
$pageASP
)&&
(-s
$pageDUMP
)&&
(-z
$pageCONTEXTE
)) {$langue
/$sens
/pageaspiree$i
.html\" target=\"_blank\">Page Aspirée</a></td><td><a href=\"../PERL/DUMP-TEXTE/
$langue
/$sens
/dump$i
.txt\" target=\"_blank\">Dump</a></td><td colspan=\"2\">Oups ! Fichiers vides : vérifier le dump</td>
</tr>";
}
# Sinon, les fichiers ne sont pas vides...
else
{$langue
/$sens
/pageaspiree$i
.html\" target=\"_blank\">Page Aspirée</a></td><td><a href=\"../PERL/DUMP-TEXTE/
$langue
/$sens
/dump$i
.txt\" target=\"_blank\">Dump</a></td><td><a href=\"../PERL/CONTEXTES/
$langue
/$sens
/contexte$i
.html\" target=\"_blank\">Version HTML</a></td><td><a href=\"../PERL/CONTEXTES/
$langue
/$sens
/contexte$i
.txt\" target=\"_blank\">Version TXT</a></td></tr>"; }
############
# Liens ajoutés ! #
############
_______________________
Fin du script !
###########################
# Finalisation du tableau et fin du script #
###########################
# incrementation du compteur (pour le traitement de chaque url)
$i
+= 1;# Fin des différents traitements pour chaque url
}
# Fin de la condition pour le traitement des fichiers seulement à l'intérieur des dossiers de langue(et non des fichiers cachés, dans la deuxième boucle)
}
# Fin de la deuxième boucle 'foreach', pour le traitement de chaque fichier d'urls à l'intérieur des dossiers de langue
}
# on imprime le pied de chaque tableau
# on ajoute un espace entre les tableaux des differentes langues un lien vers le haut de la page
# Fin de la condition pour le traitement des dossiers de langue seulement (et non des fichiers cachés, dans la première boucle)
closedir
(DOSLANGUE);}
# Fin de la première boucle 'foreach', pour le traitement de chaque dossier de langue
}
# Fin du tableau html : fermeture des balises (contenues dans le fichier footperl.html)
my
$pathfoot
= "./footperl.html";open
(FOOT, "<:encoding(UTF-8)",$pathfoot
)||
die
"Impossible d'ouvrir $pathfoot : $!\n";# on imprime les lignes contenues dans le fichier html de pied de tableau (autre façon de procéder : ligne par ligne)
while( <FOOT> ) {
$_
";}
close
(FOOT);# Fermeture du tableau et du dossier contenant les dossiers de langue
close
(TABLEAU);closedir
(DOSURL);# Fin de l'éxecution du script
exit
;#########
# THE END ! #
#########
______________________________________________________________
Fonctions (procédures)
#########
# Fonctions #
#########
# Pour supprimer les balises html dans la page aspirée
sub
supprime_html {my
@balises_a_ignorer = ("applet","code","embed","head","object","script","server");my
$html
=shift
@_;$html
=~ s/\n+/ /g;$html
=~ s/\r+/ /g;decode_entities
($html
);foreach
my
$balise
(@balises_a_ignorer) {$html
=~s/<$balise
.*?<\/$balise
>//ig;}
$html
=~ s///g;#commentaires
$html
=~ s/<\/?p\/?>/\n/ig;#paragraphes
$html
=~ s//\n/ig;#retours à la ligne
$html
=~ s/<\/tr>/\n/ig;#lignes de tableau
$html
=~ s/<\/?h[1-6]>/\n/ig;#titres
$html
=~ s/<\/?div.*?>/\n/ig;#sections
$html
=~ s/<.*?>//g;#autres balises
$html
=~ s/\s*\n\s*/\n/g;#espaces en debut/fin de ligne
$html
=~ s/ +/ /g;#sequences de plusieurs espaces
return
$html
;}
#----------------------------------------------------------------------------
# Pour remplacer certains points de code par leur correpondant en latin-1
sub
normalise_latin1 {my
$chaine
=shift
@_;$chaine
e =~ s/[\x{2019}\x{2018}]/\'/g;$chaine
=~ s/[\x{201C}\x{201D}]/\"/g;$chaine
=~ s/[\x{2013}\x{2014}]/-/g;$chaine
=~ s/\x{2026}/.../g;$chaine
=~ s/\x{0152}/OE/g;$chaine
=~ s/\x{0153}/oe/g;$chaine
=~ s/[^\x{0000}-\x{00FF}]//g;return
$chaine
;}