Scraping avec Python -Tutoriel- pages web statiques
I. Quelques définitions :
1-Le scraping
2-Page web statique
3-Page web dynamique
II. Scraper une page web statique
1-Inspecter les données ciblées dans le code source
2-Récupérer uniquement les données qui nous interessent
3-Automatiser le scraping sur plusieurs pages
I. Quelques définitions
1-Le scraping c’est quoi?
Pour faire court, c’est le fait de récupérer des données ciblées d’une ou plusieurs pages web.
Exemple : Récupérer tous les titres des articles de la page d’accueil du Figaro.
2-Définition page web statique
Une page web statique c’est simplement une page web qui présente tout son contenu directement : pas de lien vers une partie cachée de la page web, pas d’élément sur lequel cliquer pour avoir à afficher une partie cachée de la page.
En gros, c’est une page web qui ne bouge pas, ou il n’y a pas d’interaction possible. Exemple :
3-Définition page web dynamique
Pas opposition, une page web dynamique contiendra de l’information “cachée”, c’est-à-dire que le contenu de la page pourra être modifié en fonction de l’utilisateur, en cliquant sur un lien par exemple.
Exemple : Une recherche sur Google proposant plusieurs suggestions est une page web dynamique.
On voit bien que le contenu de la page web va changer quand on cliquera sur une des pages suggérées par Google.
Aujourd’hui quasiment toutes les pages web sont dynamiques.
II. Scraper une page web statique
PS : Notebook disponible sur mon Github via ce lien.
Je vais choisir pour cet exemple une page web, qui présente un tableau de données “statiques”. (La page en soi contient des liens, elle est donc dynamique, mais les données qui nous interessent sont “statiques” donc la méthode est la même.)
Sur ce site, on dispose des prénoms donnés aux bébés et leur occurence pour l’année 2019 en France.
On va récupérer toutes ces données dans un tableau automatiquement.
Si l’on scroll jusqu’en bas on remarque qu’il y a plusieurs pages de prénoms :
Lorsque l’on clique sur la page suivante, l’URL de la page est modifiée et le numéro de la page du classement apparait :
Sur chaque page du classement, les données sont toujours organisées pareil : les prénoms/occurences sont rangés dans un tableau juste en dessous d’un titre “Prénoms les plus donnés en France”.
En somme, la structure de la page ne change pas ➡ Il sera alors facile pour nous de récupérer ce tableau de données pour chaque page du classement, en faisant une boucle sur le numéro.
1-Inspecter les données ciblées dans le code source
Tout d’abord, rendez vous sur la page que vous souhaitez scraper et affichez le code source de la page en appuyant sur la touche F12. (Pour cela, dans la plupart des cas il faut maintenir la touche fn puis appuyez sur F12,)
Vous verrez alors le code source s’afficher sur la droite :
Toutes les informations d’une page web se situent dans son code source. Mais nous ne voulons pas tout récupérer! Il nous faut juste le tableau des prénoms/occurences.
2-Récupérer uniquement les données qui nous interessent
Pour obtenir les données de la page web, nous utiliserons la bibliothèque requests qui fera des requêtes HTTP à l’URL que nous lui préciserons.
Pour extraire uniquement les données qui nous interessent, nous allons utiliser une bibliothèque Python : BeautyfulSoup qui va nous aider à trier les informations.
Nous allons stocker les données dans un dataframe, très utile pour la manipulation de données. La bibliothèque nécessaire pour cela est pandas.
Installations
pip install bs4
pip install requests
pip install pandas
Importations
from bs4 import BeautifulSoup
import requests
import pandas as pd
On récupère d’abord la page web “brute” dans la variable r en faisant une requête HTTP GET à l’URL:
url = "https://www.journaldesfemmes.fr/prenoms/classement/prenoms/les-plus-donnes"r = requests.get(url)
On transforme ensuite le code HTML brut en un arbre syntaxique (une soupe) pour pouvoir en extraire les informations qui nous interessent.
soup = BeautifulSoup(r.text, 'lxml')
Parfait, on a maintenant toutes les infos de la page web triées.
On peut admirer la beauté de la soupe en affichant :
print(soup.prettify())
Puis on recherche toutes les valeurs que l’on va rentrer dans notre tableau :
Recherche d’une donnée dans une page web
- Afficher le code source (fn + F12)
- Selectionner l’inspecteur d’éléments (Ctrl + Shift + c) ou en appuyant sur :
- Cliquez sur le premier prénom du classement ➡ vous verrez alors le code source vous indiquer l’endroit correspondant au prénom dans l’arbre syntaxique. Séléctionnez les petites flèches noires et vous devriez voir le prénom, son occurence en dessous et son classement au dessus :
- Remarquez que les informations sont stockées dans une balise <td> puis dans une balise <tr> & qu’il y a autant de prénoms sur la page que de balises “<tr>…</tr>” ➡ Pour une balise <tr>, on a donc l’information d’une ligne du classement.
Extraction d’une donnée ciblée à partir du code HTML
Nous allons chercher toutes les balises <tr>/<td> dans notre soupe pour récupérer uniquement les données du tableau.
Pour vérifier qu’on récuperera bien les données cherchées, vous pouvez exécuter le code suivant :
for i in soup.find_all("tr")[1:]:
print(i.find_all("td"))
On a bien toutes les infos! Evitera juste de prendre la première ligne qui est vide.
Mais avant ça, on va créer un dataframe pour y stocker nos données.
columns_names = ["Rang", "Prénom", "Naissances en 2019"]
df = pd.DataFrame(columns = columns_names)
Super maintenant tout est prêt! On a plus qu’à cueillir nos données et à les rajouter au fur et à lesure dans notre tableau df.
for i in soup.find_all("tr")[1:]:
# On cherche le rang du ième prénom
rank = i.find_all("td")[0].text
# On cherche le ième prénom ....
name = i.find_all("td")[1].text
# La ième occurence
occurence = i.find_all("td")[2].text # On rajoute ligne par ligne au dataframe
df = df.append({'Rang': rank, 'Prénom': name, 'Naissances en 2019': occurence}, ignore_index=True)
Vérifiez vos 5 premières lignes sont correctes :
print(df.head())
Et voila, on vient de scraper une page web :)
Récapitulation
Mais on a juste scrapé une page, alors qu’il y a un certain nombre :
3-Automatiser le scraping sur plusieurs pages
On l’a vu plus haut, la structure de la page ne change pas. Pour le vérifier, vous pouvez rechercher un prénom sur n’importe quelle autre page avec l’inspecteur d’éléments et remarquer que le prénom se situe bien dans une balise <tr>/<td>.
Donc, on peut automatiser le scraping en bouclant sur le numéro de page.
Cette fois-ci, on va utiliser une URL contenant le numéro de page, comme expliqué plus haut.
url = "https://www.journaldesfemmes.fr/prenoms/classement/prenoms/les-plus-donnes?page="
La seule différence avec la partie 1, c’est que nous allons itérer sur le numéro de page, débuttant à 1, et tester que la valeur du prénom change bien à chaque itération.
numero_page = 1
prenom_0 = "Prénom par défault"
prenom = ""while prenom_0 != prenom :
prenom = prenom_0
print("Nous allons scraper cette page web : " + url + str(numero_page))try :
r = requests.get(url + str(numero_page))
soup = BeautifulSoup(r.text, 'lxml')
for i in soup.find_all("tr")[1:]:
rang = i.find_all("td")[0].text
prenom = i.find_all("td")[1].text
occurence = i.find_all("td")[2].textdf = df.append({'Rang': rang, 'Prénom': prenom, 'Naissances en 2018': occurence}, ignore_index=True)
numero_page += 1
except :
print("Erreur lors du scraping")
break
L’affichage du dataframe nous donne :
Vous pouvez retrouver le notebook de ce tuto à télécharger et à tester sur votre machine!!