Boîte à Outils 3

Script final

En adaptant le script de Serge Fleury et en l'intégrant au script de la BàO2, il m'est dorénavant possible de procéder en une seule commande à la collecte des flux RSS dans un dossier donné, l'extraction dans un fichier texte et un fichier XML du titre et de la description de chaque article par catégorie, l'étiquetage morpho-syntaxique en utilisant TreeTagger et enfin d'extraire des patrons morpho-syntaxiques prédéfinis.

#!/usr/bin/perl
# Importation des bibliothèques
use XML::RSS;
use utf8;
use HTML::Entities;
# Initialisation des variables
#my $rss = XML::RSS->new(ErrorContext=>2);
#print $rss;
my $rep = "$ARGV[0]";
$rep =~ s/[\/]$//;				# On s'assure que le nom du répertoire ne se termine pas par un "/"
my %tableCategories = ();		# Tableau - Rubriques
my @tableArticles = ();			# Table de hachage - Articles
my $i = 1;						# Compteur d'articles lus pour debug
my $nom = "Anaïs Chanclu";				
# Fonction de parcours d'arborescence de fichiers
sub scanFiles {
	my $path = shift(@_);
	opendir(dir, $path) or die "Je n'arrive pas à ouvrir $path : $!\n";
	my @files = readdir(dir);
	closedir(dir);
	foreach my $file (@files) {
		next if $file =~ /^\.\.?$/;
		$file = $path . "/" .$file;
		# Si file est un répertoire, la fonction est alors récursive
		if (-d $file) {
			&scanFiles($file);		# Récursion
		}	
		# Si file est un fichier, on traite le fichier
		if (-f $file) {
			if ($file =~ /\.xml$/) {
				# Vérification de la validité du fichier d'entrée
				my $rss = new XML::RSS;
				eval {	$rss -> parsefile($file); };
				open(cr,">>:encoding(utf8)", "script5.cr");
				print cr "\nTraitement de '$file':\n$@\n";
				close(cr) and next if $@;
				# Le fichier est bel et bien un fichier RSS, on poursuit !
					# On recupère l'encodage
					open(fileItem, $file);
					my $encoding = $rss -> {'encoding'};
					close(fileItem);					
					# On recupère le titre du flux selon l'encodage pour avoir la catégorie
					open(fileItem, "<:encoding($encoding)", $file);
					my $category = $rss -> {'channel'} -> {'title'};
					# On nettoie la catégorie
					$category = lc($category);
					$category =~ s/le monde.fr : //g;
					$category =~ s/toute l'actualité sur le monde.fr//g;
					$category =~ s/\s//g;
					$category =~ s/[,.;:!]//g;
					$category =~ s/[éêëè]/e/g;
					$category =~ s/[âäà]/a/g;
					$category =~ s/[îï]/i/g;
					$category =~ s/[ôö]/o/g;
					$category =~ s/[ûüù]/u/g;
					$category =~ s/[ÿ]/y/g;
					# Si la catégorie n'est pas exploitable, on reprend au début de la boucle
					open(cr,">>:encoding(utf8)", "script5.cr");
					print cr "\nCatégorie ".uc($category)." à traiter...\n";
					close(cr) and next if($category eq "") ;
					# On initialise les noms des fichiers de sortie
					my $outputXml = "sortie-" . $category . ".xml";
					my $outputTxt = "sortie-" . $category . ".txt";	
					my $outputTitle = "title-" . $category . ".tmp" ;
					my $outputDesc = "desc-" . $category . ".tmp" ;		
					my $outCategory = "tag-" . $category . ".xml" ;
					# On verifie que la catégorie n'existe pas
					if (!(existCategory($category,@tableCategories))) {
						# si c'est le cas on l'ajoute
						push(@tableCategories,$category);
						# On crée un fichier XML vide
						open(fileOutXml, ">:encoding(utf-8)", $outputXml) or die "Je n'ai pas réussi à ouvrir le fichier $outputXml !";				
						print fileOutXml "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n";
						print fileOutXml "<PARCOURS>\n";
						close(fileOutXml);							
						# On crée un fichier texte vide
						open(fileOutTxt, ">:encoding(utf-8)", $outputTxt) or die "Je n'ai pas réussi à ouvrir le fichier $outputTxt !";
						close(fileOutTxt);				
						# Un fichier tagger XML de tous les articles de la catégorie avec titre et description
						open(Sortie, ">:encoding(utf-8)" ,$outCategory) or die "Je n'ai pas réussi à ouvrir le fichier $outCategory !";
						print Sortie "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n";
						print Sortie "<PARCOURS>\n\t<NOM>$nom</NOM>\n\t<FILTRAGE>\n";
						close(Sortie) ;
					}
					# On récupère le contenu désiré des articles
					foreach my $item (@{$rss -> {'items'}}) {
						my $tmpTitle = $item -> {'title'};
						my $tmpDesc = $item -> {'description'};											
						# On ne garde que le nécessaire
						$tmpDesc =~ s/<p.*?\/>//;
						$tmpDesc =~ s/<a href[^>]+>//g;
						$tmpDesc =~ s/<img[^>]+>//g;
						$tmpDesc =~ s/<\/a>//g;
						$tmpDesc =~ s/<[^>]+>//g;
						$tmpDesc =~ s/ - Lisez l'intégralité de l'article pour plus d'information./"/g;
						# On nettoie le titre et la description
						$cleanTitle = decode_entities($tmpTitle);
						$cleanDesc = decode_entities($tmpDesc);
						# Fichier de compte-rendu
						open(cr,">>:encoding(utf8)", "script5.cr");
						print cr "$i - $category - $cleanTitle \n";
						close(cr);
						# On verifie que l'article n'existe pas déjà
						if ($tableArticles{$cleanTitle} ne $cleanDesc) {
							# S'il n'existe pas, on l'ajoute
							$tableArticles{$cleanTitle} .= $cleanDesc;			
							# On ajoute le titre et la description dans le fichier XML...
							open(fileOutXml, ">>:encoding(utf-8)", $outputXml) or die "Je n'ai pas réussi à ouvrir le fichier $outputXml !";
							print fileOutXml "<item>\n\t<titre>$cleanTitle</titre>\n\t<description>$cleanDesc</description>\n</item>\n";
							close(fileOutXml);
							# On prépare l'étiquetage du titre et on initialise outCategory
							open(tmpFile, ">:encoding(utf-8)", "tmpTitle.txt");
							print tmpFile $cleanTitle;
							close(tmpFile);
							open(Sortie, ">>:encoding(utf-8)", $outCategory) or die "Je n'ai pas réussi à ouvrir le fichier $outCategory !";
							print Sortie "\t\t<item num=\"$i\">\n";
							print Sortie "\t\t\t<article>\n"; 
							close(Sortie) ;
							# On prépare l'étiquetage de la description
							open(tmpFile, ">:encoding(utf-8)", "tmpDesc.txt");
							print tmpFile $cleanDesc;
							close(tmpFile);		
							print $i. " - ".$category." - ".$cleanTitle ."\n";							
							# Étiquetage du titre 
							open(Sortie, ">>:encoding(utf-8)", $outCategory) or die "Je n'ai pas réussi à ouvrir le fichier $outCategory !";
							print Sortie "\t\t\t\t<titre>\n" ;	
							close(Sortie) ;
							system("perl ~/treetagger/tokenise-fr.pl tmpTitle.txt | ~/treetagger/bin/tree-tagger -lemma -token -no-unknown ~/treetagger/lib/french-utf8.par > $outputTitle");
							system("perl ./tt2xml-art.pl $outputTitle") ;
							my $res = $outputTitle . ".xml" ;
							system("cat $res >> $outCategory") ;
							open(Sortie, ">>:encoding(utf-8)", $outCategory) or die "Je n'ai pas réussi à ouvrir le fichier $outCategory !";
							print Sortie "\t\t\t\t</titre>\n" ;
							close(Sortie) ;	
							# Étiquetage de la description
							open(Sortie, ">>:encoding(utf-8)", $outCategory) or die "Je n'ai pas réussi à ouvrir le fichier $outCategory !";
							print Sortie "\t\t\t\t<description>\n" ;	
							close(Sortie) ;
							system("perl ~/treetagger/tokenise-fr.pl tmpDesc.txt | ~/treetagger/bin/tree-tagger -lemma -token -no-unknown ~/treetagger/lib/french-utf8.par > $outputDesc");
							system("perl ./tt2xml-art.pl $outputDesc") ;
							my $res = $outputDesc . ".xml" ;							
							system("cat $res >> $outCategory") ;
							open(Sortie, ">>:encoding(utf-8)", $outCategory) or die "Je n'ai pas réussi à ouvrir le fichier $outCategory !";
							print Sortie "\t\t\t\t</description>\n" ;	
							close(Sortie) ;															
							# Nettoyage et fermeture des balises article et item
							open(Sortie, ">>:encoding(utf-8)", $outCategory) or die "Je n'ai pas réussi à ouvrir le fichier $outCategory !";
							print Sortie "\t\t\t</article>\n";
							print Sortie "\t\t</item>\n";
							close(Sortie) ;	
							system("rm tmpDesc.txt tmpTitle.txt *.tmp *.tmp.xml");		
							# ...ainsi que dans le fichier TXT
							open(fileOutTxt, ">>:encoding(utf-8)", $outputTxt) or die "Je n'ai pas réussi à ouvrir le fichier $outputTxt !";						
							print fileOutTxt "§ " . $cleanTitle . "\n" . $cleanDesc ."\n\n";
							close(fileOutTxt);
						}		
						$i++;	# compteur d'articles
					}
					close(fileItem);
			}
		}
	}
}
# Fonction de recherche de categorie dans le tableau
sub existCategory {
	my ($cat,@tab) = @_;
	$res=0 ;
	foreach my $c (@tab) {
		if ($c eq $cat) {
			$res=1;
			last;
		}
	}
	return $res;
}
# Fichier de compte-rendu
open(cr,">:encoding(utf8)", "script5.cr");
print cr "Compte-rendu de traitement de script5.pl\n";
close(cr);
# On parcourt les fichiers
&scanFiles($rep);
# Fin de traitement
foreach my $category (@tableCategories) {
	# Fermetures des balises des fichiers de sortie par catégorie
	my $outputXml = "sortie-" . $category . ".xml";
	if (!open (fileOutXml,">>:encoding(utf-8)", $outputXml)) { die "Problème à l'ouverture du fichier $outputXml."};
	print fileOutXml "</PARCOURS>\n";
	close(fileOutXml);
	# Fermetures des balises des fichiers de sortie par catégorie filtrée
	my $outCategory = "tag-".$category .".xml";	
	if (!open (Sortie,">>:encoding(utf-8)", $outCategory)) { die "Problème à l'ouverture du fichier $outCategory."};
	print Sortie "\t</FILTRAGE>\n</PARCOURS>\n" ;
	close(Sortie) ;
	# Extraction de patrons morpho-syntaxiques
	my @patrons=("NOM ADJ", "NOM PRP NOM", "ADJ NOM");
	foreach my $patron (@patrons) {
		$patron =~ s/\s/_/g;
		my $outPatron = $category."-".$patron.".txt";
		system("perl script2-patron.pl $outCategory $patron > $outPatron");
	}
}
exit;