Bao1 Filtrage et nettoyage

 


Le corpus du projet Boîte à outils est composé par les fichiers de flux RSS du journal Le Monde de de l'année 2014.

 

Tous les fichiers à traiter sont sous forme XML. On extrait le contenu balisé en «title » et en « description » qui continent le titre et le résumé de chaque nouvelle article.

 

Les fichiers XML sont nommés par les numéros qui représentent les rubriques correspondants.


Dans cette tâche, il s’agit d’abord de parcourir le répertoire de corpus et de lire les fichiers XML , ensuite on fait l’extraction de contenu textuel de <title> et de <description>, et finalement on le sauvegarde dans un fichier texte et un fichier XML.

 

On a utilisé un script perl pour réaliser cette tâche. Concernant les méthode, ici nous allons en présenter deux : une méthode d’expression régulière  et une autre méthode qui utilise la bibliothèque de « XML ::lib ».

 

A. La méthode d'expression régulière :

 

Le programme principal

 

01 #!/usr/bin/perl
02 <<DOC;
03 Votre Nom : Chunxiao YAN
04  mars 2015
05  usage : perl 2015BAO1exrg.pl repertoire-a-parcourir  repertoire-de-sortie
06 DOC
07 
08 use Unicode::String qw(utf8);
09 
10 #----------------------bon script par rub ----------------------------------------
11 my $rep="$ARGV[0]";
12 $rep=~ s/[\/]$//;  
13 
14 my $repsortie=$ARGV[1];
15 print $repsortie;
16 mkdir($repsortie) or die ("Probleme avec la creation du repertoire de $repsortie, verifier s'il en existe deja une");
17 
18 my %dicTitle=();
19 my %dicDescription=();
20 my %dicrubriques=();
21 #----------------------------------------
22 &parcoursarborescencefichiers($rep);    # traitement de tous les fichiers
23 
24 opendir(DIR, $repsortie) or die "probleme d'ouverture de repertoire: $!\n";
25 my @listefichiers = readdir(DIR);
26 closedir(DIR);
27 foreach my $fichier (@listefichiers) {
28     if ($fichier=~/\.xml$/) {
29     if (!open (FILE,">>:encoding(utf-8)",$repsortie."\\".$fichier)) { die "Pb a l'ouverture du fichier $output1"};
30     print FILE "</PARCOURS>\n";
31     close(FILE);
32     }    
33 }
34 exit;
 

 

Ce programme principal prend deux arguments en entrée:

 

perl     scriptbao1.pl       répertoire-de-corpus       répertoire-de-sortie

 

Ensuite trois tables de hachage sont établis :


my %dicTitle=();
my %dicDescription=();
my %dicrubriques=();

 

La fonction de parcoursarborescencefichiers($rep) parcours le répertoire du corpus , extrait le contenu de <title> et de <description> dans les fichiers XML de RSS, nettoie les données et les sauvegarde dans les fichiers textes et les fichiers XML classés par rubrique.

 

Finalement, on parcours le répertoire de sortie et écrit la balise de fin </parcours> dans tous les fichiers sorties en XML qu’on a créé au cours d’exécution de la fonction parcoursarborescencefichiers($rep).

 

Les fonctions :

 

