Parser un flux de syndication avec Python

En faisant des recherches pour l’écriture d’un programme, je suis tombé par hasard sur la documentation de feedparser, qui permet de lire les informations d’un flux RSS (ou Atom) avec Python. Ce n’était pas ce que je cherchais, mais j’ai quand même voulu tester, à titre informatif : il s’avère que c’est extrêmement simple.

Pour récupérer les informations d’un flux, il suffit d’utiliser la fonction parse() de feedparser, comme ceci :

feedparser.parse(url_du_flux)

Cette fonction renvoie un objet de la classe FeedParserDict. Comme son nom le laisse deviner, il s’agit d’une classe d’objet qui parse les données du flux sous forme de dictionnaire. Comme ce dernier peut rapidement devenir (très) volumineux, il est plus pratique de sélectionner les données souhaitées.

Données du flux

Un répertoire est disponible sur Github pour accompagner cet article, comportant un script qui reprend les différentes fonctions expliquées ci-dessous, ainsi que deux exemples de fichiers de sortie (1 et 2).

Certaines données permettent de se faire une vue globale d’un flux, sans entrer dans ses contenus à proprement parler. Ils correspondent à la clé feed ou channel : vous pouvez normalement utiliser l’une ou l’autre indifféremment1. Sachant que par ailleurs le flux parsé avec feedparser.parse() est un objet dont la structure est celle d’un dictionnaire, les syntaxes admises seront assez variées.

Par exemple, si on parse le flux de syndication de ce carnet avec feedparser :

tekipaki = feedparser.parse('https://tekipaki.hypotheses.org/feed')

Et qu’on ajoute ensuite les quatre lignes suivantes :

print(tekipaki['feed']['title'])
print(tekipaki.feed.title)
print(tekipaki['channel']['title'])
print(tekipaki.channel.title)

La console affichera ceci :

Tekipaki
Tekipaki
Tekipaki
Tekipaki

Le titre a bien été récupéré quelle que soit la syntaxe choisie. Les noms des différents éléments disponibles sont assez transparents (et listés dans la documentation), et il est très facile d’écrire une fonction qui affiche les données relatives à un flux. Par exemple, pour afficher le titre, l’URL, la description et la date de la dernière mise à jour :

def print_feed_data(feed):
    print(feed.channel.title)
    print(feed.channel.link)
    print(feed.channel.description)
    print(f"Dernière mise à jour : {feed.channel.updated}")

Appeler cette fonction sur la variable tekipaki2 utilisée précédemment et qui contient le flux de ce carnet (parsé par feedparser) affichera ceci :

Tekipaki
https://tekipaki.hypotheses.org
Carnet d'Alexander Delaporte, ingénieur d'études au Centre de recherches linguistiques sur l'Asie Orientale
Dernière mise à jour : Mon, 31 Aug 2020 09:58:43 +0000

Toutes les informations ne sont pas forcément disponibles, notamment la description. C’est le cas pour La Croisée de la BULAC, qui compile des publications issues de différents carnets de recherche.

veille_bulac = feedparser.parse('https://veillebulac.hypotheses.org/feed')
print_feed_data(veille_bulac)

Renvoie :

La Croisée de la BULAC
https://veillebulac.hypotheses.org

Dernière mise à jour : Tue, 08 Sep 2020 14:28:04 +0000

Ces informations globales peuvent être intéressantes, mais ce ne sont pas les contenus les plus pertinents pour une extraction automatique à partir du flux de syndication.

Données des publications

Le flux RSS permet surtout d’obtenir des données relatives aux dernières publications.

Le nombre de publications disponibles dans le flux est variable. Si vous utilisez un carnet Hypotheses, vous pouvez le paramétrer dans Tableau de bord > Réglages > Lecture > Les flux de syndication affichent les derniers X éléments. La valeur par défaut est 15.

Réglage du nombre de publications dans les flux de syndication d’un carnet Hypotheses

De façon similaire aux informations générales du flux accessibles avec feed.channel (ou feed.feed), on peut obtenir les données relatives aux publications en utilisant feed.entries. Les publications étant multiples, il ne faut pas oublier de créer une boucle3 :

