Filtrage de texte

Dans cette partie nous automatisons le parcours de l'arborescence de fils RSS dans le but d'en extraire les zones textuelles qui nous intéressent et de le structurer sous la forme d'un document XML qui constituera notre corpus de travail.


Le script de filtrage

Le texte censé constituer notre corpus est inclus dans les balises <title> et <description> des fils RSS (pour visualiser la structure d'un fil RSS, cliquez ici: unFilRss.xml). La première contient en effet le titre de chaque article, et la deuxième un bref résumé de celui-ci.

Nous écrivons un petit script Perl en nous nous inspirant de celui fourni par les enseignants: filtreur.pl. Le script modifié (MY_filtreur.pl) prend en argument le fichier à lire et le nom du fichier XML à produire en sortie.

#!/usr/bin/perl
open(FICH_IN, "$ARGV[0]");
open(FICH_OUT, ">$ARGV[1]");

Une fois ouverts les flots d'entrée et de sortie, le fichier est parcouru ligne par ligne. A chaque tour de boucle on vérifie si la variable scalaire $ligne, où la ligne courante est stockée, contient une des deux balises. Si c'est le cas, la ligne est imprimée dans le flot de sortie:

while ($ligne=)
{
  if ($ligne =~ /\<title\>(.*)\<\/title\>/)
	{print FICH_OUT "$ligne";}
  if ($ligne =~ /\<description\>(.*)\<\/description\>/)
	{print FICH_OUT "$ligne";}
}

Pour conclure le petit script, ne pas oublier de fermer les deux flots:

close(FICH_IN);
close(FICH_OUT);

Parcours d'arborescence

L'opération de filtrage doit maintenant être appliquée au contenu de toute une arborescence. Le fils RSS sont en effet divisés par jour d'émission, et les dossiers les contenant sont eux mêmes regroupés par mois et année.

Pour que le parcours de l'arborescence soit complet, quel que soit le niveau de profondeur des différents répertoires, il faut que la procédure soit recursive. C'est-à-dire, qu'à chaque fois que l'on rencontre un nouveau dossier, la routine de parcours d'arboresence s'appelle elle-même. La récursivité s'arrête lorsque, dans un répertoire, il n'y a que de fichiers.

Pour savoir si un objet contenu dans un répertoire est un fichier ou un dossier, on utilise les tests de fichier:

Il ne reste qu'à vérifier que le fichier est en format XML (notre arborescence contient en effet une version texte simple de chaque fil RSS):
($file =~/\.xml$/)

A chaque fichier XML on applique donc le filtrage codé ci-dessus. Ce qui était un petit programme indépendant devient une procédure appelée par le programme principal.

En Perl, les définitions de sous-programme sont précedées par sub, alors que leurs appels sont précedés par & :

sub parcoursarborescencefichiers {
    my $path = shift(@_);	#on récupère le premier paramètre 
				contenu dans la variable implicite @_
    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);	#recurse!
	}
	if ((-f $file) && ($file =~/\.xml$/)) {
#       TRAITEMENT à réaliser sur chaque fichier:
	&filtreur($file);
	print $i++,"\n";
	}
    }
}
#----------------------------------------------

sub filtreur {
	my $fichier = shift(@_);
	open(FICH_IN, "$fichier");
		while ($ligne=)  {
			if ($ligne =~ /(\[^<]+\<\/title\>)/)
				{$DUMPFULL1.="$1\n";}
			if ($ligne =~ /(\[^<]+\<\/description\>)/)
				{$DUMPFULL1.="$1\n";}
		}
		close(FICH_IN);
}

Structuration XML

Les textes ainsi extraits ne sont pas directement imprimés. Tout le long du parcours d'arborescence, ils sont concatenés et stockés dans une seule variable scalaire nommée $DUMPFULL.

L'ensemble de textes doit en effet être structuré en format XML, de façon à permettre les traitements suivants. Une fois le parcours d'arborescence terminé, l'entête de fichier XML ainsi que les différentes balises sont imprimées dans le flot de sortie et le contenu de la variable $DUMPFULL est imprimé dans l'élément FILTRAGE:

print FILEOUT "<?xml version=\"1.0\" encoding=\"iso-8859-1\" ?>\n";
print FILEOUT "<PARCOURS>\n";
print FILEOUT "<NOM>Arianna</NOM>\n";
print FILEOUT "<FILTRAGE>".$DUMPFULL1."</FILTRAGE>\n";
print FILEOUT "</PARCOURS>\n";
close(FILEOUT);
exit;

Pour accéder au script de parcours d'arborescence, cliquez ici: AB_parcours.pl.

Le script de nettoyage

Nous avons un petit mais ennuyeux problème d'encodage de caractères. A travers un script Perl très simple (MY_nettoyeur.pl) les caractères qui s'affichent mal sont remplacés par leur équivalents bien codés.

Voici le noyau du script:

while ($ligne=)
{
	$ligne =~ s/& #38;#39;/\'/g;
	$ligne =~ s/& #233;/é/g;
	$ligne =~ s/& #234;/ê/g;
	$ligne =~ s/& #38;#34;/\"/g;
}

Ce script peut être exécuté en ligne de commande sur la sortie du filtreur, ou bien constituer un sous-programme appelé par le programme principal de parcours d'arborescence et étiquetage.


Le fichier construit (SORTIE-AB_parcours.xml) ressemble à ceci:

<?xml version="1.0" encoding="iso-8859-1" ?>
<PARCOURS>
<NOM>Arianna</NOM>
<FILTRAGE><title>Le Monde.fr : A la Une</title>
<description>Toute l'actualité au moment de la connexion</description>
<title>Démonstration de force des prosyriens à Beyrouth</title>
<description>Toutes les composantes de l'opposition prosyrienne ont appelé à 
manifester dans le centre de Beyrouth pour réclamer la démission du premier
ministre, Fouad Siniora.</description> <title>Le match PSG-Toulouse est à "très haut risque" selon les RG</title> <description>Après la décision de fermeture du kop rouge de Boulogne, la
préfecture craint un blocage des accès au Parc des Princes par les supporteurs
ultras.</description> <title>La galaxie écologiste, interrogations et tractations</title> <description>L'écologie est au centre de la campagne présidentielle.
L'irruption de Nicolas Hulot dans ce paysage met en lumière l'éclatement de la
galaxie écologiste.</description> <title>Grande-Bretagne : polémique sur les conditions de détention d'immigrés
illégaux</title> <description>Des incidents ont éclaté dans le centre d'Harmondsworth près de
Londres.</description> <title>La direction du "Parisien" veut améliorer la productivité et lancer de
nouveaux produits</title>

Aller à l'étape suivante