Web scraping Python : extraire des données web et les analyser avec Pandas, pas à pas – illustration Python

Web scraping Python : extraire des données web et les analyser avec Pandas, pas à pas

Thématique
Data & business intelligence
Mis à jour
Lecture
12 min
Formation
Python Data Science : Du Web Scraping à l'Analyse Pandas

L'essentiel en 30 secondes

  • Le web scraping Python consiste à télécharger le code HTML d'une page avec Requests, puis à en extraire les informations utiles avec BeautifulSoup.
  • Pandas range ensuite les données collectées dans un DataFrame, une table en mémoire que l'on nettoie, filtre, trie, agrège et exporte vers Excel ou CSV.
  • Avant de scraper un site, vérifiez s'il propose une API, lisez ses conditions d'utilisation et son fichier robots.txt, et espacez vos requêtes.
  • Les pages dont le contenu est généré en JavaScript nécessitent un navigateur automatisé comme Selenium ou Playwright, car Requests ne récupère que le HTML initial.
  • Travailler dans un environnement virtuel (venv) isole les bibliothèques de chaque projet et évite les conflits de versions.
Sommaire de l'article
  1. Qu’est-ce que le web scraping avec Python ?
  2. À quoi sert le web scraping en data science ?
  3. Scraper de façon responsable : les règles à respecter
  4. Comment faire du web scraping avec Python : les étapes
  5. Analyser les données avec Pandas
  6. Astuces et bonnes pratiques de scraping
  7. Les erreurs fréquentes en web scraping Python
  8. Quel outil choisir pour extraire des données web ?
  9. Comment progresser en web scraping et en data science Python ?
  10. En résumé

Le web scraping Python consiste à écrire un script qui télécharge des pages web et en extrait automatiquement les informations utiles : prix, titres, caractéristiques de produits, annonces, résultats sportifs. Associé à Pandas, il permet ensuite de nettoyer ces données, de les analyser et de les exporter vers Excel, en quelques lignes de code.

Ce guide s’adresse aux débutants en programmation comme aux analystes qui veulent automatiser une collecte d’informations. Vous y verrez comment préparer votre environnement, lire la structure d’une page HTML, écrire un script d’extraction complet, parcourir plusieurs pages, puis manipuler les résultats dans un DataFrame Pandas.

Qu’est-ce que le web scraping avec Python ?

Le web scraping est l’extraction automatisée de données depuis des pages web. En Python, un script envoie une requête HTTP au site (bibliothèque Requests), reçoit le code HTML de la page, l’analyse (bibliothèque BeautifulSoup) pour isoler les éléments voulus, puis enregistre le résultat dans une structure exploitable, le plus souvent un DataFrame Pandas.

Le processus suit toujours quatre temps :

  1. Télécharger la page (requête HTTP GET).
  2. Analyser le HTML pour construire un arbre de balises navigable.
  3. Extraire les éléments ciblés grâce à leurs balises, classes ou attributs.
  4. Structurer et exporter les données : liste de dictionnaires, DataFrame, puis fichier Excel ou CSV.

Python domine ce domaine pour une raison simple : il réunit dans un même langage la collecte (Requests, BeautifulSoup, Selenium, Scrapy) et l’analyse de données (Pandas, Matplotlib, scikit-learn). On passe de la page web au graphique sans changer d’outil.

À quoi sert le web scraping en data science ?

Les usages professionnels sont nombreux, dès lors qu’une information est publique mais qu’aucun export n’est proposé :

  • Veille tarifaire : suivre l’évolution des prix d’un catalogue concurrent.
  • Études de marché : recenser des offres, des annonces ou des caractéristiques de produits.
  • Constitution de jeux de données : alimenter une analyse statistique ou un modèle de machine learning.
  • Suivi de contenus : repérer les nouveautés d’une page de publications ou d’un site institutionnel.
  • Consolidation : rassembler dans un tableau unique des informations dispersées sur des dizaines de pages.

Avant de coder, posez-vous une question : le site propose-t-il une API ou un export ? Une API renvoie des données déjà structurées (souvent en JSON), plus fiables et plus stables qu’un scraping qui cassera à la prochaine refonte du site.

Scraper de façon responsable : les règles à respecter