for entry in tekipaki.entries:    
    print(entry.title)
    print(entry.link)

La boucle parcourt ici les 15 publications les plus récentes de ce carnet4 et affiche leur titre et leur URL, du plus récent au plus ancien.

Affichage des 15 dernières publications, extrait.

Pour avoir une idée un peu plus précise du contenu de ces publications sans pour autant récupérer l’intégralité de leur contenu, il peut être intéressant d’extraire leurs tags (ou étiquettes, ou mots clés, selon la terminologie). Ceux-ci se trouvent à l’index tag correspondant à une publication/entrée. Par exemple :

tekipaki.entries[0].tags

La ligne ci-dessus permet d’obtenir les tags de l’article le plus récent (dont l’index est 0) de ce carnet. Mais attention, encore une fois ceci ne revoie pas une simple chaîne de caractères mais une liste de dictionnaires. La chaîne de caractères correspondant au tag à proprement parler est à l’index term de chacun de ces dictionnaires. Il faudra alors le récupérer avec une boucle pour afficher les tags sous forme de chaînes de caractères.

for tag in tekipaki.entries[0].tags:
    print(tag['term'])

Renvoie :

Corpus et ressources
Traitement automatique
Étiquetage morphosyntaxique
Japonais
POS tagging
Python
Sudachi
SudachiDict
SudachiPy

Il s’agit bien des tags correspondant à cet article. Vous pouvez remarquer que la hiérarchie category/tag (catégorie/étiquette), qu’on retrouve notamment dans les publications des carnets Hypotheses, est ignorée (Corpus et ressources et Traitement automatique ne sont en fait pas des étiquettes mais des catégories sur Tekipaki).

Il est bien sûr également possible d’obtenir d’autres informations, telles que l’auteur (clé author) ou la date de publication (clé published ou published_parsed).

Utiliser les données extraites

En combinant l’utilisation de feedparser et csv (comme expliqué ici), on peut très facilement écrire dans un fichier CSV un tableau contenant des informations sur les dernières publications d’un flux.

C’est ce que fait la fonction entries_table() du script mis à disposition sur Github5, qui prend en entrée le chemin d’accès du fichier de sortie et un flux parsé avec feedparser.parse(). On peut ainsi faire de la veille sur un ou plusieurs flux et en conserver une trace dans un fichier. Modifier légèrement cette fonction peut également permettre d’obtenir des contenus plus ciblés : en ajoutant une ou plusieurs conditions, il serait tout à fait possible de filtrer les publications pour ne récupérer que celles qui comporteraient un ou plusieurs tag(s) donné(s), ou qui seraient rédigées par un auteur en particulier (ce qui serait peu utile sur un flux comme celui de Tekipaki, mais beaucoup plus sur le flux d’un site regroupant des contenus d’auteurs multiples, comme La Croisée de la BULAC).

Citer ce billet : “Parser un flux de syndication avec Python”, par Alexander Delaporte. Publié sur Tekipaki le 18/09/2020. Lien : https://tekipaki.hypotheses.org/628.
  1. Ceci est possible parce que l’objet UniversalFeedParser de feedparser sait gérer différents types de flux, et accepte dans la mesure du possible les terminologies correspondantes même lorsque la terminologie ne coïncide pas avec le type de flux traité. []
  2. print_feed_data(tekipaki) []
  3. La classe de feed.entries est list : il s’agit d’une liste de dictionnaires, où chaque dictionnaire correspond à une publication. []
  4. Pour rappel, tekipaki correspond au flux du carnet, parsé par feedparser (tekipaki = feedparser.parse('https://tekipaki.hypotheses.org/feed')). J’ai gardé les paramètres par défaut des flux de syndication, ce qui explique que tekipaki.entries contienne les données de 15 publications. []
  5. Celui-ci a été utilisé sur des flux issus de carnets Hypotheses, selon le contenu du flux à traiter des ajustements peuvent être nécessaires. []

Auteur/autrice : Alexander Delaporte

Ingénieur d'études au Centre de recherches linguistiques sur l'Asie Orientale

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée.

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.

Rechercher dans OpenEdition Search

Vous allez être redirigé vers OpenEdition Search