====== Chargement d'un flux RSS ====== Cet exercice reprend des méthodes vues dans [[nsi:premiere:web:serveur_web_python|ce TD]]. **Objectif : Afficher les titres d'un flux RSS.** ===== RSS, qu'est ce que c'est ? ===== Le [[https://fr.wikipedia.org/wiki/RSS|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 à : Franceinfo - Les Titres Franceinfo - Les Titres Tue, 08 Jun 2021 19:03:00 +0200 francetvinfo 2021 (https://www.francetvinfo.fr) https://www.francetvinfo.fr/titres/ Emmanuel Macron giflé : cinq questions sur l'agression subie par le président de la République Tue, 08 Jun 2021 18:44:39 +0200 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] 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] "Intolérable", "inadmissible"... A gauche comme à droite, les responsables politiques condamnent unanimement l'agression d'Emmanuel Macron Tue, 08 Jun 2021 17:51:30 +0200 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] 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] 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 ''%%%%'' 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 ''%%...%%'' 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 ''%%%%'', ''%%
%%'', 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 ''%%...%%'' ou éventuellement ''%%%%''. ==== 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 [[https://www.fil.univ-lille1.fr/~marvie/python/chapitre4.html#minidom-il-fait-le-maximum|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 ''%%%%'' 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 sous root for article in root.getElementsByTagName('item'): # article correspond à un des noeuds titlenode = article.childNodes[0] # premier noeud enfant de article # dans le flux, l'enfant [0] est toujours un noeud # 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 </code> ===== 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//) <WRAP tip>**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.</WRAP> <code python linenums> # 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>...) 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])