Le scraping touche aux droits des sites et, parfois, aux données personnelles. Quelques règles s’imposent :

  • Lisez les conditions d’utilisation du site : certaines interdisent explicitement la collecte automatisée.
  • Consultez le fichier robots.txt (à la racine du domaine, par exemple /robots.txt) : il indique les zones que le site ne souhaite pas voir parcourues par des robots.
  • Espacez vos requêtes avec une pause entre chaque page, et ne lancez pas des centaines de requêtes simultanées.
  • Identifiez-vous avec un en-tête User-Agent explicite plutôt que de vous faire passer pour un autre service.
  • Ne contournez jamais une authentification, un paywall ou une protection anti-robot.
  • Données personnelles : noms, e-mails, téléphones sont soumis au RGPD, même s’ils sont publiés en ligne.

Pour vous entraîner sans risque, utilisez des sites conçus pour cela, comme books.toscrape.com, un faux catalogue de livres créé spécialement pour apprendre le scraping. C’est lui que nous utilisons dans les exemples ci-dessous.

Comment faire du web scraping avec Python : les étapes

Étape 1 — Installer Python et créer un environnement virtuel

Installez la dernière version stable de Python depuis le site officiel python.org. Sous Windows, cochez l’option Add python.exe to PATH pendant l’installation.

Créez ensuite un dossier de projet et un environnement virtuel, qui isole les bibliothèques de ce projet :

mkdir scraping-livres
cd scraping-livres
python -m venv .venv

# Activation sous Windows
.venv\Scripts\activate

# Activation sous macOS / Linux
source .venv/bin/activate

pip install requests beautifulsoup4 pandas openpyxl jupyter

Dans Visual Studio Code, installez l’extension Python, ouvrez le dossier, puis choisissez l’interpréteur de l’environnement virtuel avec Ctrl+Maj+P > Python: Select Interpreter.

Étape 2 — Tester une première requête

Commencez par vérifier que Python communique bien avec le web. Sur une API de test, la réponse arrive directement en JSON :

import requests

reponse = requests.get("https://jsonplaceholder.typicode.com/users", timeout=10)
print(reponse.status_code)      # 200 si tout va bien
utilisateurs = reponse.json()   # liste de dictionnaires Python
print(utilisateurs[0]["name"])

Sur une page web classique, la réponse est du HTML : reponse.text contient le code source de la page, que l’on va maintenant analyser.

Étape 3 — Comprendre la structure HTML de la page

Ouvrez la page dans votre navigateur, faites un clic droit sur un élément (le prix d’un livre) puis Inspecter. Les outils de développement affichent la balise correspondante. Sur books.toscrape.com, chaque livre est décrit ainsi :

  • un bloc article de classe product_pod ;
  • le titre complet dans l’attribut title du lien situé dans le h3 ;
  • le prix dans un paragraphe de classe price_color ;
  • la note dans un paragraphe de classe star-rating, suivie d’un mot (One à Five).

Repérer ce motif répété est la clé : on écrit l’extraction pour un bloc, puis on la répète sur tous.

Étape 4 — Écrire le script d’extraction

import requests
from bs4 import BeautifulSoup

URL = "https://books.toscrape.com/catalogue/page-1.html"
EN_TETES = {"User-Agent": "Mozilla/5.0 (projet de formation Python)"}

reponse = requests.get(URL, headers=EN_TETES, timeout=10)
reponse.raise_for_status()          # stoppe le script en cas d'erreur HTTP
reponse.encoding = "utf-8"          # évite les caractères mal décodés

soup = BeautifulSoup(reponse.text, "html.parser")

livres = []
for bloc in soup.select("article.product_pod"):
    livres.append({
        "titre": bloc.h3.a["title"],
        "prix": bloc.select_one("p.price_color").get_text(strip=True),
        "note": bloc.select_one("p.star-rating")["class"][1],
    })

print(len(livres), "livres extraits")
print(livres[0])

Les deux méthodes essentielles de BeautifulSoup sont select(), qui renvoie tous les éléments correspondant à un sélecteur CSS, et select_one(), qui renvoie le premier. get_text(strip=True) récupère le texte sans espaces superflus, et la notation element["attribut"] lit la valeur d’un attribut.

Étape 5 — Automatiser le scraping sur plusieurs pages

Le catalogue est réparti sur plusieurs pages numérotées. On transforme le code en fonction, puis on boucle sur les numéros de page, avec une pause entre chaque requête :

import time
import requests
from bs4 import BeautifulSoup

EN_TETES = {"User-Agent": "Mozilla/5.0 (projet de formation Python)"}
session = requests.Session()

