Dans ce billet vous allez apprendre à scraper des données précises dans un page web en Python (pour par exemple récupérer des listes d’adresses ou autres).
Le scraping de donnée consiste à récupérer automatiquement du contenu d’une page Web, par opposition au fait de les récupérer "à la main" avec des copier-coller.
- Les prérequis et leur installation
- Elle n'est pas belle ma soupe de données ?
- Optionnel : Extraire les données dans un fichier CSV
Les prérequis et leur installation
Pour nous atteler à cette tâche, nous avons besoin de plusieurs choses :
- Python (2 ou 3 peu importe, sachant que les exemples présentés seront en Python 3)
- La bibliothèque BeautifulSoup
- La bibliothèque Requests
- Le gestionnaire de paquet pip
Nous allons partir du principe que vous avez déjà Python d’installé et connaissez les bases de ce langage. Sinon je ne peux que vous conseiller de lire l’excellent tutoriel disponible sur le site.
Le gestionnaire de paquet pip
Pip est un gestionnaire de paquet pour Python qui permet d’installer, mettre à jour et de désinstaller facilement les bibliothèques non intégrées de base avec Python. Je vous recommande chaudement de l’utiliser si ce n’est pas déjà le cas.
Pour le télécharger, vous pouvez vous rendre sur la documentation officielle de pip et suivre la procédure décrite en fonction de votre OS.
Une fois installé, si vous êtes sous Windows, n’oubliez pas d’ajouter pip dans votre variable PATH
pour y avoir accès facilement, en rajoutant le chemin vers le dossier Script
de votre installation Python dans le PATH (un peu d’aide sur le sujet chez Sam & Max).
Voilà vous pouvez désormais installer facilement des bibliothèques Python (et toutes leurs dépendances) directement depuis votre terminal.
Installer BeautifulSoup et Requests
Vous pouvez désormais récupérer ces merveilleuses bibliothèques grâce à pip.
Pour faire cela, vous devez rentrer la commande suivante dans votre terminal :
1 | pip install bs4 requests |
Une fois cela fait, nous sommes prêts à attaquer le vif du sujet.
Elle n'est pas belle ma soupe de données ?
Commençons donc la construction de notre scraper.
Pour ce billet nous allons apprendre à scraper une page de Zeste de Savoir : la liste des tutos informatiques.
Il faut donc que notre script commence par les déclarations des bibliothèques utiles.
1 2 3 4 | import os import csv import requests from bs4 import BeautifulSoup |
Dans cette déclaration :
- Nous importons la bibliothèque os pour gérer la pause à la fin du script ;
- La bibliothèque CSV est optionnelle et seulement utile si vous voulez exporter les données scrappées dans un fichier CSV ;
- Nous importons la bibliothèque Requests qui va nous permettre de charger la page et stocker son contenu dans une variable ;
- Nous importons BeautifulSoup.
Nous récupérons la page avec requests.get
(qui va faire une requête HTTP/HTTPS). Une fois cette requête réalisée, nous pouvons récupérer le contenu de la page avec .content
. Enfin nous fournissons ce contenu à BeautifulSoup pour le parser.
1 2 3 | requete = requests.get("https://zestedesavoir.com/tutoriels/?category=autres-informatique") page = requete.content soup = BeautifulSoup(page) |
Nous avons désormais une variable soup
qui contient toutes les données structurées de la page et nous allons pouvoir les exploiter.
Récupérer l’information d’une balise HTML précise
Si par exemple nous souhaitions récupérer sur cette page le texte du titre <h1>
, nous pouvons procéder comme ceci.
1 2 | h1 = soup.find("h1", {"class": "ico-after ico-tutorials"}) print(h1.string) |
Détaillons un peu ce code. Pour récupérer les informations de la balise <h1>
nous avons récupéré les données avec BeautifulSoup et les avons affectés à une variable. La donnée récupérée est la première occurrence de tag HTML qui soit un tag <h1>
et qui possède les classes ico-after ico-tutorials
.
Si jamais vous avez un doute sur quelle est la balise ou la class de l’info que vous voulez récupérer vous pouvez la voir avec l’inspecteur de votre navigateur :
Si vous exécutez ce script, vous pouvez voir qu’effectivement le print
affiche ce que nous souhaitons mais avec beaucoup d’espace vide. Cela est dû au générateur de page HTML du site qui rajoute ces espaces vides (ce n’est pas le cas partout sur le web donc la solution sera à utiliser seulement pour des cas précis).
Pour remédier à cela, nous allons utiliser la méthode str.strip()
de Python après avoir sauvegardé le texte dans une variable.
1 | titre = h1.string.strip() |
Récupérer les informations de plusieurs balises identiques
Ok c’est bien sympa tout ça, mais si je veux récupérer le titre de tous les tutoriels de la page je fais comment ?
Nous y venons jeune impatient !
Pour cela BeautifulSoup a une autre méthode qui va vous aider : find_all()
.
Donc nous allons utiliser le code suivant pour récupérer le titre et le descriptif de chaque tutoriel :
1 2 3 4 5 6 | h3 = soup.find_all("h3", {"class": "content-title"}) desc = soup.find_all("p", {"class": "content-description"}) liste_titre = [elt.string.strip() for elt in h3] liste_description = [elt.string.strip() for elt in desc] |
find_all()
nous fournit une liste qu’il faut parcourir avec une boucle for
. À partir de cette boucle, nous avons donc pu stocker dans deux listes tous les titres et les descriptions des tutoriels de la page grâce aux compréhensions de liste de Python.
Ici nous avons utilisé des listes mais vous auriez aussi pu stocker ces données dans des dictionnaires avec comme clés les titres et comme valeurs les descriptions.
Une autre solution aurait été de stocker les deux valeurs dans une liste de tuples.
Optionnel : Extraire les données dans un fichier CSV
Vous avez maintenant toutes ces données, mais il va falloir pouvoir les "sortir" de votre script dans un format exploitable par le commun des mortels.
Pour cela nous allons utiliser la bibliothèque csv.
Il faut au préalable déclarer et ouvrir votre fichier csv en écriture avec un gestionnaire de contexte :
1 2 | with open("donnees.csv", "w", encoding="utf-8") as fichier writer = csv.writer(fichier) |
Une fois cela fait vous pouvez grâce à une boucle inscrire dans votre csv les données.
1 2 3 4 5 6 7 | j = len(liste_titre) i = 0 with open("donnees.csv", "w", encoding="utf-8") as fichier writer = csv.writer(fichier) while i < j: writer.writerow((liste_titre[i], liste_description[i])) i+=1 |
Comme vous pouvez le voir, l’instruction pour écrire une ligne dans un CSV est :
1 | writer.writerow(()) |
Cette double parenthèse est due au fait que nous utilisons un tuple en argument ici. Comme un tuple est noté à l’intérieur de parenthèse, il y a donc ici une double parenthèse. Vous pouvez en apprendre plus sur les tuples dans le tuto d’apprendre-python.com si le sujet vous intéresse.
Pour votre information cette méthode (writer.writerow
) ne peut recevoir en argument qu’un itérable. Pour en savoir plus si cela vous intéresse je ne peux que vous recommander la documentation officielle sur le sujet.
Et voilà, vous avez un fichier CSV contenant tous les informations qui peut donc être importé dans tableur (Excel ou LibreOfficeCalc par exemple).
Vous savez désormais comment scraper facilement des données structurées dans une page HTML. Pour aller plus loin, je ne peux que vous recommander d’aller faire un tour sur la documentation officielle de BeautifulSoup.
Je tiens à remercier les membres du site qui m’ont aidé dans la rédaction / correction de ce billet, en particulier Victor.