Table des matières
Chargement d'un flux RSS
Cet exercice reprend des méthodes vues dans ce TD.
Objectif : Afficher les titres d'un flux RSS.
RSS, qu'est ce que c'est ?
Le RSS (Really Simple Syndication) est un format de fichier dont le contenu est produit automatiquement pour tenir compte des mises à jours sur un site web (par exemple)
Syndication ou souscription : système qui consiste à vendre / fournir à plusieurs diffuseurs le droit de reproduire un contenu ou de diffuser un programme. Le diffuseur de contenu est appelé syndicate.
Imaginons une situation :
- A est un site produisant des podcasts (par exemple
www.franceculture.fr). De nouveaux podcasts sont produits régulièrement. - B est une application sur téléphone qui permet de s'abonner à divers podcasts.
A souhaite que ces podcasts soient écoutés et B souhaite que ses utilisateurs puissent voir facilement tous les podcasts disponibles. Il est donc essentiel que A publie une liste à jour de ses podcasts pour que B puisse y accéder.
Cette liste est un fichier RSS. Le fichier RSS est presque toujours produit automatiquement par l'environnement qui permet à A d'entretenir son site : à chaque nouveau podcast déposé sur le site, une nouvelle entrée dans le fichier RSS est automatiquement créée.
Comme ce fichier RSS se remplit et se vide tout seul à mesure que les nouveaux podcasts sont créés puis deviennent périmés, on parle de flux. C'est donc un flux RSS.
Bien sûr, j'ai parlé de podcasts, mais tout ce qui a été dit est valable pour n'importe quel type de contenu : des vidéos, des images, des articles, des news, des tweets, l'état du réseau RATP…
Format du flux RSS
Prenons l'exemple du flux RSS des articles de France Info : https://www.francetvinfo.fr/titres.rss
Le fichier obtenu est au format *.xml. C'est un simple fichier texte qui ressemble à :
<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>Franceinfo - Les Titres</title>
<description>Franceinfo - Les Titres</description>
<pubDate>Tue, 08 Jun 2021 19:03:00 +0200</pubDate>
<generator>francetvinfo 2021 (https://www.francetvinfo.fr)</generator>
<link>https://www.francetvinfo.fr/titres/</link>
<atom:link rel="self" type="application/rss+xml" href="https://www.francetvinfo.fr/titres.rss"/>
<item>
<title>Emmanuel Macron giflé : cinq questions sur l'agression subie par le président de la République</title>
<description><![CDATA[Le chef de l'Etat a reçu une gifle lors d'un déplacement à Tain-l'Hermitage (Drôme), mardi. "Rien ne change sur les prochains déplacements", assure l'Elysée.]]></description>
<pubDate>Tue, 08 Jun 2021 18:44:39 +0200</pubDate>
<link>https://www.francetvinfo.fr/politique/emmanuel-macron/emmanuel-macron-gifle-lors-d-un-deplacement-dans-la-drome/emmanuel-macron-gifle-cinq-questions-sur-l-agression-subie-par-le-president-de-la-republique_4655901.html#xtor=RSS-3-[lestitres]</link>
<guid>https://www.francetvinfo.fr/politique/emmanuel-macron/emmanuel-macron-gifle-lors-d-un-deplacement-dans-la-drome/emmanuel-macron-gifle-cinq-questions-sur-l-agression-subie-par-le-president-de-la-republique_4655901.html#xtor=RSS-3-[lestitres]</guid>
<enclosure type="image/jpeg" length="21675" url="https://www.francetvinfo.fr/image/75wmi7lt0-0257/500/281/24758405.jpg"/>
</item>
<item>
<title>"Intolérable", "inadmissible"... A gauche comme à droite, les responsables politiques condamnent unanimement l'agression d'Emmanuel Macron</title>
<description><![CDATA[Le chef de l'Etat a été giflé mardi par un individu lors de son déplacement dans la Drôme, à la rencontre des restaurateurs.]]></description>
<pubDate>Tue, 08 Jun 2021 17:51:30 +0200</pubDate>
<link>https://www.francetvinfo.fr/politique/emmanuel-macron/emmanuel-macron-gifle-lors-d-un-deplacement-dans-la-drome/intolerable-inadmissible-a-gauche-comme-a-droite-les-responsables-politiques-condamnent-unanimement-l-agression-d-emmanuel-macron_4655879.html#xtor=RSS-3-[lestitres]</link>
<guid>https://www.francetvinfo.fr/politique/emmanuel-macron/emmanuel-macron-gifle-lors-d-un-deplacement-dans-la-drome/intolerable-inadmissible-a-gauche-comme-a-droite-les-responsables-politiques-condamnent-unanimement-l-agression-d-emmanuel-macron_4655879.html#xtor=RSS-3-[lestitres]</guid>
<enclosure type="image/jpeg" length="29261" url="https://www.francetvinfo.fr/image/75wmi7nvl-0fff/500/281/24758373.jpg"/>
</item>
</channel>
</rss>
Il n'y a que deux articles dans ce flux. Je l'ai abrégé. Le flux original est beaucoup plus long.
Le format XML est lourd et un peu pénible. C'est un format à balises comme HTML. Néanmoins il est très utilisé, c'est bien d'en avoir entendu parler.
Quelques exemples ici dans ce fichier :
- La balise
<rss>s'ouvre ligne 2 et se referme ligne 27. Elle contient l'ensemble du flux. - Dans ce flux il n'y a qu'une seule chaîne (channel), la balise s'ouvre ligne 3 et se ferme ligne 26.
- Cette chaîne est décrite par les balises des lignes 4 à 9 (title, description…)
- Une série (juste 2 dans cet exemple abrégé) de balises
<item>...</item>suivent. Ce sont les articles. Le premier commence ligne 10 et termine ligne 17. - À l'intérieur de chaque article, d'autres balises donnent des informations. Pour le premier article par exemple, lignes 11 à 16, title, description, …
Notez une différence avec HTML : en HTML, les balises <a>, <div>, etc. sont toutes des balises appartenant à la norme HTML. Il n'est pas prévu que l'on rajoute nos propres balises. En XML c'est différent. XML décrit seulement l'organisation des balises mais nous sommes libres de créer des balises avec les noms que l'on veut, du moment que l'on respecte la forme <balise>...</balise> ou éventuellement <balise options />.
XML avec Python
Dans la plupart des langages, on pourra trouver des bibliothèques de fonctions permettant de gérer facilement les fichiers XML.
En python on pourra utiliser xml.dom.minidom :
import xml.dom.minidom as xml
# si le xml est dans un fichier, par ex flux_rss.xml :
xml_doc = xml.parse('flux_rss.xml')
# si le xml est dans une chaîne de caractère, par ex reponseXML
xml_doc = xml.parseString(reponseXML)
Le document est construit sous forme d'un arbre (pensez à un arbre généalogique) : une balise enferme d'autres balises qui sont ses enfants. Une des balise (dans l'exemple la balise <rss> contient l'ensemble. C'est la racine.
root = xml_doc.documentElement # racine
On peut ensuite parcourir les enfants, les enfants des enfants :
# root.getElementByTagName('item') renvoie la liste des noeuds <item> sous root
for article in root.getElementsByTagName('item'):
# article correspond à un des noeuds <item>
titlenode = article.childNodes[0] # premier noeud enfant de article
# dans le flux, l'enfant [0] est toujours un noeud <title>
# donc titlenode est un noeud <title>
textnode = titlenode.childNodes[0]
# titlenode a un unique enfant, c'est un noeud de texte
# textnode est donc le noeud contenant le texte du noeud <item> titlenode
print(textNode.data) # par exemple, on affiche le contenu de textnode, c'est à dire le titre
Implémentation Python
La solution proposée est en 3 parties :
- connexion au flux RSS de France Info (fait)
- analyse du contenu du fichier reçu avec XML (à faire)
- affichage des titres (à faire)
Remarque : La plupart des sites sont aujourd'hui en https, c'est à dire chiffrés. Cela occasionne quelques complications. J'ai commenté autant que possible pour que vous compreniez le principe général. Dans tous les cas, gardez à l'esprit que, en fonction des évolutions des technologies, on est obligé de s'adapter. Par exemple, ici, j'ai découvert la bibliothèque python ssl à l'occasion de cet exercice. On a donc besoin de savoir lire des documentations sur internet pour prendre en main ces outils.
# rss.py
# lecture flux RSS
import socket # pour création socket TCP-IP
import ssl # gestion chiffrement pages https
import urllib.request as req
import xml.dom.minidom as xml
def get_xml(url):
"""
url: adresse du flux rss
renvoie le contenu du fichier xml
"""
context = ssl.SSLContext()
with req.urlopen(url, context=context) as reponse:
return reponse.read().decode('utf8')
def get_titles(texte_xml):
'''
texte_xml : le texte XML dans lequel chercher
retourne l'ensemble des titres (contenus dans <title>...</title>)
sous forme d'une liste.
'''
# à vous !
pass
En ligne 14 j'ai changé l'ancien context = ssl.create_default_context() qui ne fonctionnait plus pour ssl.SSLContext(). Ce n'est pas idéal car ce choix fait qu'on ne vérifie pas le certificat ssl du site. Cela nous évite les erreurs mais est potentiellement dangereux (les certificats sont là pour la sécurité). Toutefois, dans le cadre de ce TP on échange aucune donnée sensible et on ne risque rien.
# main.py from rss import get_xml, get_titles # adresse du flux lui-même url = 'https://www.francetvinfo.fr/titres.rss' xml = get_xml(url) titles = get_titles(xml) # affiche les 3 premiers titres print(titles[:3])
