.. _TD2AEcoWebScrapingrst: ===================== 2A.eco - Web-Scraping ===================== .. only:: html **Links:** :download:`notebook `, :downloadlink:`html `, :download:`python `, :downloadlink:`slides `, :githublink:`GitHub|_doc/notebooks/td2a_eco/TD2A_Eco_Web_Scraping.ipynb|*` Sous ce nom se cache une pratique très utile pour toute personne souhaitant travailler sur des informations disponibles en ligne, mais n’existant pas forcément sous la forme d’un tableau *Excel*\ … Bref, il s’agit de récupérer des informations depuis *Internet*. Le `webscraping `__ désigne les techniques d’extraction du contenu des sites internet. Via un programme informatique : nous allons aujourd’hui vous présenter comme créer et exécuter ces robots afin de recupérer rapidement des informations utiles à vos projets actuels ou futurs. .. code:: ipython3 from jyquickhelper import add_notebook_menu add_notebook_menu() .. contents:: :local: Un détour par le Web : comment fonctionne un site ? --------------------------------------------------- Même si nous n’allons pas aujourd’hui faire un cours de web, il vous faut néanmoins certaines bases pour comprendre comment un site internet fonctionne et comment sont structurées les informations sur une page. Un site Web est un ensemble de pages codées en *HTML* qui permet de décrire à la fois le contenu et la forme d’une page *Web*. HTML ~~~~ Les balises ~~~~~~~~~~~ Sur une page web, vous trouverez toujours à coup sûr des éléments comme ````, ````, etc. Il s’agit des codes qui vous permettent de structurer le contenu d’une page *HTML* et qui s’appellent des balises. Citons, par exemple, les balises ``<p>``, ``<h1>``, ``<h2>``, ``<h3>``, ``<strong>`` ou ``<em>``. Le symbole ``< >`` est une balise : il sert à indiquer le début d’une partie. Le symbole ``</ >`` indique la fin de cette partie. La plupart des balises vont par paires, avec une *balise ouvrante* et une *balise fermante* (par exemple ``<p>`` et ``</p>``). Exemple : les balise des tableaux ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. math:: \begin{array}{rr} \hline Balise & \text{Description} \\ \hline < table> & \text{Tableau} \\ < caption>& \text{Titre du tableau} \\ < tr> & \text{Ligne de tableau} \\ < th> & \text{Cellule d'en-tête}\\ < td> & \text{Cellule} \\ < thead> & \text{Section de l'en-tête du tableau} \\ < tbody> & \text{Section du corps du tableau} \\ < tfoot> & \text{Section du pied du tableau} \\ \end{array} Application : un tableau en HTML '''''''''''''''''''''''''''''''' Le code *HTML* du tableau suivant <table> <tr> <th>Prénom</th> <th>Nom</th> <th>Profession</th> </tr> <tr> <td>Mike</td> <td>Stuntman</td> <td>Cascadeur</td> </tr> <tr> <td>Mister</td> <td>Pink</td> <td>Gangster</td> </tr> </table> Donnera dans le navigateur +------------+-----------+----------+ | Prénom | Mike | Mister | +============+===========+==========+ | Nom | Stuntman | Pink | +------------+-----------+----------+ | Profession | Cascadeur | Gangster | +------------+-----------+----------+ Parent et enfant ^^^^^^^^^^^^^^^^ Dans le cadre du langage HTML, les termes de parents (parent) et enfants (child) servent à désigner des élements emboîtés les uns dans les autres. Dans la construction suivante, par exemple : < div> < p> bla,bla < /p> < /div> On dira que l’élément ``<div>`` est le parent de l’élément ``<p>`` tandis que l’élément ``<p>`` est l’enfant de l’élément ``<div>``. -------------- Mais pourquoi apprendre ça pour scraper me direz-vous ? Pour bien récupérer les informations d’un site internet, il faut pouvoir comprendre sa structure et donc son code HTML. Les fonctions python qui servent au scrapping sont principalement construites pour vous permettre de naviguer entre les balises. Optionnel - CSS - le style de la page WEB ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Quand le bout de code html est écrit, il apaprait sous la forme d’un texte noir sur un fond blanc. Une manière simple de rendre la page plus belle, c’est d’y ajouter de la couleur. La feuille de style qui permet de rendre la page plus belle correspond au(x) fichier(s) `CSS <https://en.wikipedia.org/wiki/Cascading_Style_Sheets>`__. Toutes les pages HTML qui font référence à cette feuille de style externe hériteront de toutes ses définitions. Nous y reviendrons plus en détail dans le TD sur `Flask <http://flask.pocoo.org/>`__ (module Python de création de site internet). Scrapper avec python -------------------- Nous allons essentiellement utiliser le package `BeautifulSoup4 <https://www.crummy.com/software/BeautifulSoup/bs4/doc/>`__ pour ce cours, mais d’autres packages existent (`Selenium <https://selenium-python.readthedocs.io/>`__, `Scrapy <https://scrapy.org/>`__\ …). `BeautifulSoup <https://www.crummy.com/software/BeautifulSoup/bs4/doc/>`__ sera suffisant quand vous voudrez travailler sur des pages HTML statiques, dès que les informations que vous recherchez sont générées via l’exécution de scripts `Javascript <https://fr.wikipedia.org/wiki/JavaScript>`__, il vous faudra passer par des outils comme Selenium. De même, si vous ne connaissez pas l’URL, il faudra passer par un framework comme `Scrapy <https://scrapy.org/>`__, qui passe facilement d’une page à une autre (“crawl”). Scrapy est plus complexe à manipuler que `BeautifulSoup <https://www.crummy.com/software/BeautifulSoup/bs4/doc/>`__ : si vous voulez plus de détails, rendez-vous sur la page du tutorial `Scrapy Tutorial <https://doc.scrapy.org/en/latest/intro/tutorial.html>`__. Utiliser BeautifulSoup ~~~~~~~~~~~~~~~~~~~~~~ Les packages pour scrapper des pages HTML : - `BeautifulSoup4 <https://www.crummy.com/software/BeautifulSoup/bs4/doc/>`__ (``pip install bs4``) - `urllib <https://docs.python.org/3/library/urllib.html#module-urllib>`__ .. code:: ipython3 import urllib import bs4 #help(bs4) 1ere page HTML ^^^^^^^^^^^^^^ On va commencer facilement, prenons une page wikipedia, par exemple celle de la Ligue 1 de football : `Championnat de France de football 2016-2017 <https://fr.wikipedia.org/wiki/Championnat_de_France_de_football_2016-2017>`__. On va souhaiter récupérer la liste des équipes, ainsi que les url des pages Wikipedia de ces équipes. .. code:: ipython3 # Etape 1 : se connecter à la page wikipedia et obtenir le code source url_ligue_1 = "https://fr.wikipedia.org/wiki/Championnat_de_France_de_football_2016-2017" from urllib import request request_text = request.urlopen(url_ligue_1).read() print(request_text[:1000]) .. parsed-literal:: b'<!DOCTYPE html>\n<html class="client-nojs" lang="fr" dir="ltr">\n<head>\n<meta charset="UTF-8"/>\n<title>Championnat de France de football 2016-2017 \xe2\x80\x94 Wikip\xc3\xa9dia\n