Table of Contents
Introduction
Que ce soit pour une sauvegarde locale, un accès hors ligne, une migration vers un autre CMS ou une veille concurrentielle, aspirer un site web est une tâche essentielle en web scraping. L’objectif est de récupérer l’intégralité des pages HTML, les images, les fichiers multimédias et les documents liés, tout en préservant l’arborescence du site.
Dans ce guide, nous verrons comment aspirer n’importe quel site web en Python en utilisant Selenium, Requests, BeautifulSoup, et en optimisant la gestion des ressources.
Pourquoi Aspirer un Site Web ?
✔ Archivage : Conserver une copie statique d’un site web 📂
✔ Consultation hors ligne : Accéder au contenu sans connexion Internet 🚀
✔ Migration vers un autre CMS : Récupérer toutes les pages et fichiers 📦
✔ Sauvegarde de documentation : Garder des copies locales pour référence 📜
✔ Scraping d’informations : Extraire des données pertinentes pour analyse 📊
1️⃣ Pré-requis Techniques
Avant de commencer, assurez-vous d’avoir installé les outils nécessaires :
pip install selenium requests beautifulsoup4
Vous aurez également besoin de :
- Google Chrome et ChromeDriver (pour Selenium)
- Un accès au site web cible, avec ou sans authentification
2️⃣ Configuration du Script
Nous allons configurer notre script pour récupérer l’ensemble du site, en téléchargeant les pages HTML, les fichiers multimédias et les documents liés.
import logging
import os
import time
import requests
import re
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.chrome.service import Service
from urllib.parse import urlparse, unquote, parse_qs, urljoin
from bs4 import BeautifulSoup
# Configuration du site à aspirer
SITE_URL = "https://example.com"
LOGIN_URL = "https://example.com/login"
USERNAME = "your_username"
PASSWORD = "your_password"
OUTPUT_FOLDER = "./site_mirror"
3️⃣ Lancement du Navigateur et Authentification (Si Nécessaire)
Selenium nous permet d’interagir avec des sites protégés par un login.
def setup_browser():
"""Initialisation de Selenium avec Chrome en mode headless."""
logging.info("Configuration du navigateur...")
options = webdriver.ChromeOptions()
options.add_argument("--headless")
options.add_argument("--no-sandbox")
options.add_argument("--disable-dev-shm-usage")
options.add_argument("--window-size=1920,1080")
service = Service("/usr/bin/chromedriver")
return webdriver.Chrome(service=service, options=options)
def login_to_site(browser):
"""Connexion au site via Selenium."""
browser.get(LOGIN_URL)
WebDriverWait(browser, 10).until(EC.presence_of_element_located((By.NAME, "username")))
browser.find_element(By.NAME, "username").send_keys(USERNAME)
browser.find_element(By.NAME, "password").send_keys(PASSWORD)
browser.find_element(By.NAME, "password").submit()
time.sleep(2)
logging.info("Connexion réussie.")
4️⃣ Capturer les Cookies pour Requests
Selenium permet l’authentification, mais Requests est plus rapide pour le téléchargement des ressources.
def capture_cookies(browser):
"""Extrait les cookies de Selenium et les transmet à Requests."""
cookies = browser.get_cookies()
session_cookies = {cookie['name']: cookie['value'] for cookie in cookies}
logging.info("Cookies capturés : %s", session_cookies)
return session_cookies
5️⃣ Création d’une Arborescence Basée sur l’URL
Nous devons recréer la structure des pages web localement.
def generate_local_path(url, output_folder):
"""Crée un chemin de fichier basé sur l’URL."""
parsed_url = urlparse(url)
path = unquote(parsed_url.path.strip("/"))
if not path or path.endswith("/"):
path = os.path.join(path, "index.html")
else:
path += ".html"
local_path = os.path.join(output_folder, path)
os.makedirs(os.path.dirname(local_path), exist_ok=True)
return local_path
6️⃣ Exporter et Sauvegarder les Pages
Nous utilisons BeautifulSoup pour récupérer un HTML propre.
def save_page(browser, url, output_folder):
"""Télécharge et sauvegarde une page HTML."""
browser.get(url)
time.sleep(2)
file_path = generate_local_path(url, output_folder)
with open(file_path, "w", encoding="utf-8") as f:
f.write(browser.page_source)
logging.info("Page exportée : %s", file_path)
return file_path
7️⃣ Télécharger les Ressources (Images, PDF, etc.)
Nous devons modifier les liens dans les pages HTML pour pointer vers des fichiers locaux.
def download_resources(browser, html_content, output_folder, base_url, file_path):
"""Télécharge toutes les ressources liées (images, fichiers)."""
soup = BeautifulSoup(html_content, "html.parser")
cookies = capture_cookies(browser)
for img in soup.find_all("img"):
img_url = urljoin(base_url, img["src"])
local_path = download_file_with_cookies(img_url, cookies, output_folder, "media/images")
if local_path:
img["src"] = os.path.relpath(local_path, os.path.dirname(file_path))
for link in soup.find_all("a"):
href = link.get("href")
if href and href.startswith("/") and (".pdf" in href or ".docx" in href):
file_url = urljoin(base_url, href)
local_path = download_file_with_cookies(file_url, cookies, output_folder, "documents")
if local_path:
link["href"] = os.path.relpath(local_path, os.path.dirname(file_path))
with open(file_path, "w", encoding="utf-8") as f:
f.write(str(soup))
logging.info("Ressources liées téléchargées et mises à jour.")
8️⃣ Exploration Récursive du Site
Nous allons parcourir toutes les pages et les enregistrer.
def crawl_site(browser, start_url, output_folder):
"""Parcourt toutes les pages du site et les télécharge."""
visited = set()
to_visit = [start_url]
while to_visit:
url = to_visit.pop(0)
if url in visited:
continue
file_path = save_page(browser, url, output_folder)
visited.add(url)
soup = BeautifulSoup(browser.page_source, "html.parser")
for link in soup.find_all("a"):
href = link.get("href")
if href and href.startswith("/") and href not in visited:
to_visit.append(urljoin(SITE_URL, href))
logging.info("Exploration terminée.")
🔹 Exécuter le Script
if __name__ == "__main__":
logging.basicConfig(level=logging.INFO)
browser = setup_browser()
login_to_site(browser)
crawl_site(browser, SITE_URL, OUTPUT_FOLDER)
browser.quit()
Conclusion
✅ Aspirer un site web complet est possible avec Python et Selenium.
✅ Ce script garde l’arborescence et télécharge toutes les ressources liées.
✅ Vous obtenez un export propre et structuré en HTML.
🚀 Améliorations possibles ? Ajouter le support pour des sites JavaScript-heavy (via Playwright) ou exporter en PDF !
💡 Si ce guide vous a aidé, partagez-le et optimisez votre scraping ! 🎯