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
#/usr/bin/perl
  <<DOC; 
  ////////////////////////////////////////////////////////////////////////////////////////////////////////
  //                                                                                                    //
  //  Nom : Hayoung SEO                                                                                 //
  //  Date : Avril 2021                                                                                 // 
  //  Version XML::RSS                                                                                  //     
  //  But : Parcourir toute l'arborescence et extraire les contenus textuels de tous les fils RSS       //
  //  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 bao1_hayoung_seo.pl repertoire-a-parcourir rubrique                                  // 
  //  Exemple d'usage : perl bao1_hayoung_seo.pl 2020 3208                                              //      
  //                                                                                                    //
  ////////////////////////////////////////////////////////////////////////////////////////////////////////
  DOC
  #-----------------------------------------------------------
  use XML::RSS;
  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)","bao1_sortie_xmlrss_$rubrique.txt";
  open my $OUTXML,">:encoding(utf8)","bao1_sortiexml_xmlrss_$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;
  print "Temps de traitement : ", $t->elapsed, " secondes\n";
  exit;
  #----------------------------------------------
  # Sous-programme 
  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";
                  # On crée un objet et le stock dans un scallaire $rss
                  my $rss=new XML::RSS;
                  # parsefile : fontion prédéfini dans le XML::RSS 
                  eval {$rss->parsefile($file); }; 
                  if ( $@ ){ # s'il y a une erreur 
                      $@=~s/at \/.*?$//s; # remove module line number 
                      print STDERR "\nERROR in '$file':\n$@\n";
                  }
                  # pas d'erreur on avance 
                  else
                  { 
                      foreach my $item(@{$rss->{'items'}})
                      {
                          my $titre=$item->{'title'};
                          my $description=$item->{'description'};
                          # 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 
                          my($titre,$description)=&nettoyage($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>$titre</titre>\n";
                          print $OUTXML "<description>$description</description>\n";
                          print $OUTXML "</item>\n";
                      }
                  }
              }
          }
      }
  }
  #----------------------------------------------
  # 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/&lt;.+?&gt;//g; # &lt; est le code de < ,  &gt; est le code de >
      $description=~s/&#38;#39;/'/g; 
      $description=~s/&#38;#34;/"/g;
      $titre=~s/&lt;.+?&gt;//g;
      $titre=~s/&#38;#39;/'/g;
      $titre=~s/&#38;#34;/"/g;
      $titre=~s/&nbsp;/ /g;
      $description=~s/&nbsp;/ /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;
  }