def extraire_page(numero):
    url = f"https://books.toscrape.com/catalogue/page-{numero}.html"
    reponse = session.get(url, headers=EN_TETES, timeout=10)
    if reponse.status_code == 404:
        return None                      # plus de page : on s'arrête
    reponse.raise_for_status()
    reponse.encoding = "utf-8"
    soup = BeautifulSoup(reponse.text, "html.parser")
    resultats = []
    for bloc in soup.select("article.product_pod"):
        resultats.append({
            "titre": bloc.h3.a["title"],
            "prix": bloc.select_one("p.price_color").get_text(strip=True),
            "note": bloc.select_one("p.star-rating")["class"][1],
            "page": numero,
        })
    return resultats

tous_les_livres = []
numero = 1
while True:
    page = extraire_page(numero)
    if not page:
        break
    tous_les_livres.extend(page)
    numero += 1
    time.sleep(1)                        # une seconde entre deux pages

print(len(tous_les_livres), "livres au total")

Cette version a trois qualités : elle s’arrête d’elle-même quand il n’y a plus de page, elle réutilise la connexion grâce à requests.Session(), et elle ménage le serveur avec time.sleep(). C’est le type de refactoring qui rend un script maintenable : une fonction par tâche, des constantes en haut, aucune valeur répétée.

Étape 6 — Charger les résultats dans un DataFrame Pandas

import pandas as pd

df = pd.DataFrame(tous_les_livres)

print(df.shape)       # (nombre de lignes, nombre de colonnes)
print(df.head())      # 5 premières lignes
df.info()             # types et valeurs non nulles par colonne

Une liste de dictionnaires se convertit directement en DataFrame : chaque clé devient une colonne, chaque dictionnaire une ligne.

Étape 7 — Exporter vers Excel ou CSV

df.to_excel("livres.xlsx", index=False)                       # nécessite openpyxl
df.to_csv("livres.csv", index=False, encoding="utf-8-sig")    # accents lisibles dans Excel

Certains tutoriels utilisent la bibliothèque xlwt, qui produit l’ancien format .xls. Elle fonctionne, mais n’est plus maintenue : pour un fichier .xlsx moderne, passez par Pandas et openpyxl.

Analyser les données avec Pandas

Une fois les données dans un DataFrame, Pandas devient votre tableur programmable. Le plus confortable pour explorer est Jupyter Notebook (lancez jupyter notebook dans le terminal, ou ouvrez un fichier .ipynb dans VS Code) : chaque cellule s’exécute séparément et affiche son résultat juste en dessous.

Series et DataFrame : les deux structures de base

Une Series est une colonne de valeurs avec un index ; un DataFrame est un ensemble de Series qui partagent le même index. df["prix"] renvoie une Series, df[["titre", "prix"]] renvoie un DataFrame de deux colonnes.

Nettoyer et typer les colonnes

Les prix extraits sont du texte (« £51.77 ») et les notes des mots (« Three »). Il faut les convertir pour calculer :

df["prix"] = (
    df["prix"]
    .str.replace("£", "", regex=False)
    .astype(float)
)

correspondance = {"One": 1, "Two": 2, "Three": 3, "Four": 4, "Five": 5}
df["note"] = df["note"].map(correspondance)

df = df.drop_duplicates(subset="titre")
print(df.isna().sum())      # valeurs manquantes par colonne

Filtrer, trier et agréger

# Livres à plus de 50 £, du plus cher au moins cher
chers = df[df["prix"] > 50].sort_values("prix", ascending=False)

# Livres bien notés et abordables
bons_plans = df[(df["note"] >= 4) & (df["prix"] < 20)]

# Statistiques par note
synthese = df.groupby("note")["prix"].agg(["count", "mean", "min", "max"]).round(2)
print(synthese)

# Statistiques descriptives globales
print(df["prix"].describe())

Les conditions se combinent avec & (et) et | (ou), chaque condition entre parenthèses. groupby() joue le rôle d’un tableau croisé dynamique : il regroupe les lignes et calcule une agrégation par groupe.

Les opérations Pandas à connaître

