Boîte à outils 1
Le rôle de cette boîte à outils est de parcourir l'arborescence des fichiers XML contenant les flux RSS pour en extraire les champs "titre" et "description". Ainsi, notre objectif est de produire deux types de fichiers de sorties par rubrique (culture, internationale, sport, etc.): un fichier au format ".txt" et un autre au format XML contenant chacun les titres et les descriptions des mises à jour à partir du corpus 2014.
Les fichiers contenant les flux RSS sont organisés dans des sous-répertoires d'un répertoire principal. Ce dernier est parcouru récursivement (la fonction "parcoursarborescencefichiers" appelle elle même à la rencontre de chaque sous-répertoire):
sub parcoursarborescencefichiers { my $path = shift(@_); opendir(DIR, $path) or die "Can't open $path: $!\n"; my @files = readdir(DIR); closedir(DIR); foreach my $file (@files) { next if $file =~ /^\./; $file = $path."/".$file; if (-d $file) { &parcoursarborescencefichiers($file); } if (-f $file) {
A la rencontre d'un fichier, le programme teste si celui-ci est au format XML et son nom ne commence pas par le motif "fil":
if (-f $file) { if (($file=~/\.xml$/) && ($file!~/\/fil.+\.xml$/)) { # Récupérer l'encodage du fichier
Par la suite, l'appel de la fonction "trouve_encodage" pour le fichier courant permet de récupérer l'encodage du fichier XML du flux RSS:
# Récupérer l'encodage du fichier my $encodage=trouve_encodage($file); # si l'encodage n'est pas vide, faire le traitement... if ($encodage ne "") { my $texte = ""; my $texteXML="<file>\n"; $texteXML.="<name>$file</name>"; $texteXML.="<items>\n"; my $texteBRUT=""; # Trouver la rubrique
Enfin, si l'encodage est trouvé, on appelle la fonction "trouve_rubrique" qui va rouvrir le fichier XML avec le bon encodage afin de chercher la rubrique du flux RSS contenu dans ce fichier:
# Trouver la rubrique my ($rub, $texte) = trouve_rubrique($file, $encodage); print "RUBRIQUE : $rub\n";
Voici maintenant la fonction repererubriques qui exécute toutes les étapes citées ci-dessus et sauvegarde l'ensemble des rubriques dans "$dicoRUB":
sub repererubriques { my $path = shift(@_); opendir(DIR, $path) or die "can't open $path: $!\n"; my @files = readdir(DIR); closedir(DIR); foreach my $file (@files) { # Ignorer les répertoire . et .. et tous les fichiers cachés (commençant par .) next if $file =~ /^\./; # Construire le nom de fichier en lui rajoutant le chemin complet $file = $path."/".$file; if (-d $file) { &repererubriques($file); } if (-f $file) { # Ne traiter que les fichiers "xml" (ignorer aussi les fichiers ayant le format "filXXX.xml") if (($file=~/\.xml$/) && ($file!~/\/fil.+\.xml$/)) { # Récupérer l'encodage du fichier my $encodage = trouve_encodage($file); if ($encodage ne "") { # Trouver la rubrique my ($rub, $texte) = trouve_rubrique($file, $encodage); # mémoriser les rubriques if ($rub ne ""){ $dicoRUB{$rub}++; } } else { print"Fichier $file ==> encodage non détecté \n"; } } } } }
On passe ensuite à la détection des titres et descriptions, que l'on stocke dans des variables pour effectuer plusieurs traitements :
while ($texte =~ /<item><title>(.+?)<\/title>.+?<description>(.+?)<\/description>/g) { my $titre=$1; my $desc=$2; ############################### my $rss = new XML::RSS; $rss->parsefile($file); foreach my $item(@{$rss->{'items'}}) { my $titre = $item->{'title'}; my $desc = $item->{'description'}; # si l'encodage n'est pas UTF-8, réencoder via le module Unicode::String if (uc($encodage) ne "UTF-8"){ utf8($titre); utf8($desc); } # traiter les caractère diachrités avec HTML::Entities $titre = HTML::Entities::decode($titre); $desc = HTML::Entities::decode($desc); $titre = &clean($titre); $desc = &clean($desc); # verifier s'il n'y a pas de doublons while ($texte =~ /<item><title>(.+?)<\/title>.+?<description>(.+?)<\/description>/g) { my $titre=$1; my $desc=$2; ########################### my $rss = new XML::RSS; $rss->parsefile($file); foreach my $item(@{$rss->{'items'}}) { my $titre = $item->{'title'}; my $desc = $item->{'description'}; # si l'encodage n'est pas UTF-8,réencoder via le module Unicode::String if (uc($encodage) ne "UTF-8"){ utf8($titre); utf8($desc); } # traiter les caractère diachrités avec HTML::Entities $titre = HTML::Entities::decode($titre); $desc = HTML::Entities::decode($desc); $titre = &clean($titre); $desc = &clean($desc); # verifier s'il n'y a pas de doublons
La fonction "clean" permet de supprimer les balises non pertinentes intégrées aux titres et descriptions et de filtrer certains caractères indésirables.
sub clean { my $texte=shift; $texte=~s/<img[^>]+>//g; $texte=~s/<a href[^>]+>//g; $texte=~s/<\/a>//g; $texte=~s/<[^>]+>//g; $texte=~s/&/et/g; $texte=~s/\x{201c}/“/g; $texte=~s/\x{201d}/”/g; $texte=~s/\x{2019}/’/g; $texte=~s/\x{2018}/‘/g; $texte=~s/\x{2013}/-/g; $texte=~s/\x{2192}/→/g; $texte=~s/\x{2026}/.../g; $texte=~s/\x{0153}/œ/g; $texte=~s/\x{0152}/Œ/g; $texte=~s/\x{fffd}/�/g; # caractère de remplacement $texte=~s/\x{20ac}/€/g; $texte=~s/\x{2009}/ /g; # thin space return $texte; }
Les titres et les discriptions ne doivent pas être stockés en doublons. Pour cela, on utilise des tables de hashage (dictionnaires):
my %dicoTITRES=(); my %dicoDESC=(); my %dicoRUB=();
if (!(exists $dicoTITRES{$titre}) and (!(exists $dicoDESC{$desc}))){ $dicoTITRES{$titre}++; $dicoDESC{$desc}++; $texteXML.="<item>\n<title>$titre</title>\n<description>$desc</description>\n</item>\n"; print OUTTXT "$titre\n"; print OUTTXT "$desc\n";
L'intérêt que nous portons à l'encodage est que nous voulons que les sorties XML soient en UTF-8 et les sorties ".txt" en ISO-8859-1.
my $output1=$sortie.$rub.".xml"; my $output2=$sortie.$rub.".txt"; if (!open (OUTXML,">>:encoding(utf-8)", $output1)) { die "Can't open file $output1"; } if (!open (OUTTXT,">>:encoding(iso-8859-1)", $output2)) { die "Can't open file $output2"; }
Vous pouvez télécharger ici le script entier
Vous pouvez également voir ici un exemple du résultat TXT et XML pour la rubrique CINEMA.
Nous pouvons désromais passer à à la boîte à outils 2 où on va utiliser des outils d'annotation afin d'étiqueter les titres et les descriptions.