Le web scraping avec ChatGPT a discrètement transformé la façon dont une grande partie du code d'extraction s'écrit. L'ancienne méthode était fragile : inspecter une page, écrire manuellement des sélecteurs CSS et les réécrire à chaque fois que le site publiait un nouveau balisage. La nouvelle méthode s'appuie sur le modèle. Vous récupérez une copie propre de la page, vous la transmettez à un modèle OpenAI et vous demandez les champs souhaités sous forme de JSON structuré. Les sélecteurs se trouvent dans votre prompt plutôt que dans votre code, et ils résistent aux changements de mise en page qui auraient cassé un parseur codé en dur.
Il y a une mise en garde honnête que le marketing a tendance à omettre : ChatGPT ne peut pas récupérer la page à votre place. Il n'a pas de navigateur fiable, il se fait bloquer comme n'importe quel autre client, et lui demander une URL en direct retourne souvent une hallucination convaincante plutôt que des données réelles. Ce guide divise donc clairement le travail. Crawlbase se charge de la récupération et du rendu derrière une IP de confiance, le modèle OpenAI s'occupe de la compréhension, et Python assemble les deux. Tout ce qui suit est exécutable, limité aux pages publiques et conçu pour gérer les pages trop grandes pour être envoyées au modèle en une seule fois.
Comment fonctionne réellement le web scraping avec ChatGPT
Il est utile d'être précis sur ce que fait chaque outil, car les confondre est l'erreur que commettent la plupart des tutoriels. Un modèle de langage est une couche de raisonnement, pas un client réseau. Donnez-lui du texte propre et il est excellent pour extraire des champs structurés de contenu désordonné. Demandez-lui d'aller chercher ce contenu lui-même et il échoue : pas de moteur de rendu, pas de pool de proxies, pas de gestion des CAPTCHAs, et une forte tendance à inventer des valeurs plausibles lorsqu'il ne peut pas charger la page.
Un pipeline fonctionnel comporte donc trois étapes. D'abord, récupérer et rendre la cible avec la Crawling API, qui exécute la page dans un vrai navigateur derrière des IPs résidentielles rotatives et retourne le HTML finalisé. Ensuite, réduire ce HTML à quelque chose de compact, soit du texte dépouillé, soit du markdown, pour ne pas payer à envoyer des balises de navigation et de script au modèle. Enfin, demander à un modèle OpenAI de lire ce contenu et de retourner du JSON correspondant à un schéma que vous définissez. Le modèle ne touche jamais au réseau ; il lit seulement ce que vous lui fournissez.
Gardez ces responsabilités séparées. Crawlbase est ce qui charge la page, rend le JavaScript et passe les blocages. Le modèle OpenAI ne récupère rien : il lit seulement le HTML ou le markdown que vous lui transmettez et retourne des données structurées. Si vous demandez directement à ChatGPT une URL en direct, il ne peut pas la charger de manière fiable et peut en fabriquer la réponse.
Ce dont vous avez besoin avant de commencer
Il s'agit d'une construction de niveau débutant à intermédiaire. Vous avez besoin de Python 3.9 ou supérieur, d'un compte Crawlbase pour un token normal et un token JavaScript, et d'une clé API OpenAI. Le niveau gratuit de Crawlbase couvre largement assez de requêtes pour suivre ce guide, et les appels au modèle ici utilisent un modèle petit et peu coûteux. Définissez les deux secrets comme variables d'environnement plutôt que de les coller dans le script.
python --version mkdir chatgpt-scraper && cd chatgpt-scraper pip install crawlbase openai beautifulsoup4 html2text export CRAWLBASE_TOKEN="your_normal_token" export CRAWLBASE_JS_TOKEN="your_javascript_token" export OPENAI_API_KEY="your_openai_key"
Quatre bibliothèques font le travail. crawlbase est le client pour la Crawling API, openai est le SDK officiel pour les appels au modèle, beautifulsoup4 réduit une page rendue à du texte lisible, et html2text convertit le HTML en markdown lorsque vous souhaitez que le modèle voie la structure comme les titres et les tableaux. Vous n'aurez pas toujours besoin des deux, BeautifulSoup et html2text ; choisissez la représentation qui convient le mieux à la page.
Étape 1 : Récupérer la page rendue avec la Crawling API
Commencez par obtenir une copie propre de la page. Utilisez le token JavaScript pour tout site qui rend le contenu côté client, ce qui représente la plupart des pages modernes, et passez ajax_wait plus page_wait pour que le contenu chargé tardivement ait le temps d'apparaître avant que le HTML ne soit retourné. L'exemple ci-dessous pointe vers une page de produit publique ; remplacez-la par l'URL publique sur laquelle vous travaillez.
import os from crawlbase import CrawlingAPI api = CrawlingAPI({"token": os.environ["CRAWLBASE_JS_TOKEN"]}) target_url = "https://www.example.com/products/widget" def fetch_html(url): response = api.get(url, {"ajax_wait": "true", "page_wait": 4000}) if response["status_code"] != 200: raise RuntimeError(f"Fetch failed: {response['status_code']}") return response["body"].decode("utf-8", "ignore") if __name__ == "__main__": html = fetch_html(target_url) print(len(html), "bytes of rendered HTML")
Exécutez-le et vous devriez voir un nombre d'octets substantiel et, si vous affichez une tranche, un contenu réel plutôt qu'une coquille vide. C'est l'étape que ChatGPT ne peut pas réaliser seul : la Crawling API a rendu le JavaScript et routé la requête via une IP de confiance afin que la page soit retournée en entier. Avec du HTML propre en main, le modèle peut prendre le relais.
Étape 2 : Réduire la page à du texte propre ou du markdown
Le HTML brut est principalement du bruit pour un modèle de langage : scripts, styles, chemins SVG et balises de suivi qui coûtent des tokens et diluent le signal. Dépouilllez-les d'abord. Pour une extraction de champs simples, le texte de BeautifulSoup suffit. Lorsque la page a une structure significative, comme un tableau de spécifications ou une liste imbriquée, convertissez en markdown afin que le modèle puisse voir la hiérarchie.
from bs4 import BeautifulSoup import html2text def to_text(html): soup = BeautifulSoup(html, "html.parser") for tag in soup(["script", "style", "noscript", "svg"]): tag.decompose() return soup.get_text(separator=" ", strip=True) def to_markdown(html): converter = html2text.HTML2Text() converter.ignore_links = True converter.ignore_images = True return converter.handle(html)
Cette seule opération réduit souvent le nombre de tokens d'un ordre de grandeur, ce qui signifie des extractions moins coûteuses, plus rapides et plus précises parce que le modèle ne doit pas naviguer dans du balisage. Si vous préférez ignorer cette étape entièrement, Crawlbase peut retourner directement du markdown prêt pour les LLMs depuis la récupération, de sorte que la page arrive dans la forme qu'un modèle souhaite sans étape de conversion locale.
Étape 3 : Demander au modèle OpenAI d'extraire du JSON structuré
Voici maintenant le web scraping avec ChatGPT à proprement parler. Envoyez le contenu nettoyé à un modèle OpenAI avec un prompt qui nomme chaque champ souhaité et force la sortie en JSON. Le réglage le plus important est de demander une réponse en objet JSON, afin d'obtenir des données analysables plutôt que de la prose. Une température basse empêche le modèle de se montrer créatif avec des valeurs qui devraient être copiées textuellement.
import json from openai import OpenAI client = OpenAI() SYSTEM = ( "You extract structured data from web page content. " "Return only valid JSON. Copy values verbatim from the text. " "If a field is not present, use null. Never invent data." ) def extract(content, fields): prompt = ( f"Extract these fields as JSON: {', '.join(fields)}.\n\n" f"Page content:\n{content}" ) response = client.chat.completions.create( model="gpt-4o-mini", temperature=0, response_format={"type": "json_object"}, messages=[ {"role": "system", "content": SYSTEM}, {"role": "user", "content": prompt}, ], ) return json.loads(response.choices[0].message.content)
Assemblez les trois étapes et vous disposez d'un scraper complet qui ne code jamais un sélecteur en dur.
if __name__ == "__main__": html = fetch_html(target_url) text = to_text(html) data = extract(text, ["product_name", "price", "rating", "in_stock"]) print(json.dumps(data, indent=2))
Le résultat est structuré et prêt à être stocké.
{ "product_name": "Acme Widget Pro", "price": "$49.99", "rating": "4.6", "in_stock": true }
Le modèle ne peut extraire que depuis une page qu'il peut réellement voir. La Crawling API rend le JavaScript dans un vrai navigateur, fait tourner les IPs résidentielles côté serveur et retourne du HTML finalisé ou du markdown prêt pour les LLMs en un seul appel, de sorte que ChatGPT reçoit du contenu propre plutôt qu'une coquille bloquée. Commencez sur le niveau gratuit et pointez vers une page publique.
Concevoir des prompts qui extraient de façon fiable
Le prompt est désormais là où réside votre logique de scraping, il vaut donc la peine de le rédiger avec soin. Quelques modèles font la différence entre une sortie instable et des données sur lesquelles vous pouvez compter.
Définir un schéma explicite, pas une demande vague
« Récupère les infos importantes » laisse au modèle la liberté de deviner. Nommez chaque champ, son type et ce qu'il faut faire s'il est absent. Passer un squelette JSON dans le prompt est encore plus efficace, car le modèle remplit une forme qu'il peut voir plutôt qu'une forme qu'il doit inférer.
schema = { "product_name": "string", "price": "string, include currency symbol", "rating": "number or null", "specs": "object of key-value pairs", } prompt = ( f"Fill this schema from the page content. " f"Use null for anything absent.\n\n" f"Schema:\n{json.dumps(schema, indent=2)}\n\n" f"Content:\n{content}" )
Fixer les formats et interdire l'invention
Précisez exactement comment chaque valeur doit être présentée : conservez le symbole de devise sur les prix, normalisez les dates au format YYYY-MM-DD, retournez les notes sous forme de nombres. Tout aussi important, dites au modèle de ne jamais deviner. L'instruction « utilisez null pour les champs manquants, n'inventez jamais » dans le prompt système est ce qui stoppe les valeurs hallucinées, le risque principal dans l'extraction basée sur des modèles.
Baisser la température et valider la sortie
Définissez temperature=0 afin que la même page produise le même JSON. Validez ensuite ce qui est retourné : confirmez que cela s'analyse, vérifiez que les clés requises existent et vérifiez les types. Le modèle retourne du texte, traitez donc sa sortie comme une entrée non fiable jusqu'à ce que votre code l'ait vérifiée, exactement comme vous le feriez avec toute source externe.
Gérer les pages volumineuses qui dépassent la fenêtre de contexte
Le schéma ci-dessus fonctionne jusqu'à ce qu'une page soit trop grande pour tenir dans un seul appel au modèle. Les longues listes de catégories, les avis avec des centaines d'entrées et la documentation dense peuvent dépasser la fenêtre de contexte ou simplement coûter trop cher par requête. La solution est de diviser le contenu en morceaux, d'extraire depuis chacun et de fusionner les résultats.
def chunk_text(text, size=12000, overlap=500): chunks = [] start = 0 while start < len(text): end = start + size chunks.append(text[start:end]) start = end - overlap return chunks def extract_large(text, fields): results = [] for chunk in chunk_text(text): part = extract(chunk, fields) if part: results.append(part) return results
Quelques règles maintiennent le découpage honnête. Faites se chevaucher les morceaux de quelques centaines de caractères afin qu'un enregistrement à cheval sur une limite ne soit pas coupé en deux. Divisez sur des ruptures naturelles comme les paragraphes ou les éléments de liste plutôt qu'en milieu de mot lorsque c'est possible. Pour les pages de liste, demandez à chaque morceau un tableau d'éléments et concaténez les tableaux, puis dédupliquez sur une clé stable comme un ID produit ou une URL, puisque le chevauchement produira quelques doublons. Ce schéma est le même que celui utilisé par les systèmes en production, et les mécanismes plus larges sont couverts dans comment l'extraction de données par IA fonctionne.
Quand la page résiste
Tout ce qui précède suppose que la récupération réussit. Sur les sites bien défendus, ce ne sera pas le cas, du moins pas longtemps. La Crawling API gère le rendu et la rotation des IPs dans l'appel que vous avez déjà écrit, ce qui lève la plupart des blocages. Lorsque vous opérez à plus grand volume ou ciblez des cibles inhabituellement agressives, routez via le Smart AI Proxy, qui adapte sa stratégie par cible pour maintenir des taux de succès élevés, ou utilisez la Crawling API lorsqu'un site dispose déjà d'un parseur maintenu et que vous voulez des champs propres sans appel au LLM.
La division du travail est ce qu'il faut retenir : Crawlbase est responsable du passage des défenses et de la livraison d'une vraie page, et le modèle OpenAI est responsable de la lecture. Confondre les deux, en demandant à ChatGPT de récupérer une URL, est ce qui produit des requêtes bloquées et des réponses hallucinées. Gardez-les séparés et chacun fait la partie pour laquelle il est doué. Si vous souhaitez comparer des familles de modèles pour la partie extraction, notre guide sur l'utilisation de Gemini AI pour le web scraping suit la même forme de récupération puis extraction.
Points clés
- Divisez le travail en deux. Crawlbase récupère et rend la page ; le modèle OpenAI extrait les données du contenu propre. Le modèle ne touche jamais au réseau.
- Réduisez avant de prompter. Dépouilllez le HTML en texte ou markdown pour dépenser les tokens sur le contenu, pas sur les balises de script, et obtenir des extractions moins coûteuses et plus précises.
-
Faites de votre prompt votre schéma. Nommez chaque champ et son type, forcez la sortie JSON, définissez
temperature=0et dites au modèle d'utiliser null au lieu d'inventer des valeurs. - Découpez les grandes pages. Divisez avec chevauchement, extrayez par morceau, puis fusionnez et dédupliquez sur une clé stable lorsque le contenu dépasse la fenêtre de contexte.
- Validez la sortie. Le modèle retourne du texte ; confirmez qu'elle s'analyse et possède les clés et types attendus avant de la stocker.
- Restez sur les données publiques. Respectez les conditions d'utilisation et le robots.txt de chaque site ; pas de comptes, pas de données personnelles, pas d'actions derrière une connexion.
Foire aux questions
ChatGPT peut-il scraper un site web directement ?
Non. ChatGPT n'a aucun moyen fiable de récupérer une page en direct : il se fait bloquer comme n'importe quel autre client et fabrique souvent une réponse lorsqu'il ne peut pas charger l'URL. Ce qu'il fait bien, c'est lire le contenu que vous lui fournissez et retourner des données structurées. Vous récupérez donc la page avec un outil comme la Crawling API, puis vous transmettez le HTML propre ou le markdown au modèle pour extraction.
Pourquoi récupérer avec Crawlbase plutôt qu'avec Python requests ?
Parce qu'une requête simple retourne une coquille vide sur les sites lourds en JavaScript et se fait bloquer sur les sites défendus. La Crawling API rend la page dans un vrai navigateur et route via des IPs résidentielles rotatives, de sorte que le contenu que voit le modèle est le contenu qu'un humain verrait. Sans cette étape, le modèle extrait depuis une page vide ou une page de détection de bot.
Quel modèle OpenAI dois-je utiliser pour l'extraction ?
Un modèle petit et rapide comme gpt-4o-mini gère bien la plupart des extractions de champs et maintient les coûts bas à grande échelle. Utilisez un modèle plus grand uniquement lorsque la page exige un vrai raisonnement, comme inférer des champs implicites plutôt qu'explicites, ou réconcilier des valeurs contradictoires. Commencez petit, mesurez la précision sur vos pages et passez à la taille supérieure seulement si le petit modèle rate.
Comment empêcher le modèle d'halluciner des valeurs ?
Trois choses ensemble. Définissez temperature=0 pour une sortie déterministe, instruisez le modèle dans le prompt système d'utiliser null pour les champs manquants et de ne jamais inventer de données, et validez le JSON retourné dans le code. Lui demander de copier les valeurs textuellement du texte, plutôt que de résumer, réduit aussi les réponses fabriquées.
Comment gérer une page trop volumineuse pour une seule requête ?
Divisez le contenu nettoyé en morceaux se chevauchant, extrayez depuis chaque morceau séparément et fusionnez les résultats. Pour les pages de liste, retournez un tableau par morceau et dédupliquez sur une clé stable comme un ID produit, puisque le chevauchement produit quelques doublons. Dépouiller d'abord le HTML en texte réduit également la page suffisamment pour que de nombreuses pages « trop grandes » tiennent dans un seul appel.
Le web scraping avec ChatGPT est-il légal ?
Cela dépend des conditions d'utilisation du site cible, de votre juridiction et de ce que vous faites des données. Restez strictement sur le contenu public, respectez le robots.txt et les attentes de cadence, et ne touchez jamais aux comptes, aux données personnelles ou à quoi que ce soit derrière une connexion. Pour une réutilisation commerciale, obtenez une autorisation ou un accord officiel sur les données plutôt que de vous fier à un scraper.
Crawlez n'importe quel site à grande échelle, sans combattre l'infrastructure.
Crawlbase gère les proxies, les empreintes et les CAPTCHA afin que votre équipe livre des pipelines de données au lieu de maintenir la plomberie de crawl. 1 000 requêtes gratuites, sans carte requise.