BesoinCode PandasÉquivalent Excel
Aperçu des donnéesdf.head(), df.info()Parcourir la feuille
Sélectionner des colonnesdf[["titre", "prix"]]Masquer des colonnes
Filtrer des lignesdf[df["prix"] > 50]Filtre automatique
Trierdf.sort_values("prix")Trier de A à Z
Créer une colonnedf["prix_ttc"] = df["prix"] * 1.2Formule dans une colonne
Agréger par groupedf.groupby("note")["prix"].mean()Tableau croisé dynamique
Joindre deux tablespd.merge(df1, df2, on="id")RECHERCHEX
Supprimer les doublonsdf.drop_duplicates()Supprimer les doublons

Astuces et bonnes pratiques de scraping

  • Commencez par pandas.read_html : si les données sont déjà dans un tableau HTML, pd.read_html(url) renvoie directement une liste de DataFrames (bibliothèque lxml requise).
  • Protégez chaque extraction : si un élément manque sur une fiche, select_one() renvoie None et l’accès à un attribut provoque une erreur. Testez la présence de l’élément avant de lire son contenu.
  • Enregistrez le HTML brut d’une page pendant le développement pour travailler hors ligne et ne pas solliciter le site à chaque test.
  • Journalisez la page en cours et les erreurs rencontrées : sur un long scraping, vous saurez où reprendre.
  • Sauvegardez régulièrement les résultats intermédiaires, par exemple toutes les dix pages.
  • Surveillez les changements du site : une refonte suffit à casser les sélecteurs. Un script de scraping demande une maintenance régulière.

Repérer l’API cachée d’un site dynamique

Avant de sortir un navigateur automatisé, ouvrez les outils de développement (F12), onglet Réseau, puis filtrez sur Fetch/XHR et rechargez la page. Beaucoup de sites dynamiques chargent leurs données depuis une URL qui renvoie du JSON. Si cette requête est accessible sans authentification et que les conditions du site le permettent, l’interroger directement avec requests.get(...).json() est plus rapide, plus léger et plus stable que d’analyser le HTML affiché.

Visualiser rapidement les résultats

Pandas s’appuie sur Matplotlib pour produire un premier graphique en une ligne, pratique pour vérifier la cohérence des données collectées :

df["prix"].plot(kind="hist", bins=20, title="Répartition des prix")
df.groupby("note")["prix"].mean().plot(kind="bar", title="Prix moyen par note")

Un histogramme montre immédiatement une valeur aberrante (un prix à zéro, un prix multiplié par cent) qui trahit une erreur d’extraction ou de conversion. Pour des analyses statistiques plus poussées, le langage R est une alternative solide à Pandas, très utilisée dans la recherche et les études.

Les erreurs fréquentes en web scraping Python

ErreurCauseSolution
AttributeError: 'NoneType' object has no attribute...Le sélecteur ne trouve pas l’élémentVérifier le sélecteur dans l’inspecteur, tester if element:
La liste extraite est videContenu généré en JavaScriptChercher l’API appelée par la page ou utiliser Selenium/Playwright
Caractères bizarres (« £ »)Mauvais encodage détectéDéfinir reponse.encoding = "utf-8"
Erreur 403 ou 429Blocage ou trop de requêtesRalentir, respecter les règles du site, ne pas insister
ModuleNotFoundErrorBibliothèque installée hors de l’environnement virtuelActiver le venv puis relancer pip install
Somme ou moyenne impossible sur une colonneValeurs restées en texteNettoyer puis convertir avec astype(float) ou pd.to_numeric
Fichier CSV illisible dans ExcelEncodage ou séparateurencoding="utf-8-sig" et, si besoin, sep=";"

Quel outil choisir pour extraire des données web ?

OutilIdéal pourLimites
API officielleDonnées structurées et stablesN’existe pas toujours, quotas possibles
pandas.read_htmlTableaux HTML simplesUniquement les balises de tableau
Requests + BeautifulSoupLa majorité des sites statiquesNe lit pas le contenu généré en JavaScript
Selenium ou PlaywrightSites dynamiques, clics, défilementPlus lent, plus lourd à installer
ScrapyCollectes à grande échelle, nombreux sitesCourbe d’apprentissage plus élevée
Power Query (onglet Web)Récupérer un tableau web sans coderPeu adapté aux pages complexes et à la pagination

Si votre objectif est seulement d’importer un tableau web dans un rapport, sans écrire de code, le connecteur Web de Power Query suffit souvent : notre guide Power Query dans Power BI le présente.

Comment progresser en web scraping et en data science Python ?

