- Version : beautifulsoup4 4.14.3 + requests 2.34.1, Python 3.10+ requis
- Ce que vous allez construire : un scraper qui extrait titres, prix et liens d'une page HTML et exporte en CSV
- Temps estimé : 20 minutes sur Mac M1, 30 minutes sur Intel/Linux
- Piège fréquent :
AttributeError: 'NoneType'quand le sélecteur CSS ne matche pas — toujours vérifier avec Inspecter avant de coder
Introduction
Vous allez construire un scraper web fonctionnel avec Python 3.10+, BeautifulSoup 4.14.3 et Requests 2.34.1 en 20 minutes, capable d'extraire des données structurées depuis n'importe quelle page HTML. Documentation officielle BeautifulSoup — PyPI beautifulsoup4 4.14.3.
Ce que vous allez construire et pourquoi en 2026
Un script Python qui scrape automatiquement les titres, prix et liens d'une page web, exporte les résultats en CSV et gère les erreurs courantes (404, anti-bot, encodage). Prérequis : Python 3.10 ou supérieur, 4 Go de RAM minimum, macOS/Linux/Windows. Temps estimé : 20 minutes sur Mac M1, 30 minutes sur Intel. BeautifulSoup est gratuit, open-source sous licence MIT, et compatible Python 3.7+.
Installation : commandes exactes à copier
python3 -m venv scraper-env
source scraper-env/bin/activate # Linux/macOS
# scraper-envScriptsactivate # Windows
pip install beautifulsoup4==4.14.3 requests==2.34.1 lxml
Résultat attendu : Successfully installed beautifulsoup4-4.14.3 requests-2.34.1 lxml-5.3.0. Erreur courante : ERROR: Could not build wheel for lxml → installer les bibliothèques système avec sudo apt install libxml2-dev libxslt1-dev (Ubuntu) ou xcode-select --install (macOS).
Configuration : les fichiers et variables à définir
Créez un fichier .env à la racine du projet :
# .env
TARGET_URL=https://books.toscrape.com
OUTPUT_DIR=./output
DELAY_SECONDS=1
USER_AGENT=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36
TARGET_URL est l'URL cible. DELAY_SECONDS est le délai entre chaque requête (1 seconde minimum pour respecter le serveur). USER_AGENT identifie votre scraper — ne pas laisser la valeur par défaut de Requests (python-requests/2.34.1) car certains sites la bloquent.
Le code du projet : construire la fonctionnalité principale
Créez scraper.py :
import csv
import os
import time
from pathlib import Path import requests
from bs4 import BeautifulSoup
from dotenv import load_dotenv load_dotenv() TARGET_URL = os.getenv("TARGET_URL", "https://books.toscrape.com")
OUTPUT_DIR = Path(os.getenv("OUTPUT_DIR", "./output"))
DELAY = int(os.getenv("DELAY_SECONDS", "1"))
HEADERS = {"User-Agent": os.getenv("USER_AGENT", "ScraperBot/1.0")} def fetch_page(url: str) -> BeautifulSoup: """Télécharge une page et retourne un objet BeautifulSoup.""" response = requests.get(url, headers=HEADERS, timeout=10) response.raise_for_status() # Utiliser .content (bytes) pas .text (str) pour éviter # les problèmes d'encodage return BeautifulSoup(response.content, "lxml") def extract_books(soup: BeautifulSoup) -> list[dict]: """Extrait les données de chaque livre sur la page.""" books = [] articles = soup.find_all("article", class_="product_pod") for article in articles: title = article.h3.a["title"] price = article.find("p", class_="price_color").get_text(strip=True) link = article.h3.a["href"] books.append({"title": title, "price": price, "link": link}) return books def save_to_csv(data: list[dict], filename: str) -> None: """Sauvegarde les données en CSV.""" OUTPUT_DIR.mkdir(parents=True, exist_ok=True) filepath = OUTPUT_DIR / filename with open(filepath, "w", newline="", encoding="utf-8") as f: writer = csv.DictWriter(f, fieldnames=["title", "price", "link"]) writer.writeheader() writer.writerows(data) print(f"{len(data)} livres sauvegardés dans {filepath}") def main(): print(f"Scraping {TARGET_URL}..") soup = fetch_page(TARGET_URL) books = extract_books(soup) save_to_csv(books, "books.csv") time.sleep(DELAY) if __name__ == "__main__": main()
Points clés du code : response.content (bytes) plutôt que response.text pour éviter les erreurs d'encodage, le parser "lxml" plus rapide que "html.parser", et response.raise_for_status() qui lève une exception sur les codes 4xx/5xx. Chaque fonction fait une seule chose — c'est le pattern recommandé par la documentation BeautifulSoup.
Tester et valider que ça fonctionne
pip install python-dotenv
python scraper.py
Sortie attendue :
Scraping https://books.toscrape.com..
20 livres sauvegardés dans output/books.csv
Vérifiez le fichier CSV :
head output/books.csv
title,price,link
A Light in the Attic,£51.77,catalogue/a-light-in-the-attic_1000/index.html
..
Si vous obtenez AttributeError: 'NoneType' object has no attribute 'text', c'est que le sélecteur CSS ne trouve pas l'élément. Ouvrez la page dans votre navigateur, clic droit → Inspecter, et vérifiez que la classe CSS correspond exactement à ce que votre code cherche.
Déployer et utiliser en production
Pour exécuter le scraper régulièrement avec cron (Linux/macOS) :
# Éditer le crontab
crontab -e
# Exécuter chaque jour à 6h du matin
0 6 * * * cd /chemin/vers/projet && /chemin/vers/scraper-env/bin/python scraper.py >> scraper.log 2>&1
Pour un déploiement Docker :
# Dockerfile
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY .
CMD ["python", "scraper.py"]
Pour mettre à jour BeautifulSoup : pip install --upgrade beautifulsoup4. Vérifiez la version avec pip show beautifulsoup4.
Aller plus loin : 3 extensions concrètes
1. Scroller plusieurs pages : Ajoutez une boucle qui suit les liens « Next » avec soup.find("li", class_="next").a["href"]. Ajoutez un paramètre max_pages pour limiter le nombre de pages.
2. Exporter en JSON au lieu de CSV : Remplacez save_to_csv par import json; json.dump(data, open(filepath, "w"), ensure_ascii=False, indent=2). Plus adapté pour les API.
3. Gérer le JavaScript rendering : Installez pip install selenium webdriver-manager et remplacez requests.get() par un driver Selenium qui attend le chargement dynamique. Nécessaire pour les sites React/Vue.
Étapes à suivre5
Étape 1 — Installer Python, BeautifulSoup et Requests
Installez Python 3.10 ou supérieur si ce n’est pas déjà fait. Téléchargez-le sur python.org ou via votre gestionnaire de paquets :brew install python@3.12(macOS) ousudo apt install python3 python3-pip(Ubuntu). Créez un environnement virtuel pour isoler les dépendances :python3 -m venv scraper-env && source scraper-env/bin/activate. Installez les paquets :pip install beautifulsoup4==4.14.3 requests==2.34.1 lxml python-dotenv. Vérifiez l’installation :python3 -c "from bs4 import BeautifulSoup; print(BeautifulSoup.__version__)"doit afficher4.14.3. Si vous obtenezModuleNotFoundError: No module named 'bs4', vérifiez que votre environnement virtuel est activé avecwhich python— le chemin doit pointer versscraper-env/bin/python. Pour figer les versions et garantir la reproductibilité, lancezpip freeze > requirements.txtaprès l’installation. Sur Ubuntu, sipython3-venvest absent, installez-le avecsudo apt install python3.12-venvavant de créer l’environnement.Étape 2 — Configurer le projet et les variables d'environnement
Créez la structure de fichiers :mkdir scraper-project && cd scraper-project && touch scraper.py .env requirements.txt. Dansrequirements.txt, listez les dépendances :beautifulsoup4==4.14.3 requests==2.34.1 lxml python-dotenv. Dans.env, définissezTARGET_URL=https://books.toscrape.com(site d’entraînement officiel pour le scraping),OUTPUT_DIR=./output,DELAY_SECONDS=1(délai entre les requêtes), etUSER_AGENT=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36. Le délai d’une seconde minimum est une bonne pratique pour ne pas surcharger le serveur cible. Le User-Agent personnalisé évite que Requests envoiepython-requests/2.34.1qui est souvent bloqué par les filtres anti-bot. Créez le dossier de sortie :mkdir -p output. Chargez les variables dans votre script avecfrom dotenv import load_dotenv; load_dotenv()— cela lit automatiquement le fichier.envet les expose viaos.environ. Ajoutez.envau fichier.gitignorepour ne jamais committer vos variables de configuration.Étape 3 — Construire le scraper avec les fonctions principales
Écrivezscraper.pyavec trois fonctions :fetch_page(url)qui télécharge la page HTML avecrequests.get(url, headers=HEADERS, timeout=10)et retourneBeautifulSoup(response.content, "lxml")— utilisez.content(bytes) pas.textpour éviter les problèmes d’encodage.extract_books(soup)qui parcourt les éléments avecsoup.find_all("article", class_="product_pod")et extrait titre (article.h3.a["title"]), prix (article.find("p", class_="price_color").get_text(strip=True)) et lien (article.h3.a["href"]).save_to_csv(data, filename)qui écrit les résultats en CSV aveccsv.DictWriter. La fonctionmain()appelle les trois en séquence. Appelezresponse.raise_for_status()après chaquerequests.get()pour attraper les erreurs 404/500 immédiatement. Ajoutez un en-têteAccept-Language: fr-FR,fr;q=0.9dans vosHEADERSpour obtenir le contenu en français quand le site propose plusieurs langues. Utiliseztime.sleep(float(os.getenv("DELAY_SECONDS", 1)))entre chaque requête pour respecter le serveur cible.Étape 4 — Tester, debugger et gérer les erreurs courantes
Exécutezpython scraper.pyet vérifiez que le fichieroutput/books.csvcontient 20 lignes de données. Les 3 erreurs les plus fréquentes et leurs solutions :AttributeError: 'NoneType' object has no attribute 'text'→ le sélecteur CSS ne trouve pas l’élément, ouvrez la page dans votre navigateur et vérifiez la classe avec Inspecter (clic droit → Inspecter l’élément).requests.exceptions.ConnectionError→ vérifiez votre connexion internet et l’URL dans.env.UnicodeDecodeError→ vous avez utiliséresponse.textau lieu deresponse.content— corrigez en passantresponse.contentà BeautifulSoup. Ajoutez untry/exceptautour defetch_page:try: soup = fetch_page(url) except requests.HTTPError as e: print(f"Erreur HTTP : {e}"); return []. Pour déboguer le HTML reçu, enregistrez-le dans un fichier :with open('debug.html', 'w') as f: f.write(soup.prettify()). Vérifiez le nombre de résultats extraits avecprint(f"Books trouvés : {len(books)}")— si le nombre est 0, le sélecteur CSS est probablement incorrect.Étape 5 — Déployer en production et maintenir le scraper
Pour automatiser l'exécution quotidienne, ajoutez une entrée cron :crontab -epuis0 6 * * * cd /chemin/vers/scraper-project && /chemin/vers/scraper-env/bin/python scraper.py >> scraper.log 2>&1. Pour déployer en Docker, créez unDockerfileavecFROM python:3.12-slim, copiez les fichiers et lancezdocker build -t scraper . && docker run --rm -v /Users/user/Documents/guidepratiquefr/guidepratiquefr/output:/app/output scraper. Pour surveiller votre scraper en production, ajoutez un logging basique :import logging; logging.basicConfig(filename='scraper.log', level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s'). Pour mettre à jour BeautifulSoup :pip install --upgrade beautifulsoup4. Vérifiez la version avecpip show beautifulsoup4. Les sites changent leur structure HTML — testez votre scraper chaque semaine avecpython -m pytest tests/.
Conseils pratiques
- Utilisez
soup.find_all(string=lambda text: "python" in text.lower())pour une recherche insensible à la casse —string="Python"ne matche que la casse exacte. - Ajoutez
timeout=10à chaquerequests.get()pour éviter que votre script ne reste bloqué indéfiniment sur un serveur qui ne répond pas. - Utilisez
soup.prettify()pour afficher le HTML indenté et trouver plus facilement les bons sélecteurs CSS lors du développement.
Points d'attention
AttributeError: 'NoneType' object has no attribute 'text'→ votre sélecteur CSS ne trouve pas l'élément. Ouvrez la page dans le navigateur, clic droit → Inspecter, et vérifiez que la classe/le tag correspond exactement.requests.exceptions.HTTPError: 403 Client Error→ le site bloque votre User-Agent. Remplacez la valeur par défaut de Requests par un User-Agent de navigateur réel dans le headerHEADERS.- Scrapper un site sans vérifier ses Conditions Générales d'Utilisation peut être illégal. Vérifiez le fichier
robots.txtà la racine du site (ex :example.com/robots.txt) et respectez les directivesDisallow.
Questions fréquentes5
BeautifulSoup fonctionne-t-il sans GPU ?
Oui. BeautifulSoup est une bibliothèque Python pure qui parse du HTML en mémoire CPU. Aucun GPU nest nécessaire. 4 Go de RAM suffisent pour parser des pages de plusieurs mégaoctets.
Quelle version de Python est nécessaire pour BeautifulSoup 4.14.3 ?
Python 3.7 minimum. Python 3.10+ est recommandé pour les type hints et le pattern matching. La version 4.9.3 était la dernière à supporter Python 2.7.
BeautifulSoup est-il gratuit et open-source ?
Oui. BeautifulSoup est sous licence MIT depuis la version 4.0. Vous pouvez lutiliser gratuitement pour tout projet personnel ou commercial. Le support professionnel est disponible via Tidelift.
Comment debugger si BeautifulSoup ne trouve pas un élément ?
print(soup.prettify()) pour voir le HTML indenté. Vérifiez que la classe CSS correspond exactement — les espaces comptent (class_="price color" ≠ class_="price_color"). Si la page utilise du JavaScript pour afficher le contenu, Requests ne verra que le HTML initial — utilisez Selenium à la place.BeautifulSoup vs Scrapy : lequel choisir ?
BeautifulSoup est idéal pour scraper 1 à 10 pages rapidement avec un script simple. Scrapy est un framework complet pour des projets de grande envergure (des milliers de pages, pipelines, middleware). Commencez par BeautifulSoup si votre besoin est ponctuel — migrez vers Scrapy quand vous avez besoin de parallélisme, de filtres middleware ou dexport automatique vers une base de données.
Guides Technologie & IA
Voir toutConstruire un chatbot local avec Ollama et Python en 30 minutes
Utiliser DeepSeek V4 en 2026 pour améliorer la recherche
Utiliser Claude Opus 4.7 en 2026 pour améliorer la productivité
Comment créer et gérer ses mots de passe de manière sécurisée en 2026
Reconnaître un deepfake en 2026 — Comment ça marche
Poursuivez votre lecture
Multi-catégories"Impôts du Cœur" : les agents des finances publiques proposent leur aide à la déclaration de revenus sur le marché
Comment refuser un loyer supérieur à 30 % du revenu en 2026 ?
Construire un agent IA autonome avec CrewAI et Python en 2026
Protéger vos données personnelles en ligne en 2026 — conseils pratiques
Comment créer et utiliser son identité numérique avec FranceConnect en 2026
Transmission d'entreprise 2026 : dispositifs fiscaux et étapes clés pour vendre ou céder son affaire
Équipe éditoriale GuidePratiquefr
Rédacteurs spécialisés en droit, fiscalité et finances
Rédigé et vérifié par notre équipe de rédacteurs spécialisés. Sources officielles consultées : service-public.fr, legifrance.gouv.fr, impots.gouv.fr, ameli.fr. Dernière vérification : 14 mai 2026.
Sources officielles consultées
Les informations contenues dans ce guide sont fournies à titre indicatif et ne remplacent pas un conseil professionnel personnalisé.