Le web scraping a longtemps été un exercice de patience : inspecter le HTML, écrire des sélecteurs CSS fragiles, gérer les pages dynamiques en JavaScript, et tout recommencer quand le site change sa structure. L'IA change complètement la donne. Au lieu de parser du HTML, on peut maintenant comprendre la page et en extraire les informations de manière intelligente.
Dans ce guide, on explore le scraping assisté par IA : comment ça marche, quels outils utiliser, des exemples concrets, et les considérations éthiques et légales à connaître.
🔄 Scraping classique vs scraping IA
Le scraping classique : fragile et laborieux
Le scraping traditionnel repose sur l'analyse de la structure HTML :
# Scraping classique avec BeautifulSoup
import requests
from bs4 import BeautifulSoup
response = requests.get("https://example.com/produits")
soup = BeautifulSoup(response.text, "html.parser")
produits = []
for card in soup.select("div.product-card"):
nom = card.select_one("h3.product-title").text.strip()
prix = card.select_one("span.price").text.strip()
produits.append({"nom": nom, "prix": prix})
# ❌ Problèmes :
# - Si le site change "div.product-card" → tout casse
# - Pages JavaScript → requests ne suffit pas
# - Données dans des formats variés → regex fragiles
# - Anti-bot → headers, cookies, captchas
Le scraping IA : comprendre au lieu de parser
Le scraping IA utilise un LLM pour comprendre le contenu de la page, pas sa structure HTML :
# Scraping IA : le LLM comprend la page
from openai import OpenAI
client = OpenAI()
# On récupère le texte de la page (pas besoin de parser le HTML)
page_content = fetch_page_as_text("https://example.com/produits")
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[
{"role": "system", "content": """Extrais tous les produits
de cette page. Pour chaque produit, donne :
- nom, prix, description, disponibilité
Réponds en JSON."""},
{"role": "user", "content": page_content}
],
response_format={"type": "json_object"}
)
produits = json.loads(response.choices[0].message.content)
# ✅ Fonctionne même si la structure HTML change
# ✅ Comprend le contexte ("en rupture", "promo -30%")
# ✅ Extrait des infos implicites
Comparaison détaillée
| Aspect | Scraping classique | Scraping IA |
|---|---|---|
| Robustesse | ⭐⭐ Casse si le HTML change | ⭐⭐⭐⭐⭐ Comprend le contenu |
| Vitesse | ⭐⭐⭐⭐⭐ Très rapide | ⭐⭐⭐ Plus lent (appel LLM) |
| Coût | ⭐⭐⭐⭐⭐ Quasi gratuit | ⭐⭐⭐ Coût API LLM |
| Précision | ⭐⭐⭐⭐ Si bien codé | ⭐⭐⭐⭐ Très bon sur données textuelles |
| Données structurées | ⭐⭐⭐ Demande du travail | ⭐⭐⭐⭐⭐ JSON natif |
| Setup | ⭐⭐ Lent (sélecteurs, debug) | ⭐⭐⭐⭐⭐ Rapide (prompt + go) |
| Maintenance | ⭐⭐ Casse régulièrement | ⭐⭐⭐⭐ Rarement besoin de MAJ |
| Volume | ⭐⭐⭐⭐⭐ Millions de pages | ⭐⭐⭐ Limité par coûts/rate limits |
💡 La meilleure approche : combiner les deux. Utilisez le scraping classique pour récupérer le contenu brut rapidement, puis l'IA pour l'extraire et le structurer intelligemment.
🛠️ Les outils du scraping IA
1. web_fetch + LLM : la méthode simple
La méthode la plus directe : récupérer le contenu d'une page en texte/markdown, puis le faire analyser par un LLM.
import httpx
from openai import OpenAI
client = OpenAI()
# Étape 1 : Récupérer la page en texte lisible
# (en utilisant un service comme Jina Reader ou un extracteur markdown)
response = httpx.get(
"https://r.jina.ai/https://example.com/article",
headers={"Accept": "text/markdown"}
)
page_markdown = response.text
# Étape 2 : Extraire les données avec le LLM
extraction = client.chat.completions.create(
model="gpt-4o-mini",
messages=[
{"role": "system", "content": """Tu es un extracteur de données.
Extrais les informations demandées au format JSON.
Si une info n'est pas trouvée, mets null."""},
{"role": "user", "content": f"""Page web :
{page_markdown}
Extrais : titre, auteur, date, résumé (2 phrases), tags"""}
]
)
print(extraction.choices[0].message.content)
Si vous utilisez OpenClaw, l'outil web_fetch est intégré nativement :
# OpenClaw peut directement fetch + analyser
# L'agent utilise web_fetch puis le LLM pour structurer
User: "Récupère les 5 derniers articles de TechCrunch sur l'IA"
# → OpenClaw fetch la page, extrait, structure en JSON
2. Browser automation + IA : pour les sites dynamiques
Pour les sites qui nécessitent JavaScript, scroll, clics, ou authentification :
from playwright.sync_api import sync_playwright
from openai import OpenAI
client = OpenAI()
with sync_playwright() as p:
browser = p.chromium.launch(headless=True)
page = browser.new_page()
# Navigation comme un humain
page.goto("https://example.com/search")
page.fill("#search-input", "intelligence artificielle")
page.click("button[type=submit]")
page.wait_for_selector(".results")
# Scroll pour charger plus de résultats
for _ in range(3):
page.evaluate("window.scrollTo(0, document.body.scrollHeight)")
page.wait_for_timeout(2000)
# Récupérer le contenu visible
content = page.inner_text("body")
# IA pour extraire les données structurées
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[
{"role": "system", "content": """Extrais tous les résultats
de recherche. Format JSON : [{title, url, snippet, date}]"""},
{"role": "user", "content": content}
]
)
browser.close()
OpenClaw intègre un browser automation complet qui peut naviguer, cliquer, remplir des formulaires et extraire des données automatiquement :
# OpenClaw browser automation
# L'agent peut contrôler un navigateur + comprendre les pages
User: "Va sur LinkedIn, cherche les profils 'data engineer Paris'"
# → OpenClaw ouvre le browser, navigue, extrait les profils
3. API + LLM : la méthode propre
Avant de scraper, vérifiez toujours s'il existe une API ! Beaucoup de sites en proposent :
# Méthode propre : API + LLM pour structurer
import httpx
from openai import OpenAI
client = OpenAI()
# API publique (exemple : Hacker News)
stories = httpx.get(
"https://hacker-news.firebaseio.com/v0/topstories.json"
).json()[:10]
articles = []
for story_id in stories:
story = httpx.get(
f"https://hacker-news.firebaseio.com/v0/item/{story_id}.json"
).json()
articles.append(story)
# LLM pour analyser et catégoriser
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[
{"role": "system", "content": """Analyse ces articles tech.
Pour chacun, ajoute : catégorie (IA, web, hardware, autre),
pertinence (1-10), résumé en 1 phrase."""},
{"role": "user", "content": json.dumps(articles, indent=2)}
]
)
4. Vision models : scraper des images et captures d'écran
Les modèles vision peuvent « lire » des captures d'écran — utile pour les sites très visuels ou anti-scraping :
import base64
from openai import OpenAI
from playwright.sync_api import sync_playwright
client = OpenAI()
# Capture d'écran de la page
with sync_playwright() as p:
browser = p.chromium.launch()
page = browser.new_page()
page.goto("https://example.com/dashboard")
screenshot = page.screenshot() # bytes PNG
browser.close()
# Envoyer au modèle vision
b64_image = base64.b64encode(screenshot).decode()
response = client.chat.completions.create(
model="gpt-4o",
messages=[{
"role": "user",
"content": [
{"type": "text", "text": "Extrais toutes les données "
"de ce dashboard : métriques, graphiques, tableaux. "
"Format JSON structuré."},
{"type": "image_url", "image_url": {
"url": f"data:image/png;base64,{b64_image}"
}}
]
}]
)
📋 Exemples concrets
Exemple 1 : Veille concurrentielle
Surveillez automatiquement les prix et offres de vos concurrents :
import json
import httpx
from openai import OpenAI
from datetime import datetime
client = OpenAI()
CONCURRENTS = [
{"nom": "Concurrent A", "url": "https://concurrent-a.com/pricing"},
{"nom": "Concurrent B", "url": "https://concurrent-b.com/tarifs"},
{"nom": "Concurrent C", "url": "https://concurrent-c.com/plans"},
]
Pour aller plus loin sur ce sujet, consultez notre guide [Cron + IA : automatiser des tâches intelligentes 24/7](/article/cron-ia-automatiser-taches-intelligentes).
def analyser_pricing(nom: str, url: str) -> dict:
"""Scrape et analyse la page pricing d'un concurrent."""
# Récupérer le contenu
resp = httpx.get(f"https://r.jina.ai/{url}")
# Extraction IA
analysis = client.chat.completions.create(
model="gpt-4o-mini",
messages=[
{"role": "system", "content": """Analyse cette page pricing.
Extrais au format JSON :
{
"plans": [{"nom": str, "prix_mensuel": float,
"prix_annuel": float, "features": [str]}],
"offre_speciale": str ou null,
"essai_gratuit": bool,
"changements_notables": str ou null
}"""},
{"role": "user", "content": resp.text[:8000]}
]
)
result = json.loads(analysis.choices[0].message.content)
result["concurrent"] = nom
result["date_analyse"] = datetime.now().isoformat()
return result
Pour aller plus loin sur ce sujet, consultez notre guide [Générer du contenu automatiquement avec l'IA](/article/generer-contenu-automatiquement-ia).
# Lancer l'analyse
rapport = [analyser_pricing(c["nom"], c["url"]) for c in CONCURRENTS]
# Sauvegarder
with open(f"veille_{datetime.now():%Y-%m-%d}.json", "w") as f:
json.dump(rapport, f, indent=2, ensure_ascii=False)
Exemple 2 : Agrégation d'actualités
Créez votre propre flux d'actualités IA personnalisé :
import feedparser
from openai import OpenAI
client = OpenAI()
SOURCES = [
"https://techcrunch.com/feed/",
"https://www.theverge.com/rss/index.xml",
"https://feeds.arstechnica.com/arstechnica/index",
]
def agreger_actualites(sujet: str = "intelligence artificielle"):
articles = []
for feed_url in SOURCES:
feed = feedparser.parse(feed_url)
for entry in feed.entries[:10]:
articles.append({
"titre": entry.title,
"lien": entry.link,
"source": feed.feed.title,
"date": entry.get("published", ""),
"resume": entry.get("summary", "")[:500]
})
# Filtrage et analyse par IA
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[
{"role": "system", "content": f"""Tu es un curateur d'actualités.
Parmi les articles suivants, sélectionne ceux qui concernent
"{sujet}". Pour chaque article retenu :
- Résumé en 2 phrases en français
- Score de pertinence (1-10)
- Tags (3 max)
Trie par pertinence décroissante. Format JSON."""},
{"role": "user", "content": json.dumps(articles, ensure_ascii=False)}
]
)
return json.loads(response.choices[0].message.content)
# Utilisation
news = agreger_actualites("intelligence artificielle")
for article in news[:5]:
print(f"📰 {article['titre']}")
print(f" {article['resume']}")
print(f" Pertinence: {article['score']}/10")
print()
Exemple 3 : Monitoring de prix
Surveillez les prix de produits et recevez des alertes :
import json
import sqlite3
from datetime import datetime
import httpx
from openai import OpenAI
client = OpenAI()
def surveiller_prix(url: str, produit: str) -> dict:
"""Récupère et analyse le prix d'un produit."""
resp = httpx.get(f"https://r.jina.ai/{url}")
extraction = client.chat.completions.create(
model="gpt-4o-mini",
messages=[
{"role": "system", "content": """Extrais les informations
de prix de cette page produit. Format JSON :
{
"prix_actuel": float,
"prix_barre": float ou null,
"devise": "EUR",
"en_stock": bool,
"promotion": str ou null,
"vendeur": str
}"""},
{"role": "user", "content": f"Produit recherché: {produit}"
f"\n\nPage:\n{resp.text[:6000]}"}
]
)
data = json.loads(extraction.choices[0].message.content)
data["url"] = url
data["produit"] = produit
data["timestamp"] = datetime.now().isoformat()
return data
def verifier_alerte(prix_actuel: float, prix_cible: float) -> bool:
"""Vérifie si le prix est passé sous le seuil."""
return prix_actuel <= prix_cible
# Exemple d'utilisation
produits_suivis = [
{"url": "https://amazon.fr/dp/XXXXX", "nom": "GPU RTX 5080", "prix_cible": 900},
{"url": "https://fnac.com/a123456", "nom": "MacBook Air M4", "prix_cible": 1100},
]
for produit in produits_suivis:
data = surveiller_prix(produit["url"], produit["nom"])
if verifier_alerte(data["prix_actuel"], produit["prix_cible"]):
print(f"🚨 ALERTE: {produit['nom']} à {data['prix_actuel']}€ "
f"(cible: {produit['prix_cible']}€)")
🔄 Automatiser le scraping avec OpenClaw
OpenClaw est particulièrement puissant pour le scraping IA car il combine nativement :
- web_fetch : récupération de pages en markdown
- Browser automation : navigation complète (JS, clics, formulaires)
- LLM intégré : analyse et extraction automatique
- Cron jobs : exécution planifiée
# Exemple : veille automatique quotidienne avec OpenClaw
# L'agent peut être configuré pour :
# 1. Chaque matin à 8h, scraper vos sources
# 2. Extraire et catégoriser les informations
# 3. Vous envoyer un résumé par Telegram/Discord
# Configuration cron dans OpenClaw
# Voir : configurer les tâches planifiées
Pour mettre en place ce type d'automatisation, consultez :
- Installer OpenClaw sur un VPS pour un agent toujours actif
- Configurer OpenClaw pour paramétrer les tâches automatiques
- Automatiser sa vie avec l'IA pour d'autres idées d'automatisation
⚖️ Éthique et légalité du scraping
Le cadre légal
Le scraping n'est ni totalement légal ni totalement illégal. Ça dépend de plusieurs facteurs :
| Facteur | Légal ✅ | Risqué ⚠️ | Illégal ❌ |
|---|---|---|---|
| Données | Publiques, non personnelles | Publiques mais personnelles | Privées, derrière login |
| Usage | Recherche, usage personnel | Commercial, agrégation | Revente, spam |
| Volume | Raisonnable | Intensif | DoS / surcharge serveur |
| robots.txt | Respecté | Partiellement respecté | Ignoré |
| CGU du site | Conformes | Zone grise | Violation explicite |
| Région | Variable | RGPD (données perso) | CFAA (USA, accès non autorisé) |
Les règles d'or du scraping éthique
# Bonnes pratiques de scraping éthique
import time
import httpx
class EthicalScraper:
def __init__(self, delay: float = 2.0):
self.delay = delay
self.session = httpx.Client(
headers={
# 1. S'identifier clairement
"User-Agent": "MonBot/1.0 ([email protected]; "
"recherche académique)",
},
timeout=30,
follow_redirects=True,
)
def respecte_robots_txt(self, url: str) -> bool:
"""Vérifie robots.txt avant de scraper."""
from urllib.robotparser import RobotFileParser
from urllib.parse import urlparse
parsed = urlparse(url)
robots_url = f"{parsed.scheme}://{parsed.netloc}/robots.txt"
rp = RobotFileParser()
rp.set_url(robots_url)
rp.read()
return rp.can_fetch("MonBot", url)
def fetch(self, url: str) -> str | None:
# 2. Respecter robots.txt
if not self.respecte_robots_txt(url):
print(f"⛔ Bloqué par robots.txt : {url}")
return None
# 3. Rate limiting (ne pas surcharger)
time.sleep(self.delay)
response = self.session.get(url)
# 4. Respecter les codes HTTP
if response.status_code == 429: # Too Many Requests
print("⏳ Rate limited, attente...")
time.sleep(60)
return self.fetch(url)
if response.status_code != 200:
return None
return response.text
Checklist avant de scraper
# ✅ Checklist scraping éthique
☐ Vérifié robots.txt du site
☐ Lu les CGU / ToS du site
☐ Pas de données personnelles (ou RGPD respecté)
☐ Rate limiting implémenté (min 1-2 sec entre requêtes)
☐ User-Agent identifiant avec contact
☐ API officielle vérifiée (préférer si disponible)
☐ Usage légitime (recherche, veille, pas de revente)
☐ Pas de contournement de protection (captcha, login)
☐ Stockage sécurisé des données collectées
☐ Politique de rétention définie (pas de stockage infini)
RGPD et données personnelles
Si vous scrapez des données contenant des informations personnelles (noms, emails, photos...) en Europe, le RGPD s'applique :
- Base légale nécessaire (intérêt légitime, consentement...)
- Droit à l'effacement : les personnes peuvent demander la suppression
- Minimisation : ne collectez que ce qui est nécessaire
- Sécurité : protégez les données collectées
- DPO : désignez un responsable si traitement à grande échelle
Alternatives au scraping
Avant de scraper, explorez ces alternatives :
| Alternative | Avantage |
|---|---|
| API officielle | Légal, structuré, stable |
| Datasets publics | Prêt à l'emploi, souvent gratuit |
| Partenariats data | Accès légal à des données premium |
| RSS/Atom feeds | Flux d'actualités structurés |
| Common Crawl | Archive web ouverte (pétaoctets) |
| Data marketplaces | Données pré-scrapées, légales |
🚀 Architecture d'un système de scraping IA
Pour un projet de scraping IA en production, voici l'architecture recommandée :
┌──────────────────────────────────────────────────┐
│ ORCHESTRATEUR │
│ (Cron / OpenClaw / Airflow) │
└──────────────┬───────────────────┬───────────────┘
│ │
┌───────▼───────┐ ┌──────▼────────┐
│ COLLECTE │ │ COLLECTE │
│ (web_fetch) │ │ (browser) │
│ Sites simples│ │ Sites JS/SPA │
└───────┬───────┘ └──────┬────────┘
│ │
└─────────┬─────────┘
│ HTML/Markdown brut
┌────────▼────────┐
│ EXTRACTION │
│ (LLM / GPT-4o │
│ mini) │
└────────┬────────┘
│ JSON structuré
┌────────▼────────┐
│ STOCKAGE │
│ (PostgreSQL / │
│ SQLite) │
└────────┬────────┘
│
┌──────────┼──────────┐
│ │ │
┌──────▼──┐ ┌────▼────┐ ┌──▼───────┐
│ ALERTES │ │ ANALYSE │ │ DASHBOARD│
│ (email, │ │ (trends,│ │ (Grafana,│
│ Telegram)│ │ LLM) │ │ custom) │
└─────────┘ └─────────┘ └──────────┘
Estimation des coûts
| Composant | Volume | Coût mensuel |
|---|---|---|
| web_fetch (100 pages/jour) | 3 000 pages/mois | ~$0 (self-hosted) |
| LLM extraction (GPT-4o mini) | 3 000 appels × 2K tokens | ~$1.50 |
| Browser automation (si nécessaire) | Serveur + Playwright | ~$5-10 |
| Stockage (SQLite/PostgreSQL) | < 1 GB | ~$0 |
| Total | ~$5-15/mois |
Pour un monitoring de prix sur 50 produits, 3 fois par jour, le coût IA est d'environ $5/mois — bien moins qu'un abonnement à un service de monitoring commercial.
🎯 Résumé et bonnes pratiques
| Principe | Détail |
|---|---|
| Commencez simple | web_fetch + LLM avant le browser automation |
| API d'abord | Cherchez toujours une API officielle avant de scraper |
| Modèle économique | GPT-4o mini ou Haiku pour l'extraction (pas besoin d'Opus) |
| Rate limiting | Minimum 1-2 secondes entre les requêtes |
| robots.txt | Toujours respecter, c'est la base |
| Structured output | Demandez du JSON pour des données propres |
| Monitoring | Surveillez vos coûts et la qualité d'extraction |
| Éthique | Si vous ne voudriez pas qu'on le fasse sur votre site, ne le faites pas |
Le scraping IA rend accessible à tous ce qui nécessitait auparavant des développeurs spécialisés. Avec un LLM et quelques lignes de code, vous pouvez extraire, structurer et analyser des données web de manière fiable et maintenable.
Mais n'oubliez pas : avec un grand pouvoir vient une grande responsabilité. Scrapez de manière éthique, respectez les sites et les données personnelles, et privilégiez toujours les API officielles quand elles existent.
📚 Articles liés
- Qu'est-ce qu'OpenClaw ? — L'agent IA avec web_fetch et browser automation intégrés
- Automatiser sa vie avec l'IA — Combinez le scraping avec d'autres automatisations
- Installer OpenClaw sur un VPS — Hébergez votre scraper IA 24/7
- Configurer OpenClaw — Paramétrer les cron jobs pour le scraping automatique
- Sécuriser OpenClaw — Protéger votre infrastructure de scraping
- OpenRouter — Optimiser les coûts LLM de votre pipeline de scraping