01 sub parcoursarborescencefichiers {
02     my $path = shift(@_);
03     opendir(DIR, $path) or die "can't open $path: $!\n";
04     my @files = readdir(DIR);
05     closedir(DIR);
06     foreach my $file (@files) {
07     next if $file =~ /^\.\.?$/;
08     $file = $path."/".$file;
09     
10     if (-d $file) {
11         &parcoursarborescencefichiers($file);    #recurse!
12         print "je rentre dans $file \n ";
13         #my $attente=<STDIN>;
14         }
15     
16     if (-f $file) {
17         print "Traitement de : $file\n";
18         #print OUT "$file\n";
19         if (($file=~/\.xml$/) && ($file!~/\/fil.+\.xml$/)){
20             open(FILE,$file);
21             $ligne=<FILE>;
22             print $file;
23             close(FILE);
24         #----------------------detecte encodqge--------------------------------
25              $ligne =~/encoding=[\'\"]([^\'\"]+)[\'\"]/i;
26 
27             my $encodage = $1;
28             print "ENCODAGE : $encodage\n";
29         #----------------------------------------------------------------------
30             open (FILE,"<:encoding($encodage)",$file);
31             $chainecomplete = "";
32             while ($ligne=<FILE>) {
33             chomp $ligne;
34             $chainecomplete = $chainecomplete . " " . $ligne;
35             }
36             $chainecomplete=~s/> +</></g;
37         #-------------------traitement de fichier rubrique---------------------------------------
38         if ($encodage ne "") {
39             print "Extraction dans : $file \n";
40             my $tmptexteXML="<file>\n";
41             $tmptexteXML.="<name>$file</name>\n";
42             $chainecomplete=~/<pubDate>([^<]+)<\/pubDate>/;
43             $tmptexteXML.="<date>$1</date>\n";
44             $tmptexteXML.="<items>\n";
45             my $tmptexteBRUT="";
46             # on recherche la rubrique
47             $chainecomplete=~/<channel>.*?<title>([^<]+)<\/title>/;
48             my $rub=$1;
49             $rub=&nettoyagerub($rub);
50             print "RUBRIQUE : $rub\n";
51             #---------------------------------------------------------------------------------------------------
52             my $output1=$repsortie."/SORTIE-extract-txt-".$rub.".xml";
53             my $output2=$repsortie."/SORTIE-extract-txt-".$rub.".txt";
54             if ( -e $output1) {
55                 print "exsite: $rub";  
56             }
57             else {
58             &fichiersortie($rub);
59             }
60             if (!open (FILEOUT1,">>:encoding(utf-8)", $output1)) { die "Pb a l'ouverture du fichier $output1"};
61             if (!open (FILEOUT2,">>:encoding(utf-8)", $output2)) { die "Pb a l'ouverture du fichier $output2"};

 

Dans cette partie, le programme parcours le répertoire du corpus et détecte les fichiers .xml de flux RSS, une fois le fichier .xml trouvé, on commence à traiter le fichier.

 

  1. 1. Lire le fichier ligne par ligne et extrait son encodage (19-29)
  2.  

  3. 2. Concaténer tous les lignes dans le fichier et le mettre dans la variable $chainecomplete  (30-36)
  4.  

  5. 3. Créer deux variables :$tmptexteXML et $tmptexteBRUT destinées à l'écriture du fichier sortie en xml et en texte brut (38-45)
  6.  

  7. 4. Trouver la rubrique du fichier et nettoyer le $rub (47-50)
  8.  

  9. 5. Créer les fichiers de sortie en rubrique en vérifiant son existence: if ( -e $output1), si le fichier existe, le programme passe à la mode d’écriture de données dans le fichier,sinon en utilisant la fonction fichiersortie($rub) on crée ce fichier de sortie de rubrique. (51-61)

 

01 #----------------------------------------------------------------------------------------------------
02         my $cpt=0;
03         
04         
05         #----------------------------------------------
06     while ($chainecomplete=~/<item><title>([^<]*)<\/title>.*?<description>([^<]*)<\/description>/g) {
07         my $title=$1;
08         my $description=$2;
09         if (uc($encodage) ne "UTF8") {
10                   print "changement en utf8\n";
11                     utf8($title);
12                     utf8($description);
13                 }
14         if (!(exists $dicTitle{$title})){
15                     $cpt++;            
16                     $dicTitle{$title}++;
17                     $dicDescription{$description}++;
18                     
19             #--------------nettoyage-------------------
20                     print "nettoyage";
21                     $title=&nettoyage($title);
22                     $description=&nettoyage($description);
23 
24                     $tmptexteBRUT.="§$title \n";                        
25                     $tmptexteBRUT.="$description \n";
26                     $tmptexteXML.="<item num=\"$cpt\"><title>$title</title><abstract>$description</abstract></item>\n";
27             }
28               else {
29                $tmptexteXML.="<item><title>-</title><abstract>-</abstract></item>\n";
30                print "doublons";
31             }    
32             }        
33             $tmptexteXML.="</items>\n</file>\n";
34             print FILEOUT1 $tmptexteXML;
35             print FILEOUT2 $tmptexteBRUT;
36             close FILEOUT1;
37             close FILEOUT2;
38             }
39             else {
40                     print "$file ==> $encodage \n";
41                 }
42     }
43     }    
44 
45 }    
46 }

 

Avec l’expression régulière , on arrive à extraire le $title et le $description.Puis on le transcode en utf-8 si les données ne sont pas en utf-8. Le deuxième  « if » sert à supprimer les doublons à l’aide de la vérification dans les dictionnaires qu’on a créé au début de programme.Après avoir nettoyé le $title et le $description, on les écrit dans les fichiers xml et les fichiers en texte brut.

 

Nous avons un compteur $cpt qui compte le nombre de «item » qu’on a traité dont les doublons sont exclus.

 

La variable $tmptexteBRUT et la variable $tmptexteXML permettent de concaténer tous les items extraits et de faciliter l’écritures du fichier de sortie.

 

Les autres fonctions :

 

Fonction de création des fichiers de sortie

01 sub fichiersortie {
02     my $rub=shift(@_);
03     my $output1=$repsortie."/SORTIE-extract-txt-".$rub.".xml";
04     my $output2=$repsortie."/SORTIE-extract-txt-".$rub.".txt";
05     if (!open (FILEOUT1,">:encoding(utf-8)", $output1)) { die "Pb a l'ouverture du fichier $output1"};
06     if (!open (FILEOUT2,">:encoding(utf-8)",$output2)) { die "Pb a l'ouverture du fichier $output2"};
07     print FILEOUT1 "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n";
08     print FILEOUT1 "<PARCOURS>\n";
09     print FILEOUT1 "<NOM>Chunxiao YAN 2015</NOM>\n";
10     close(FILEOUT1);
11     close(FILEOUT2);
12 
13 }

 

Fonctions de nettoyage

 

01 sub nettoyage {
02     my $chainetrouvee=shift(@_);
03     $chainetrouvee=~s/&#38;#39;/'/g;
04     $chainetrouvee=~s/&#38;#34;/"/g;
05     $chainetrouvee=~s/&#39;/'/g;
06     $chainetrouvee=~s/&#34;/"/g;
07     $chainetrouvee=~s/&#233;/é/g;
08     $chainetrouvee=~s/&#234;/ê/g;
09     $chainetrouvee=~s/&lt;.*?&gt;//g;
10     return $chainetrouvee;    
11 }
12 
13 sub nettoyagerub {
14     my $rub=shift(@_);
15         $rub=~ s/Le ?Monde.fr ?://g;
16         $rub=~s/ ?: ?Toute l'actualité sur Le Monde.fr.//g;
17         $rub=~s/\x{E8}/e/g;
18         $rub=~s/\x{E0}/a/g;
19         $rub=~s/\x{E9}/e/g;
20         $rub=~s/\x{C9}/e/g;
21         $rub=~s/ //g;
22         $rub=uc($rub); # mise en majuscules
23         $rub=~s/-LEMONDE.FR//g;
24         $rub=~s/:TOUTEL'ACTUALITESURLEMONDE.FR.//g;
25         $rub=~s/LEMONDE.FR-ACTUALITE//g;
26     return $rub
27 }

 

B. La méthode de XML::RSS

 

Tout d'abord, il faut importer la bibliothèque de XML ::RSS.

 

use strict;
use Unicode::String qw(utf8);
use XML::RSS;

 

Le programme principal est identique avec celui de la méthode d’expression régulière.

 

Dans la fonction de « parcoursarborescencefichier », après avoir détecté le fichier de traitement, au lieu de concaténer les lignes dans le fichier, on lance un passeur XML-RSS qui transforme le document en un tableau qui contient l’élément et son contenu textuel.

 

01 if ($encodage ne "") {
02         #------------------module xml rss--------------------------------------------------------
03             my $rss=new XML::RSS;
04             eval {$rss->parsefile($file); };
05             if( $@ ) {
06                    $@ =~ s/at \/.*?$//s;              
07                    print STDERR "\nERROR in '$file':\n$@\n";
08                 }
09             $rss->parsefile($file);
10             print "Extraction dans : $file \n";
11             my $canal = $rss->{'channel'};
12             my $rub=$canal->{'title'};
13             $rub=&nettoyagerub($rub);
14             print "RUBRIQUE : $rub\n";

 

De cette façons, on arrive à obtenir non seulement le $rub, mais aussi le $title et le $description:

 

foreach my $item (@{$rss->{'items'}}) {
               my $description=$item->{'description'};
               my $title = $item->{'title'};

 

Les fichiers de sortie

après l'exécution du programme, on obtient un fichier de texte et un fichier d'XML pour chaque rubrique.

 

Voici un exemple de fichier .txt (une partie dans fichier "SORTIE-extract-txt-ALAUNE.txt")

 

§ Marchés financiers : le scandale du Forex s'étend à Hongkong
Les autorités bancaires allemande, américaine, britannique, singapourienne et suisse ont ouvert parallèlement des enquêtes sur ce scandale où des traders auraient réussi à fausser l'indice qui détermine le cours des devises.
§ Centrafrique : l'UE lance sa propre opération militaire
« La force comprendra jusqu'à 1 000 soldats, dirigés par le général de division Philippe Pontiès », a précisé dans un communiqué le Conseil de l'Europe
§ Bambi menacé par le réchauffement climatique
Des chercheurs du CNRS et de l'Office national de la chasse et de la faune sauvage ont établi un lien entre avancée du printemps et surmortalité des faons.
§ Un homme retranché chez lui à Antony, le RER B arrêté
L'homme a tiré un coup de feu en l'air puis s'est retranché seul dans son appartement situé près des voies du RER B, dont la circulation a été interrompue.
§ Jacques Le Goff, mort d'un « ogre historien »
Le plus grand médiéviste français, Jacques Le Goff, est mort, mardi 1er avril, à l'âge de 90 ans à l'hôpital Saint-Louis.
§ Face au Bayern, Manchester United rêve de sauver sa saison
Distancée en championnat, l'équipe de David Moyes reçoit le Bayern Munich en quart de finale de la Ligue des champions.  Manchester tentera de reproduire l'exploit de 1999 pour sauver sa saison.
§ Pour le 1er avril, Le Gorafi devient sérieux
Le site parodique a décidé de ne pas rigoler, en ce 1er avril, avec un éditorial tristement sérieux.
§ Un site de rencontre boycotte Firefox à cause des idées de son PDG
Le site américain de rencontres OK Cupid est inaccessible depuis lundi avec le navigateur Firefox, de Mozilla. Le site a voulu contester la récente nomination du nouveau PDG de Mozilla, qui est publiquement opposé au mariage entre personnes du même sexe.
§ Des vins animés : le chasselas suisse
A la découverte de ce cépage hélévète... en deux minutes chrono !
§ L'Unedic a versé 756 millions d'euros d'allocations chômage à tort en 2013
L'Unedic, qui gère les seules allocations chômage, estime que « le poids des indus rapportés aux dépenses d'indemnisation est resté stable, à 2,52 % »
§ Les idées iconoclastes de Valls au PS
Manuel Valls, nouveau premier ministre français, a longtemps cultivé une posture à part au sein de la gauche.
§ La police disperse des manifestants à Ankara
Plusieurs milliers de partisans du principal parti de l'opposition se sont réunis pour dénoncer des fraudes supposées à l'élection municipale à Ankara.
§ La Norvège reconduit son quota de baleines chassées
La Norvège a fixé à 1 286 le nombre de baleines susceptibles d'être harponnées dans ses eaux entre le 1er avril et le 30 septembre.
§ Comment s'est terminée la série « How I Met Your Mother » ?
Il est fortement recommandé d’être à jour pour lire cette note. Mais vous pouvez juste avoir envie de savoir la fin.
§ A Matignon, Valls veut « aller encore plus loin » et « plus vite »
Le désormais ex-premier ministre a mis en garde son successeur : « La tâche est immense. Ce que nous avons à faire est difficile et n'est pas terminé. »
§ Le frère de Mohamed Merah reste en détention
La cour d'appel de Paris a confirmé le maintien en détention d'Abdelkader Merah, mis en examen pour « complicité d'assassinat » dans l'enquête sur les crimes commis par son frère Mohamed Merah.
§ La grève à Saint-Lazare reconduite jusqu'à mercredi
La grève a commencé dimanche à l'appel du syndicat SUD-Rail qui conteste le projet de réorganisation des personnels d'aiguillage.
§ SNCM : l'actionnaire principal en négociation avec un groupe norvégien
Les syndicats ont dit avoir suspendu leur grève après avoir obtenu des garanties de l'actionnaire principal, Transdev, sur l'avenir de leur compagnie.
§ En direct : la passation de pouvoir à Matignon
La passation de pouvoir entre Jean-Marc Ayrault et Manuel Valls a lieu actuellement à Matignon.
§ Syrie : un bilan de « 150 000 morts » depuis trois ans
L'Observatoire syrien des droits de l'homme annonce, mardi, que le nombre des victimes de la guerre en Syrie a dépassé les 150 000 morts depuis son déclenchement en mars 2011.
§ Procès Heaulme : l'ancien suspect Henri Leclaire ne se « rappelle de rien »
L'audition de ce témoin, ex-suspect du double meurtre de Montigny-lès-Metz, mis en cause par de nouveaux témoignages, est susceptible de faire basculer l'audience.
§ Sous tutelle, la fédération PS du Pas-de-Calais se rebelle
« C'est un acte de défiance ou de défi. On reprend notre autonomie, notre souveraineté sans demander la permission » à Solférino, a déclaré un dirigeant de la deuxième fédération socialiste de France.
§ Quand Manuel Valls se déclarait pour la GPA
Lors de la campagne des primaires socialistes, Manuel Valls prenait le contre-pied de son parti en défendant la gestation pour autrui.
§ Le Maroc renforce son dispositif sanitaire face au virus Ebola en Guinée
Le Maroc a annoncé mardi avoir renforcé son dispositif de contrôle sanitaire aux frontières, en particulier à l'aéroport de Casablanca, l'un des principaux hubs d'Afrique, en raison de l'importante épidémie de fièvre Ebola en Guinée.
§ Manuel Valls en cinq phrases choc
Du changement de nom du PS aux Roms en passant par les 35 heures, le nouveau premier ministre est un habitué des déclarations polémiques.
§ Un clan de yakuzas lance son site Internet
Etre yakuza ne fait plus envie. Alors que les effectifs sont en baisse régulière, un clan mise sur Internet pour redorer son image.

 

Voici un exemple du fichier de sortie d'XML (une partie dans fichier "SORTIE-extract-txt-ALAUNE.txt")

 

01 <?xml version="1.0" encoding="utf-8" ?>
02 <PARCOURS>
03 <NOM>Chunxiao YAN 2015</NOM>
04 <file>
05 <name>2014/Apr/01/19-00-00/0,2-3234,1-0,0.xml</name>
06 <date>Tue, 01 Apr 2014 16:33:45 GMT</date>
07 <items>
08 <item num="1"><title>Marks & Spencer continue son expansion à Paris</title><abstract>Marks & Spencer va ouvrir d'ici l'été cinq nouveaux magasins dans la capitale.</abstract></item>
09 <item num="2"><title>Les prix de l’électricité vont fortement grimper en 2014</title><abstract>Le Conseil d’Etat devrait exiger de l’exécutif que les tarifs régulés couvrent les coûts d’EDF.</abstract></item>
10 <item num="3"><title>Avec la crise, les porte-conteneurs se font refaire le nez</title><abstract>Pour utiliser moins de carburant, CMA-CGM et ses rivaux rabotent le bulbe de leurs navires.</abstract></item>
11 <item><title>-</title><abstract>-</abstract></item>
12 <item num="4"><title>Les ventes de voitures neuves en hausse en mars, le marché reste en crise</title><abstract>Les groupes français PSA et Renault tirent leur épingle du jeu, selon les chiffres des immatriculations publiés mardi.</abstract></item>
13 <item num="5"><title>Bouygues Telecom prolonge la durée de son offre pour SFR jusqu'au 25 avril</title><abstract>L'opérateur a informé Vivendi de cette extension qui vise à « procéder de façon sereine et approfondie à l'examen (…) que requiert une opération aussi importante ».</abstract></item>
14 <item num="6"><title>Ce qui change au 1er avril pour les familles</title><abstract>Hausse du minimum vieillesse, revalorisation du complément familial, baisse de l'allocation de base pour les parents de jeunes enfants aux revenus élevés, entrent en vigueur.</abstract></item>
15 <item num="7"><title>General Motors rappelle 1,5 million de véhicules supplémentaires</title><abstract>Ce nouveau rappel, trois jours après un autre de 1,6 million de véhicules,  concerne principalement les Etats-Unis mais également le Canada et le Mexique.</abstract></item>
16 <item num="8"><title>Yahoo! en négociations pour un rachat dans la vidéo en ligne</title><abstract>Comme l'avait montré l'achat avorté de Dailymotion l'an dernier, le groupe internet américain souhaite mettre l'accent sur la vidéo pour relancer sa croissance.</abstract></item>
17 <item num="9"><title>Le salaire symbolique de Mark Zuckerberg, patron de Facebook</title><abstract>Le salaire de base d'un dollar de la 21e fortune mondiale est notamment complété par 653 164 dollars de rémunérations en nature.</abstract></item>
18 <item num="10"><title>« Non, Libé n’est pas sauvé ! »</title><abstract>Les représentants des salariés du journal restent très dubitatifs après les annonces de l'actionnaire Bruno Ledoux.</abstract></item>
19 <item><title>-</title><abstract>-</abstract></item>
20 <item num="11"><title>Immobilier : petits tracas et grosses galères de propriétaires</title><abstract>A la suite d’un appel à témoignage, une centaine de propriétaires nous ont raconté leur tracasseries quotidiennes. Nous publions ici les anecdotes les plus représentatives avec, à chaque fois, les conseils des juristes de l’Union nationale de la propriété immobilière (UNPI).</abstract></item>
21 <item num="12"><title>Rembourser un crédit de façon anticipée : ce qu'il faut savoir</title><abstract>Lorsqu'ils négocient leur crédit immobilier, très peu d'emprunteurs s'intéressent aux conditions de remboursement anticipé. Dommage, car cela leur permettrait de réaliser des économies, très peu d'emprunts allant jusqu'à leur terme.</abstract></item>
22 <item num="13"><title>La Redoute : 18 délégués CFDT quittent le syndicat</title><abstract>Les démissionnaires reprochent au syndicat d'avoir paraphé l'accord de la direction sur le plan social sans passer par un référendum.</abstract></item>
23 <item num="14"><title>La Poste doublement condamnée</title><abstract></abstract></item>
24 <item><title>-</title><abstract>-</abstract></item>
25 <item num="15"><title>Comment utilisez-vous les titres-restaurants ?</title><abstract>La possiblité d'avoir un titre-restaurant numérique, dont la mise en place entre en vigueur le 2 avril, vous paraît-elle intéressante ? Regretterez-vous de ne plus pouvoir donner les titres dont vous ne vous servez pas ?</abstract></item>
26 </items>
27 </file>
Exemple du fichier XML complet

 

 

 

 

 

Chunxiao YAN        Plurital © 2015