Lire une page web et en rédiger un résumé rapide ne pose pas de problème. Le faire pour quelques centaines de pages, chaque matin, est un travail tout différent, et c'est exactement le type de tâche pour lequel un modèle de langage est efficace. La partie difficile n'a jamais été le résumé en lui-même. C'est d'obtenir un texte propre et lisible depuis des pages qui résistent, puis d'alimenter un modèle avec plus de texte que sa fenêtre de contexte ne peut contenir sans perdre le fil.
Ce guide parcourt les deux moitiés de bout en bout. Vous collecterez des pages avec la Crawlbase Crawling API sous forme de markdown propre, puis vous les résumerez avec un LLM, et quand une page est trop longue pour un seul appel vous la découperez et utiliserez un résumé map-reduce pour que rien ne tombe hors de la fenêtre. Tout ici est du Python exécutable limité au contenu web public. À la fin, vous aurez un petit pipeline qui transforme une liste d'URL en résumés courts et cohérents que vous pouvez stocker, rechercher ou intégrer dans un rapport. C'est le coeur de la façon de résumer des données web avec Crawlbase et l'IA.
Pourquoi résumer des données web avec Crawlbase et l'IA
Une seule vue de page vous dit ce qu'un document dit en ce moment. La valeur apparaît quand vous le faites à grande échelle : suivre ce que dit un ensemble de pages concurrentes au fil du temps, condenser un flux d'articles en un digest quotidien, ou transformer une pile de pages de produits et d'avis en quelques lignes qu'un humain lira vraiment. Un LLM est rapide et cohérent, il applique donc les mêmes critères à chaque document et ne se fatigue pas à la page deux cents.
Le modèle n'est aussi bon que le texte que vous lui donnez, et c'est là que la plupart des projets de « résumeur IA » s'effondrent silencieusement. Les pages modernes sont lourdes en JavaScript, enveloppées de nav, de publicités, de bannières de cookies et de passe-partout, et beaucoup d'entre elles bloquent le trafic automatisé. Injectez du HTML brut dans un modèle et vous gaspillez des tokens à résumer des balises et des menus plutôt que du contenu. Le correctif est de séparer la collecte de la résumération : laissez Crawlbase gérer le rendu, le déblocage et l'extraction propre, et laissez le modèle faire ce pour quoi il est doué. Pour un regard plus approfondi sur cette étape d'extraction, voir comment fonctionne l'extraction de données par IA.
Comment le pipeline s'assemble
Il y a deux étapes, et les garder séparées est ce qui rend l'ensemble maintenable.
- Collecter. La Crawling API récupère chaque URL derrière une adresse IP de confiance, rend JavaScript quand nécessaire, et renvoie du markdown propre au lieu du HTML brut. Cela signifie que le texte que vous résumez est déjà dépouillé de la navigation, des scripts et des styles.
- Résumer. Un LLM lit le markdown et renvoie un court résumé. Pour les pages qui tiennent dans la fenêtre de contexte du modèle, c'est un seul appel. Pour les pages longues, vous divisez le texte en morceaux, résumez chacun, puis résumez les résumés. Ce dernier schéma est le map-reduce.
Demander du markdown à Crawlbase plutôt que du HTML compte plus qu'il n'y paraît. Le markdown conserve les titres, les listes et la structure tout en éliminant le bruit, donc le modèle consacre son budget de contexte au sens. Plus d'informations sur ce choix dans le web scraping en markdown prêt pour LLM.
La Crawling API peut renvoyer une page en markdown quand vous passez format=markdown (ou l'option markdown du scraper). Préférez toujours cela au HTML brut pour la résumération. Le HTML brut brûle des tokens sur des balises et des styles inline dont le modèle n'a pas besoin, et le bruit supplémentaire nuit mesurement à la qualité des résumés. Le markdown conserve la structure qui aide le modèle et laisse tomber le reste.
Mettre en place le projet
Vous avez besoin de Python 3 et de deux comptes : un compte Crawlbase gratuit pour le token, et un compte OpenAI pour le modèle. Créez d'abord le compte Crawlbase ; vous obtenez jusqu'à 20 000 requêtes API gratuites : 1 000 à l'inscription, et davantage à mesure que vous complétez les étapes d'onboarding, ce qui est largement suffisant pour suivre ce guide. Copiez votre token de requête Normal depuis la page de documentation du compte, et procurez-vous aussi une clé API d'OpenAI.
Créez ensuite un dossier de projet et installez les bibliothèques.
python --version mkdir web-summarizer && cd web-summarizer python -m venv .venv && source .venv/bin/activate pip install requests openai tiktoken
Trois dépendances font le travail : requests appelle la Crawling API, openai est le client du modèle, et tiktoken compte les tokens pour que vous sachiez quand une page est trop grande pour un seul appel. Définissez vos deux secrets comme variables d'environnement pour qu'ils restent hors du code.
export CRAWLBASE_TOKEN="your_crawlbase_normal_token" export OPENAI_API_KEY="your_openai_api_key"
Étape 1 : Récupérer une page en markdown propre
Commencez par la collecte. Vous envoyez à la Crawling API l'URL cible et une option format=markdown, et elle renvoie la page déjà convertie en markdown. La fonction ci-dessous encapsule cet appel, vérifie le statut amont et renvoie juste le corps markdown pour que le reste du pipeline ne voie jamais de HTML brut.
import os import requests CRAWLBASE_TOKEN = os.environ["CRAWLBASE_TOKEN"] API_ENDPOINT = "https://api.crawlbase.com/" def fetch_markdown(url: str) -> str: params = { "token": CRAWLBASE_TOKEN, "url": url, "format": "markdown", } response = requests.get(API_ENDPOINT, params=params, timeout=90) response.raise_for_status() return response.text if __name__ == "__main__": markdown = fetch_markdown("https://www.crawlbase.com/blog/") print(markdown[:800])
Exécutez-le et vous obtenez le texte de l'article en markdown, titres et listes intacts, avec le chrome de la page déjà supprimé. Si votre cible rend le contenu avec JavaScript, le même appel fonctionne avec le token JavaScript au lieu du token Normal, donc la page est rendue dans un vrai navigateur avant d'être convertie. Échangez le token et vous résumez du contenu de single-page-app sans aucun autre changement de code.
Texte propre en entrée, bons résumés en sortie. La Crawling API rend JavaScript, fait tourner les adresses IP résidentielles pour passer les blocages, et renvoie chaque page en markdown prêt à résumer en un seul appel, pour que le modèle ne voie jamais de barres de navigation ni de bannières de cookies. Commencez sur le niveau gratuit et pointez-la vers n'importe quelle URL publique.
Étape 2 : Résumer une page courte en un seul appel
Quand une page tient confortablement dans la fenêtre de contexte du modèle, la résumer est une seule requête. La fonction ci-dessous prend du texte markdown et une courte instruction, l'envoie au modèle avec une température basse pour la cohérence, et renvoie la chaîne de résumé. Garder la température basse est important ici : vous voulez que la même entrée produise une sortie stable entre les exécutions, pas une variété créative.
from openai import OpenAI client = OpenAI() # reads OPENAI_API_KEY from the environment MODEL = "gpt-4o-mini" def summarize(text: str, instruction: str) -> str: prompt = f"{instruction}\n\n---\n\n{text}" response = client.chat.completions.create( model=MODEL, messages=[{"role": "user", "content": prompt}], temperature=0.2, ) return response.choices[0].message.content.strip() SUMMARY_PROMPT = ( "Summarize the following web page in 4-6 sentences. " "Lead with the main point, then the key supporting facts. " "Ignore navigation, ads, and boilerplate." ) if __name__ == "__main__": page = fetch_markdown("https://www.crawlbase.com/blog/") print(summarize(page, SUMMARY_PROMPT))
C'est l'intégralité du chemin heureux pour un article normal. Récupérez le markdown, envoyez-le avec une instruction, affichez le résultat. Le modèle gère le travail de langage ; Crawlbase a géré le travail de données. La seule chose entre ceci et une page qui ne rentre pas est la longueur, ce qui est l'étape suivante.
Étape 3 : Gérer les pages longues avec le découpage
Chaque modèle a une fenêtre de contexte, une limite dure sur la quantité de texte qu'il peut lire en un seul appel. Les articles longs, les pages de documentation et les fils de discussion peuvent la dépasser, et quand c'est le cas l'API rejette la requête. Le correctif est de diviser le texte en morceaux qui tiennent chacun, avec un petit chevauchement pour qu'une phrase coupée en deux à une frontière apparaisse encore entière dans l'un des morceaux.
Utilisez tiktoken pour compter les tokens, pas les caractères, car la limite est mesurée en tokens. La fonction ci-dessous parcourt la liste de tokens et la découpe en fenêtres d'une taille fixe.
import tiktoken encoder = tiktoken.encoding_for_model("gpt-4o-mini") def chunk_text(text: str, max_tokens: int = 2000, overlap: int = 150): tokens = encoder.encode(text) chunks = [] start = 0 while start < len(tokens): end = start + max_tokens window = tokens[start:end] chunks.append(encoder.decode(window)) start = end - overlap return chunks
Chaque morceau est maintenant un fragment de texte autonome assez petit pour être résumé seul. Un max_tokens de 2 000 laisse un espace confortable pour le prompt et la réponse dans une fenêtre de contexte moderne ; réduisez-le si vous êtes sur un modèle plus petit. Le chevauchement vous empêche de perdre la phrase de limite entre deux morceaux. Avec du markdown propre de Crawlbase comme entrée, ces morceaux sont du contenu pur, ce qui maintient le nombre de morceaux bas et les résumés dans le sujet.
Étape 4 : Combiner les résumés de morceaux avec map-reduce
Le découpage vous donne plusieurs pièces ; le map-reduce les transforme à nouveau en une seule réponse. Le schéma a deux phases. Dans la phase de map, vous résumez chaque morceau indépendamment, produisant une liste de résumés partiels. Dans la phase de reduce, vous concaténez ces partiels et les résumez ensemble en un seul résumé final. Si les partiels combinés sont eux-mêmes trop longs, vous réduisez à nouveau, en répétant jusqu'à ce qu'un seul résumé reste.
MAP_PROMPT = ( "Summarize this section of a longer document in 3-4 sentences. " "Keep concrete facts, names, and numbers." ) REDUCE_PROMPT = ( "The following are summaries of consecutive sections of one document. " "Combine them into a single coherent summary of 5-7 sentences, " "removing repetition and keeping the overall narrative." ) def summarize_long(text: str) -> str: chunks = chunk_text(text) if len(chunks) == 1: return summarize(chunks[0], SUMMARY_PROMPT) partials = [summarize(c, MAP_PROMPT) for c in chunks] combined = "\n\n".join(partials) while len(encoder.encode(combined)) > 2000: partials = [summarize(c, MAP_PROMPT) for c in chunk_text(combined)] combined = "\n\n".join(partials) return summarize(combined, REDUCE_PROMPT)
Cette fonction unique gère maintenant n'importe quelle longueur. Une page courte prend un appel et revient immédiatement. Une page longue est mappée, réduite, et réduite à nouveau si nécessaire, avec la boucle garantissant que l'entrée finale tient toujours. Les prompts map et reduce séparés comptent : le prompt map demande des partiels denses en faits pour que les détails survivent au premier passage, et le prompt reduce demande un récit propre pour que le résumé final se lise comme une seule pièce plutôt qu'une liste cousue.
Étape 5 : L'exécuter sur de nombreuses URL
Les deux étapes se composent maintenant en un petit pipeline. Donnez-lui une liste d'URL, récupérez chacune en markdown, résumez chacune avec la fonction tenant compte de la longueur, et collectez les résultats. Encapsulez chaque URL dans un try/except pour qu'une mauvaise page ne fasse pas couler tout le lot, et vous avez quelque chose que vous pouvez pointer vers un flux.
import json URLS = [ "https://www.crawlbase.com/blog/", "https://www.crawlbase.com/blog/ai-data-extraction-how-it-works/", ] def run_pipeline(urls): results = [] for url in urls: try: markdown = fetch_markdown(url) summary = summarize_long(markdown) results.append({"url": url, "summary": summary}) except Exception as error: print(f"Skipped {url}: {error}") return results if __name__ == "__main__": output = run_pipeline(URLS) print(json.dumps(output, indent=2))
La sortie est un tableau JSON de paires url et summary, prêtes à écrire dans un fichier, pousser vers une base de données ou rendre dans un digest. Un exemple réduit de ce qui revient :
[ { "url": "https://www.crawlbase.com/blog/", "summary": "The Crawlbase blog covers web scraping, proxies, and data extraction, with hands-on tutorials for engineers. Recent posts focus on rendering JavaScript sites, avoiding blocks, and turning pages into clean structured data." }, { "url": "https://www.crawlbase.com/blog/ai-data-extraction-how-it-works/", "summary": "The article explains how AI models extract structured fields from messy web pages, contrasting rule-based scrapers with model-driven extraction that adapts to layout changes." } ]
Conseils pratiques pour la production
Mettre en cache le markdown récupéré
La collecte et la résumération échouent pour des raisons différentes, donc ne les coupler pas. Enregistrez le markdown de chaque page sur disque identifié par URL dès que vous le récupérez. Quand vous voulez ré-exécuter avec un prompt ou un modèle différent, vous résumez depuis le cache au lieu de re-crawler, ce qui est plus rapide et ne dépense pas de crédits API sur des pages que vous avez déjà.
Cadencer et réessayer vos requêtes
Les deux API peuvent limiter le débit d'une boucle serrée. Ajoutez un court délai entre les URL et encapsulez l'appel au modèle dans un réessai avec recul pour qu'une erreur transitoire ne perde pas une page. La Crawling API gère la rotation des IP et le déblocage pour vous, donc la cadence dont vous avez besoin ici est légère, mais il vaut quand même la peine d'être un client poli.
Fixer vos prompts et votre modèle
Des prompts réutilisables et versionnés sont ce qui rend les résumés cohérents entre les exécutions. Gardez les prompts map et reduce en un seul endroit, fixez le nom du modèle et maintenez la température basse. Quand vous en changez un, traitez-le comme un changement de votre sortie, car c'en est un.
Adapter l'outil à la page
Utilisez le token Normal pour les pages statiques et le token JavaScript pour les single-page-apps qui rendent le contenu dans le navigateur. Si vous voulez des données structurées comme le prix, le titre et la note plutôt que de la prose, utilisez la Crawling API pour obtenir du JSON structuré, puis résumez cela. Et si vous intégrez ceci dans un agent ou un workflow basé sur MCP, le Web MCP expose le même crawling et la même extraction à votre modèle comme outils. Pour une construction agentique complète, construire un pipeline de données IA avec LangChain et Crawlbase va plus loin.
Points clés
- Séparez la collecte de la résumération. Crawlbase obtient du texte propre ; le modèle fait le travail de langage. Garder les deux étapes séparées est ce qui rend le pipeline maintenable.
-
Récupérez du markdown, pas du HTML. Passez
format=markdownpour que le modèle consacre son contexte au contenu, pas aux barres de navigation et aux scripts. -
Comptez les tokens, puis découpez. Utilisez
tiktokenpour diviser les pages longues en fenêtres qui chevauchent et tiennent chacune dans la fenêtre de contexte. - Map-reduce passe à l'échelle pour n'importe quelle longueur. Résumez chaque morceau, puis résumez les résumés, en réduisant à nouveau jusqu'à ce qu'un seul reste.
- Mettez en cache et fixez pour la production. Enregistrez le markdown récupéré, versionez vos prompts, fixez le modèle et maintenez la température basse pour une sortie cohérente.
Foire aux questions
Pourquoi récupérer du markdown plutôt que du HTML brut pour la résumération ?
Le HTML brut est plein de balises, de scripts, de styles inline, de navigation et de publicités qui ne portent aucun sens pour un résumé mais coûtent quand même des tokens. La Crawling API peut renvoyer une page en markdown, qui conserve les titres, les listes et le corps du texte tout en éliminant le bruit. Cela signifie que le modèle consacre son contexte limité au contenu réel, les résumés sortent plus propres et vous payez moins de tokens par page.
Qu'est-ce que la résumération map-reduce et quand en ai-je besoin ?
Map-reduce est un schéma en deux phases pour un texte trop long pour un seul appel au modèle. Dans la phase de map, vous résumez chaque morceau du document seul ; dans la phase de reduce, vous résumez ces résumés partiels ensemble en une seule réponse finale. Vous en avez besoin chaque fois qu'une page dépasse la fenêtre de contexte du modèle. Les pages courtes passent directement à un seul appel, ce qui explique pourquoi l'exemple vérifie d'abord le nombre de morceaux.
Comment choisir une taille de morceau ?
Dimensionnez les morceaux en tokens, pas en caractères, et laissez de la place pour le prompt et la réponse. Un morceau de 2 000 tokens fonctionne bien sur les modèles modernes avec de grandes fenêtres de contexte ; réduisez-le pour les modèles plus petits. Ajoutez un petit chevauchement, environ 100 à 200 tokens, pour qu'une phrase divisée à la frontière d'un morceau apparaisse encore entière dans l'un des morceaux. Comptez les tokens avec tiktoken en utilisant le même encodage que votre modèle.
Puis-je résumer des pages rendues par JavaScript ?
Oui. Échangez le token Normal contre le token JavaScript dans l'appel à la Crawling API. Elle rend la page dans un vrai navigateur avant de la convertir en markdown, de sorte que le contenu de la single-page-app est présent quand le modèle le lit. Le reste du pipeline, le découpage et le map-reduce, ne change pas du tout.
Ai-je besoin d'un compte Crawlbase ou OpenAI payant pour suivre cela ?
Non. Crawlbase vous donne jusqu'à 20 000 requêtes API gratuites : 1 000 à l'inscription, et davantage à mesure que vous complétez les étapes d'onboarding, ce qui est suffisant pour tester cela de bout en bout. L'utilisation d'OpenAI est facturée par token, et un petit modèle comme gpt-4o-mini rend la résumération bon marché. Les deux conviennent pour commencer sur leurs niveaux gratuits ou à faible coût avant de passer à l'échelle.
Puis-je utiliser un modèle ou un fournisseur différent ?
Oui. Le pipeline ne dépend que de deux choses du modèle : un appel de style chat qui prend un prompt et renvoie du texte, et un compteur de tokens pour le découpage. Échangez le client dans la fonction summarize pour n'importe quel fournisseur que vous préférez et mettez à jour l'encodage tiktoken pour correspondre au modèle. L'étape de collecte et la logique map-reduce restent exactement les mêmes.
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.

