Le web scraping vous donne du contenu brut. Même les bons outils de scraping retournent du markdown qui inclut des menus de navigation, des bannières de cookies, des CTA de newsletters, des boutons de partage social, des sections de posts connexes et du contenu de pied de page mélangés avec l’article réel. Vous avez besoin d’une étape de nettoyage.
L’approche classique est le regex ou le parsing HTML : supprimer les éléments par nom de classe, éliminer les patterns connus, filtrer par position DOM. Cela fonctionne jusqu’à ce que ça ne fonctionne plus — chaque site a une structure différente, et les noms de classes changent constamment. Vous jouez au jeu du taupe avec chaque nouvelle source.
Une meilleure approche : utiliser un LLM. Un modèle économique comme gpt-4o-mini comprend la différence sémantique entre « contenu d’article » et « chrome du site » sans avoir besoin de connaître la structure HTML spécifique de chaque site. Vous lui donnez du markdown, il vous donne du markdown nettoyé. La logique est suffisamment générale pour fonctionner sur n’importe quel site.
Pourquoi cela fonctionne
Les LLMs sont entraînés sur d’énormes quantités de contenu web. Ils ont une forte intuition sur ce à quoi ressemble le texte d’article par rapport à ce à quoi ressemble la navigation. Un paragraphe qui dit « Abonnez-vous à notre newsletter pour des mises à jour hebdomadaires » suivi d’un bouton se lit très différemment pour un LLM qu’un paragraphe qui continue un argument ou une explication.
C’est le type de jugement qui est difficile à encoder dans des règles mais trivial pour un modèle de langage. Le compromis coût-qualité atterrit au bon endroit aussi : vous n’avez pas besoin de GPT-4o pour cela. gpt-4o-mini le gère de manière fiable à une fraction du coût.
La stratégie de prompt
La clé est d’être spécifique sur ce qu’il faut supprimer et ce qu’il faut préserver. Des instructions vagues comme « nettoie ce markdown » produisent des résultats inconsistants. Le prompt doit énumérer les deux côtés.
Message système (définit le rôle et les règles) :
You are a meticulous Markdown cleaner. Keep the main article text and structurebut remove navigation menus, cookie notices, newsletter CTAs, footers, share buttons,related posts, and other site chrome. Preserve headings, paragraphs, code blocks,lists, tables, and links (strip tracking params). Preserve the bold and italicizationmarkers. Replace the double return \n\n with a single return \n. Remove the weirdcharacters (like \_ or * * * alone in a single line). Return only the cleanedMarkdown with no commentary, and without wrapping it in a markdown block.Message utilisateur (la tâche et le contenu) :
Task: Clean the Markdown below according to the rules. Return ONLY the cleaned Markdown.
---BEGIN MARKDOWN---${content}---END MARKDOWN---Quelques décisions de conception dans ce prompt :
Énumérez explicitement ce qu’il faut supprimer. « Menus de navigation, avis de cookies, CTAs de newsletter, pieds de page, boutons de partage, posts connexes » — nommer les catégories réduit l’ambiguïté. Le modèle sait ce qu’est un avis de cookies, mais « chrome du site » seul est moins fiable.
Énumérez ce qu’il faut préserver. « Titres, paragraphes, blocs de code, listes, tables et liens » — cela empêche le modèle de supprimer agressivement du contenu dont il n’est pas sûr.
Nettoyage du formatage dans le même passage. Supprimer les paramètres de tracking des liens, normaliser les sauts de ligne, supprimer les underscores échappés et les astérisques isolés — ces éléments sont peu coûteux à inclure dans le même prompt et évitent une étape de nettoyage séparée.
Pas de commentaire, pas de code fences. La sortie va directement dans l’étape suivante du pipeline. Vous ne voulez pas que le modèle enveloppe le résultat dans des ```markdown``` ou ajoute « Voici le contenu nettoyé : ». Les deux instructions sont explicites.
Délimiteurs pour le contenu. ---BEGIN MARKDOWN--- et ---END MARKDOWN--- séparent clairement les instructions du contenu à nettoyer. Cela importe quand les articles eux-mêmes contiennent des phrases ressemblant à des instructions.
Température et sélection du modèle
Utilisez temperature: 0.1 — aussi bas que possible sans être déterministe. Vous voulez une sortie cohérente et prévisible pour la même entrée. Une température plus élevée introduit une variation inutile : le modèle pourrait choisir de conserver un encadré dans une exécution et de le supprimer dans la suivante.
gpt-4o-mini est le bon choix pour cette tâche. Il est :
- Économique : 0,15 $/1M tokens d’entrée, 0,60 $/1M tokens de sortie
- Suffisamment rapide pour le traitement par lots
- Plus que capable de comprendre « ceci est de la navigation, ceci est de l’article »
Vous n’avez pas besoin de capacités de raisonnement ou d’un long contexte pour cela. La tâche est mécanique.
Considérations de timeout
Les APIs LLM peuvent être lentes, surtout pour les articles longs. Le nœud HTTP n8n effectuant cet appel utilise timeout: 500000 (plus de 8 minutes). C’est de la programmation défensive — la plupart des réponses arrivent en quelques secondes, mais certains longs articles sur des jours d’API lents peuvent prendre nettement plus longtemps.
C’était d’ailleurs la raison pour laquelle les nœuds LLM natifs de n8n ne fonctionnaient pas pour ce workflow : leurs timeouts intégrés sont trop courts. Utiliser un nœud HTTP Request brut vous donne le contrôle sur le timeout.
Coût à l’échelle
Pour un workflow traitant ~20 articles/jour :
- Entrée par article : ~3 000-8 000 tokens (prompt système + contenu de l’article depuis Jina)
- Sortie par article : ~2 000-5 000 tokens (markdown nettoyé)
- À 600 articles/mois : ~3,6M tokens d’entrée (0,54 $), ~2,4M tokens de sortie (1,44 $)
- Total : ~2 $/mois
À ~2 $/mois pour 600 articles, le coût est faible par rapport aux alternatives.
La chaîne de format intermédiaire
Cette étape de nettoyage se situe au milieu d’un pipeline d’extraction de contenu en trois étapes :
URL → Jina AI Reader → Markdown brut (avec bruit) ↓ GPT-4o-mini cleaner → Markdown propre ↓ Parser markdown-vers-blocs Notion → Blocs NotionJina AI convertit le HTML en markdown (voir Workflow RSS-vers-Notion n8n pour la configuration). Le nettoyeur LLM supprime le bruit. Le Parser markdown-vers-blocs Notion convertit le markdown propre au format API de Notion.
La raison d’utiliser le markdown comme format intermédiaire — plutôt que de nettoyer directement le HTML — est que le markdown est plus facile à travailler programmatiquement. Il est orienté ligne, structuré sans être verbeux, et le LLM produit une sortie markdown cohérente. Parser le markdown en blocs Notion est faisable ; parser du HTML arbitraire directement ne l’est pas.
Généraliser le pattern
Ce pattern de « LLM comme filtre sémantique » s’étend au-delà du web scraping. La même approche fonctionne pour :
Newsletters par e-mail : supprimer les pieds de page, les liens de désabonnement, les messages sponsorisés — garder le contenu.
Résumés de messages Slack : supprimer les @mentions, les réactions emoji, le bruit des fils de discussion — garder le signal.
Descriptions de tickets Jira : supprimer le boilerplate de template (« Veuillez décrire le bug en détail… ») — garder le contenu réel que quelqu’un a tapé.
Descriptions de PR GitHub : supprimer les sections auto-générées — garder le résumé rédigé par un humain.
Dans chaque cas, le pattern est le même : définissez ce qu’il faut garder, définissez ce qu’il faut supprimer, utilisez un modèle économique avec une température basse, obtenez le contenu nettoyé dans le format dont vous avez besoin.
Le modèle n’a pas besoin de comprendre votre domaine. Il doit comprendre la différence entre « contenu que quelqu’un a écrit intentionnellement » et « scaffolding qui entoure ce contenu ». C’est une capacité très générale.
Connexes
- Workflow RSS-vers-Notion n8n — le pipeline complet dans lequel vit cette étape de nettoyage
- Parser markdown-vers-blocs Notion — ce qui arrive au markdown nettoyé ensuite