Voici un parcours réaliste pour devenir autonome :

  1. Les bases de Python (une à deux semaines) : variables, listes, dictionnaires, boucles, fonctions. Notre guide pour apprendre Python détaille cette étape.
  2. HTML et sélecteurs CSS (quelques heures) : balises, classes, attributs, inspecteur du navigateur.
  3. Premier scraper : une page, puis plusieurs pages avec pagination et export.
  4. Pandas : Series, DataFrames, nettoyage, filtres, groupby, jointures.
  5. Aller plus loin : sites dynamiques, stockage en base de données, visualisation, puis modèles prédictifs.

Pour être accompagné sur les premières étapes, la formation vidéo Python du web scraping à l’analyse Pandas d’EspritAcadémique dure 3 h 15, ne demande aucun prérequis et suit une démarche 100 % pratique. Elle couvre notamment :

  • l’installation de Python, la création d’un environnement virtuel et la configuration de VS Code ;
  • le test d’une première API et l’affichage de données brutes ;
  • l’analyse du code HTML et l’écriture pas à pas d’un script d’extraction de prix ;
  • l’automatisation sur plusieurs pages et l’export des résultats vers Excel ;
  • la découverte de Jupyter Notebook et les fondamentaux de Pandas, des Series aux DataFrames.

Une fois vos données collectées, deux prolongements naturels s’offrent à vous : les stocker et les interroger dans une base, avec notre guide pour apprendre SQL, ou les exploiter dans des modèles prédictifs, présentés dans notre article sur le machine learning.

En résumé

Le web scraping avec Python repose sur un enchaînement simple : Requests télécharge la page, BeautifulSoup en extrait les éléments grâce aux sélecteurs CSS, une boucle parcourt les pages avec des pauses, et Pandas transforme le résultat en DataFrame que l’on nettoie, analyse et exporte. Vérifiez toujours l’existence d’une API et les règles du site avant de collecter, et structurez votre code en fonctions pour qu’il reste facile à maintenir.

Questions fréquentes

Le web scraping est-il légal ?

Le scraping n'est pas interdit en soi, mais son usage est encadré. Respectez les conditions d'utilisation du site, ne contournez pas une authentification, ne surchargez pas le serveur et ne réutilisez pas de contenus protégés par le droit d'auteur ou les bases de données. Si vous collectez des données personnelles, le RGPD s'applique. En cas de doute pour un projet commercial, demandez un avis juridique.

Quelle bibliothèque Python utiliser pour le web scraping ?

Pour la plupart des sites, le duo Requests et BeautifulSoup suffit : Requests télécharge la page, BeautifulSoup l'analyse. Pour extraire un simple tableau HTML, pandas.read_html est encore plus rapide. Pour les sites dynamiques en JavaScript, utilisez Selenium ou Playwright. Pour des collectes à grande échelle sur des milliers de pages, le framework Scrapy est plus adapté.

Quelle est la différence entre une Series et un DataFrame dans Pandas ?

Une Series est une colonne unique de valeurs, associée à un index. Un DataFrame est un tableau à deux dimensions composé de plusieurs Series qui partagent le même index, comme une feuille Excel avec des colonnes nommées. Sélectionner une colonne d'un DataFrame, par exemple df["prix"], renvoie une Series.

Faut-il connaître Python avant d'apprendre le web scraping ?

Des bases suffisent : variables, listes, dictionnaires, boucles for et fonctions. Le scraping est d'ailleurs un excellent projet pour apprendre Python, car le résultat est concret et immédiat. Il faut aussi comprendre la structure d'une page HTML, c'est-à-dire les balises, les classes et les attributs, pour savoir quoi cibler.

Comment exporter des données scrapées vers Excel ?

Rangez les données dans un DataFrame Pandas, puis appelez df.to_excel("fichier.xlsx", index=False). Cette méthode nécessite la bibliothèque openpyxl, à installer avec pip. Pour un fichier CSV lisible directement dans Excel avec les accents, utilisez df.to_csv("fichier.csv", index=False, encoding="utf-8-sig").

Pourquoi mon script de scraping ne trouve aucun élément ?

Trois causes dominent. Le contenu est chargé en JavaScript et absent du HTML reçu par Requests. Le sélecteur CSS ne correspond pas exactement à la structure réelle de la page. Ou le site renvoie une page d'erreur ou de blocage. Affichez reponse.status_code et une partie de reponse.text pour vérifier ce que vous avez réellement reçu.