Description

La Boîte à Outils 1 consiste en l'extraction de données pertinentes à partir des fichiers XML contenant les flux RSS provenant du journal Le Monde. Ces flux RSS sont générés quotidiennement et concentrent les articles qui ont été publiés le jour-même, organisés par rubrique.

L'outil développé est un programme Perl qui vise à récupérer le titre et la description de chaque flux RSS dans deux types de fichiers différents : texte brut et XML. Pour cela, il a recours à une fonction qui parcourt l'arborescence du dossier « 2016 », dossier qui se compose des fils RSS ordonnés par mois, puis par jour. Cette fonction est résursive à partir du moment où elle ne rencontre pas un fichier XML exploitable. Le script utilise des expressions régulières pour repérer les fameux titre et description. Puisque l'on peut avoir des doublons avec les fils RSS, il s'assure également de traiter chaque article une seule fois, sans répétition. Les données sont ensuite nettoyées et envoyées dans les fichiers qui correspondent à leur rubrique. En effet, le script produit en sortie des documents TXT/XML pour chaque rubrique, soit seize au total. Avoir les données séparées de cette manière est important, particulièrement pour la BàO 3. L'inclure dans le code à cette étape du traitement simplifie la tâche pour plus tard. Sinon, contrairement aux années précédentes, les fils RSS de 2016 sont tous encodés en UTF-8, il n'y a donc pas de précautions particulières à prendre de ce côté-là.

Script

Le script prend en argument le nom du dossier contenant les fils RSS.

#!/usr/bin/perl

use strict;
use warnings;

use HTML::Entities;
use Text::Unaccent;

my $guide = "Couldn't run the program: perl $0 directory";
die $guide unless @ARGV == 1;

my $directory = "$ARGV[0]";
$directory =~ s/[\/]$//;

my %ITEM_LIST = ();  # Inventaire des articles
my %TOPIC_LIST = (); # Inventaire des rubriques

# Parcours de l'arborescense des fichiers
&browse_local_folders($directory);

my @TOPICS = keys(%TOPIC_LIST);

# Fermeture des balises dans les fichiers XML de sortie
foreach my $topic (@TOPICS) {
    my $file_xml = "SORTIE_".$topic.".xml";
    open(my $OUT_XML, ">>:encoding(UTF-8)", $file_xml) or die "Couldn't open $file_xml: $!";
    print $OUT_XML "</FILTRAGE>\n";
    print $OUT_XML "</PARCOURS>";
    close($OUT_XML);
}

exit;

# -----------------------------------------------------------------

sub browse_local_folders {
    my $path = shift(@_);
    opendir(my $DIR, $path) or die "Couldn't open $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) {
            print "PARCOURS DE L'ARBORESCENCE [$file]\n";
            &browse_local_folders($file);
        }
        # Si $file est un fichier, celui-ci est alors traité
        if(-f $file) {
            if($file =~ /,0\.xml$/) {
                print "EN COURS DE TRAITEMENT : $file\n";

                open(my $INPUT, "<:encoding(UTF-8)", $file) or die "Couldn't open $file: $!\n";
                my $text = "";
                while(my $line = <$INPUT>) {
                    chomp $line;
                    $line =~ s/\r//g;
                    $text .= $line;
                }
                $text =~ s/> +</></g;

                # Extraction du nom de la rubrique
                my $topic_name = "";
                if($text =~ /<channel>.+?<title>([^<]+)<\/title>/) {
                    $topic_name = $1;
                }
                my $i = index($topic_name, ":");
                if($i == -1) {
                    $topic_name = "Actualité à la Une";
                } else {
                    $topic_name = substr($topic_name, 0, $i-1);
                }
                $topic_name = lc($topic_name);
                $topic_name =~ s/ /-/g;
                my $topic = unac_string("UTF-8", $topic_name);

                my $file_xml = "SORTIE_".$topic.".xml";
                my $file_txt = "SORTIE_".$topic.".txt";

                # Création des fichiers de sortie pour chaque rubrique s'ils n'existent pas déjà
                if(!(exists $TOPIC_LIST{$topic})) {
                    open(my $OUT_XML, ">:encoding(UTF-8)", $file_xml) or die "Couldn't open $file_xml: $!";
                    print $OUT_XML "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
                    print $OUT_XML "<PARCOURS>\n";
                    print $OUT_XML "<NOM>De Sousa</NOM>\n";
                    print $OUT_XML "<FILTRAGE>\n";
                    close($OUT_XML);

                    open(my $OUT_TXT, ">:encoding(UTF-8)", $file_txt) or die "Couldn't open $file_txt: $!";
                    close($OUT_TXT);

                    $TOPIC_LIST{$topic} = 1;
                }

                # Récupération du contenu des articles
                while($text =~ /<item>.+?<title>(.+?)<\/title>.+?<description>(.+?)<\/description>/g) {
                    my $title = $1;
                    decode_entities($title);
                    my $description = $2;
                    $description =~ s/&lt;.+&gt;//g;
                    $description =~ s/<[^>]+>//g;
                    decode_entities($description);

                    # Ajout et impression des articles s'ils n'ont pas déjà été enregistrés
                    if(!(exists $ITEM_LIST{$title}) && ($description ne "")) {
                        open(my $OUT_XML, ">>:encoding(UTF-8)", $file_xml) or die "Couldn't open $file_xml: $!";
                        print $OUT_XML "<item>\n<title>$title</title>\n<description>$description</description>\n</item>\n";
                        close($OUT_XML);

                        open(my $OUT_TXT, ">>:encoding(UTF-8)", $file_txt) or die "Couldn't open $file_txt: $!";
                        print $OUT_TXT "Titre : $title\nDescription : $description\n";
                        close($OUT_TXT);

                        $ITEM_LIST{$title} = 1;
                    }
                }

                close($INPUT);
            }
        }
    }
}