BeautifulSoup
La bibliothèque Python qui transforme une page HTML en arborescence d'objets, pour piocher dedans avec des sélecteurs CSS ou des recherches par balise. L'outil de base du scraping côté parsing.
À quoi ça sert
Quand on veut extraire des données d'une page web (titres, prix, liens, tableaux…), on procède toujours en deux temps :
- Récupérer le HTML de la page (avec
requests, Selenium ou Playwright). - Le parser pour aller chercher ce qui nous intéresse — c'est là que BeautifulSoup entre en jeu.
BeautifulSoup (souvent appelé BS4 car la version actuelle est la 4) prend une chaîne
de HTML et renvoie une structure Python navigable : tu peux demander « tous les
<a> dont la classe est btn » ou « le premier
<h1> dans la div d'id main » en quelques lignes.
BeautifulSoup transforme une soupe de HTML en arborescence Python où on peut piocher avec des sélecteurs CSS ou des recherches par balise.
BeautifulSoup ne fait que parser du HTML qu'on lui donne. Pour récupérer une page, il faut un autre outil : requests pour les pages statiques, Selenium ou Playwright pour celles dont le contenu n'apparaît qu'après exécution du JavaScript.
Un exemple d'usage
On veut récupérer toutes les citations affichées sur la page d'accueil de
quotes.toscrape.com
(un site fait exprès pour s'entraîner au scraping). Avec requests + BS4, ça tient en
une dizaine de lignes :
import requests
from bs4 import BeautifulSoup
r = requests.get("https://quotes.toscrape.com")
soup = BeautifulSoup(r.text, "html.parser")
for bloc in soup.select(".quote"):
texte = bloc.select_one(".text").get_text(strip=True)
auteur = bloc.select_one(".author").get_text(strip=True)
print(f"{auteur} — {texte}")
Tu obtiens 10 citations affichées dans la console. Si la page utilisait du JavaScript pour
charger les citations (c'est le cas de quotes.toscrape.com/js/), requests
ne verrait qu'une coquille HTML vide : il faudrait alors passer par
Selenium ou Playwright pour exécuter
le JS, puis donner le HTML rendu à BS4.
How-to : installer et utiliser BeautifulSoup
-
Créer un venv et installer les paquets
BeautifulSoup s'installe avec pip (ou UV). On installe aussi
requestspour télécharger les pages :bashpython3 -m venv .venv source .venv/bin/activate pip install beautifulsoup4 requestsAstuceLe paquet s'appelle
beautifulsoup4mais on l'importe avecfrom bs4 import BeautifulSoup. C'est un piège classique des débutants. -
Charger une page
On télécharge le HTML avec
requests:pythonimport requests r = requests.get("https://quotes.toscrape.com") r.raise_for_status() # lève une exception si HTTP >= 400 html = r.textraise_for_status()est ta sécurité : si le site renvoie 404 ou 500, ton script s'arrête net au lieu de parser une page d'erreur. -
Parser le HTML
pythonfrom bs4 import BeautifulSoup soup = BeautifulSoup(html, "html.parser")"html.parser"est le parser intégré à Python — suffisant dans 95 % des cas. Pour des HTML cassés ou du XML, tu peux installerlxmlet passer"lxml"à la place. -
Sélectionner avec
findetfind_allL'API historique : on cherche par balise et par attributs.
python# Le premier <h1> de la page titre = soup.find("h1") # Tous les <a> dont la classe est "tag" tags = soup.find_all("a", class_="tag") # Le bloc avec id="main" main = soup.find(id="main")Note bien
class_avec un underscore :classest un mot réservé en Python. -
Sélectionner avec
select(sélecteurs CSS)Souvent plus pratique : tu utilises la même syntaxe que dans une feuille de style. Si tu sais inspecter une page avec les DevTools du navigateur, tu sais déjà écrire un sélecteur CSS.
python# Tous les blocs de classe "quote" quotes = soup.select(".quote") # Le premier h1 dans la div d'id "main" titre = soup.select_one("#main h1") # Tous les liens dans une nav liens = soup.select("nav a")selectrenvoie une liste,select_onerenvoie le premier match (ouNonesi rien ne correspond). -
Extraire le texte et les attributs
pythonlien = soup.select_one("a.next") # Texte affiché print(lien.get_text(strip=True)) # Attribut href (deux écritures équivalentes) print(lien["href"]) print(lien.get("href")) # renvoie None si l'attribut manque, plus sûrget_text(strip=True)nettoie au passage les espaces et retours à la ligne inutiles — pratique parce que le HTML brut en contient toujours. -
Combiner avec Selenium ou Playwright
Pour les pages dont le contenu est généré par JavaScript, le pattern le plus pratique est de récupérer le HTML rendu par le navigateur et de le donner à BS4 :
python# Avec Selenium soup = BeautifulSoup(driver.page_source, "html.parser") # Avec Playwright soup = BeautifulSoup(page.content(), "html.parser")On laisse le navigateur s'occuper du JS, et BS4 fait ce qu'il fait de mieux : extraire les données. Voir les fiches Selenium et Playwright pour le détail.
-
Bonnes pratiques de scraping
- Lis le
robots.txtdu site (https://exemple.com/robots.txt) et respecte ses interdictions. - Identifie ton script avec un User-Agent honnête :
requests.get(url, headers={"User-Agent": "MonProjet/0.1 contact@email.fr"}). - Espace tes requêtes avec
time.sleep(1)entre chaque page : tu n'es pas pressé, le serveur en face oui. - Vérifie les conditions d'utilisation du site avant de scraper massivement, et préfère l'API officielle si elle existe.
- Mets en cache ce que tu as déjà téléchargé pendant le développement, pour ne pas frapper le site à chaque exécution.
- Lis le
Aide-mémoire
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, "html.parser")
# Recherche par balise et attributs
soup.find("h1") # 1er match ou None
soup.find_all("a", class_="btn") # liste
soup.find(id="main")
soup.find("a", attrs={"data-id": "42"})
# Sélecteurs CSS (souvent plus simple)
soup.select(".quote .author")
soup.select_one("#main h1")
soup.select("a[href^='/page/']") # href commence par "/page/"
# Extraire
el.get_text(strip=True) # texte propre
el["href"] # attribut (KeyError si absent)
el.get("href") # attribut (None si absent)
el.attrs # tous les attributs
# Naviguer dans l'arbre
el.parent
el.children # itérable
el.next_sibling, el.previous_sibling
Pour aller plus loin
- Documentation officielle : crummy.com/software/BeautifulSoup/bs4/doc/
- Site d'entraînement utilisé dans les exemples : quotes.toscrape.com
- Pour les pages dynamiques : fiche Selenium ou Playwright.
- Pour récupérer des pages statiques : la doc de requests.