1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203 | #/usr/bin/perl
<<DOC;
////////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// Nom : Hayoung SEO //
// Date : Avril 2021 //
// But : 1. Parcourir toute l'arborescence et extraire les contenus textuels de tous les fils RSS //
// 2. Etiquetage via treetagger ET udpipe de tous les fichiers RSS //
// Stratégie pour l'étiquetage : global //
// Entrée : 1. répertoire(racine) contenant tous les fichiers RSS //
// 2. rubrique à traiter //
// Sortie : Un fichier au format txt + Un fichier au format XML //
// Usage : perl bao2_hayoung_seo.pl repertoire-a-parcourir rubrique //
// Exemple d'usage : perl bao2_hayoung_seo.pl 2020 3208 //
// //
////////////////////////////////////////////////////////////////////////////////////////////////////////
DOC
#-----------------------------------------------------------
use strict;
use utf8;
use Timer::Simple;
my $t = Timer::Simple->new();
$t->start; # timer pour savoir le temps de traitement
#-----------------------------------------------------------
my $rep="$ARGV[0]"; # repertoire à traiter
my $rubrique ="$ARGV[1]"; # rubrique à traiter
# on s'assure que le nom du répertoire ne se termine pas par un "/"
$rep=~ s/[\/]$//;
# Ouverture des fichiers txt et XML
open my $OUT,">:encoding(utf8)","bao2_sortie_$rubrique.txt";
open my $OUTXML,">:encoding(utf8)","bao2_sortiexml_$rubrique.xml";
# Ecriture de l'en-tête du fichier XML
print $OUTXML "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n";
print $OUTXML "<corpus2020>\n";
my %dico_des_titres=();
my $compteur=0;
#----------------------------------------
# Appel du sous-programme
&parcoursarborescencefichiers($rep); #recurse!
#----------------------------------------
print $OUTXML "</corpus2020>\n";
# Fermeture des fichiers
close $OUT;
close $OUTXML;
#----------------------------------------
# Appel du sous-programme d'etiquetage
&etiquetagetreetagger;
&etiquetageudpipe;
#----------------------------------------
#----------------------------------------
print "Temps de traitement : ", $t->elapsed, " secondes\n";
exit;
#----------------------------------------------
# Sous-programme récursif
sub parcoursarborescencefichiers {
my $path = shift(@_);
opendir(my $DIR, $path) or die "can't open $path: $!\n";
# On lit et renvoie comme valeur la liste @files
my @files = readdir($DIR);
closedir($DIR);
# On va examiner un à un pour éviter de lire les fichiers cachés
foreach my $file (@files) {
# Si la condition est vrai on passe à l'itération suivante, on ne veut pas traiter
next if $file =~ /^\.\.?$/; # on ne lit pas les fichiers cachés (. ou .. ) sinon boucle infini
# S'il ne s'agit pas des fichiers cachés, on continue. On relance le parcours
# Reécriture de localisation => on génère le nom relatif
$file = $path."/".$file;
# d : directory(repertoire)
# S'il s'agit d'un répertoire……
if (-d $file) {
# Ce qu'on cherche n'est pas un répertoire mais un fichier donc on relance le parcours
# pour qu'on puisse arriver aux fichiers
&parcoursarborescencefichiers($file); #recurse!
# Donc on va parcourir de nouveau, $path devient 2020/01 par exemple … puis 2020/01/01…
# Finalement on va arriver à un fichier
}
# f : file(fichier)
# S'il s'agit d'un fichier……
if (-f $file) {
# On ne veut pas traiter les fichiers qui ne sont pas au format XML
# Donc l'extension doit être .xml
if ($file =~/$rubrique.+xml$/) {
# Impression du traitement en cours dans la console
print $compteur++," Traitement de : ",$file,"\n";
# Ouverture du fichier
open my $FIC,"<:encoding(utf8)",$file;
$/=undef;
my $ligne=<$FIC>;
close $FIC;
# On va extraire les contenus textuels de titre et de description avec expression régulère
while ($ligne=~/<item>.*?<title>(.+?)<\/title>.+?<description>(.+?)<\/description>/gs) {
my $titre=$1; # on récupère le 1er zone de capture (1er parenthèse entre <title></title>)
my $description=$2; # on récupère le 2eme zone de capture (2eme parenthèse)
#$numberItem++;
# On évite de récuperer 2 fois la même information => utilisation de dictionnaire
# Si le titre n'existe pas dans le dico_des_titres
if (!(exists $dico_des_titres{$titre})) {
# On ajoute
$dico_des_titres{$titre}=$description ;
# Appel du sous-programme de nettoyage
($titre,$description)=&nettoyage($titre,$description);
#--------------------------------------------------
# Pretraitement pour treetagger
my ($titretokenisee, $descriptiontokenisee)=&pretraitement($titre, $description);
# Ecriture des fichiers de sortie
# 1. Fichier au format txt
print $OUT $titre,"\n";
print $OUT $description,"\n";
print $OUT "\n";
# 2. Fichier au format XML
print $OUTXML "<item>\n";
print $OUTXML "<titre>\n$titretokenisee</titre>\n";
print $OUTXML "<description>\n$descriptiontokenisee</description>\n";
print $OUTXML "</item>\n";
# Si le titre exsite, on ne fait rien
}
}
}
}
}
}
#----------------------------------------------
# Sous-programme nettoyage
sub nettoyage {
# On récupère les arguments
my $titre = $_[0];
my $description = $_[1];
# Nettoyage !
# On enlève <![CDATA[ et ]]>
$titre=~s/^<!\[CDATA\[//;
$titre=~s/\]\]>$//;
$description=~s/^<!\[CDATA\[//;
$description=~s/\]\]>$//;
# On enlève ou on remplace
$description=~s/<.+?>//g; # < est le code de < , > est le code de >
$description=~s/&#39;/'/g;
$description=~s/&#34;/"/g;
$titre=~s/<.+?>//g;
$titre=~s/ / /g;
$description=~s/ / /g;
# On ajoute un point à la fin du titre
# Pour la partie description il y a déjà le point à la fin => rien à faire
$titre=~s/$/\./g;
# S'il y a plusieur points => on ne laisse qu'un seul
$titre=~s/\.+$/\./g;
return $titre,$description;
}
#----------------------------------------------
# Sous-programme tokenisation pour treetagger
# renvoie le titre et le description étiquétés
sub pretraitement {
# argument géré par la liste @_
my $titre=$_[0]; # titre est 1er argument passé
my $description=$_[1]; # description est 2ème argument passé
#-------------------------------------
# Etiquetage - titre
open my $ETIK, ">:encoding(utf8)", "temporaire.txt";
print $ETIK $titre;
close $ETIK;
system("perl -f ./etiquetage/tokenise-utf8.pl temporaire.txt > testetik.txt");
open my $TEMPO, "<:encoding(utf8)", "testetik.txt";
# On fait une lecture globale
$/=undef;
my $titre_etik=<$TEMPO>;
close $TEMPO;
#-------------------------------------
# Etiquetage - description
# On écrase précédent
# Et maintenant on ouvre avec description
open my $ETIK, ">:encoding(utf8)", "temporaire.txt";
print $ETIK $description;
close $ETIK;
# description
system("perl -f ./etiquetage/tokenise-utf8.pl temporaire.txt > testetik.txt");
open my $TEMPO, "<:encoding(utf8)", "testetik.txt";
$/=undef;
my $description_etik=<$TEMPO>;
close $TEMPO;
unlink "testetik.txt", "temporaire.txt";
return $titre_etik, $description_etik;
}
#----------------------------------------------
# Sous-programme etiquetage treetagger
sub etiquetagetreetagger {
# -sgml : ne touche pas aux balises
system("perl -f ./etiquetage/tokenise-utf8.pl bao2_sortiexml_$rubrique.xml | ./etiquetage/treetagger/tree-tagger ./etiquetage/treetagger/french-utf8.par -token -lemma -no-unknown -sgml > bao2_sortiexml_treetagger_$rubrique");
# commande pour traiter & (car treetagger l'annote & NOM ; PUN - deux entrées différents - )
# donc cela posera le pb pour la sortie xml => on ajoute le point virgule à la fin pour chaque &
system("sed -i '' -e 's & \\& g' bao2_sortiexml_treetagger_$rubrique");
system("perl ./etiquetage/treetagger/treetagger2xml-utf8.pl bao2_sortiexml_treetagger_$rubrique utf8");
}
#----------------------------------------------
# Sous-programme etiquetage UDpipe
sub etiquetageudpipe {
# system : commande perl qui permet de lancer une commande Unix
# --tokenizer=parsegmented : on ne veut pas su'il sursegmente
system("./etiquetage/udpipe/udpipe-1.2.0-bin/bin-osx/udpipe --tokenize --tokenizer=parsegmented --tag --parse ./etiquetage/udpipe/modeles/french-gsd-ud-2.5-191206.udpipe bao2_sortie_$rubrique.txt > bao2_sortie_udpipe_$rubrique.txt");
# génération de la sortie au format xml également pour bao3
# system("perl ./etiquetage/udpipe/udpipe2xml.pl bao2_sortie_udpipe_$rubrique.txt")
}
|