
Construire un RAG commence par collecter le contenu à indexer. Si ce contenu est sur le web, le télécharger ne suffit pas : une page HTML mêle l'article utile à des menus, des publicités et des pieds de page. Indexer ce bruit dégrade tout le reste du pipeline. Trafilatura résout cette première étape : il isole le contenu principal d'une page et le rend en texte propre ou en Markdown, avec ses métadonnées — titre, auteur, date. Ce guide montre comment extraire une page, récupérer ses métadonnées, traiter un lot d'URL et constituer un corpus prêt pour l'indexation. Public visé : développeur qui prépare les données d'un RAG.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Pourquoi le HTML brut est inexploitable pour un RAG.
- Extraire le contenu principal d'une page en texte ou en Markdown.
- Récupérer les métadonnées : titre, auteur, date.
- Arbitrer entre précision et rappel selon l'usage.
- Traiter un lot d'URL et écrire un corpus sur disque.
Prérequis
Section intitulée « Prérequis »- Python 3.10+ et les bases de la manipulation de fichiers.
- Ce guide ouvre le parcours RAG — utile pour situer cette étape.
Le problème : le HTML brut est inexploitable
Section intitulée « Le problème : le HTML brut est inexploitable »Télécharger une page web, c'est récupérer du HTML brut. Dedans, l'article que vous visez côtoie une navigation, des bannières publicitaires, des encarts latéraux, un pied de page légal, sans compter le JavaScript et le CSS.
Pour un RAG, ce mélange est toxique. Chaque morceau de menu ou de publicité indexé devient un chunk parasite : vos recherches sémantiques remontent des fragments de navigation au lieu du contenu pertinent. La qualité d'un RAG se joue dès cette étape — un corpus sale produit un RAG sale.
Il faut donc une étape d'extraction du contenu principal : repérer, dans le HTML, le bloc qui porte l'information, et jeter le reste.
Pourquoi Trafilatura
Section intitulée « Pourquoi Trafilatura »Repérer le contenu principal « à la main » — avec des sélecteurs CSS — est fragile : chaque site a une structure différente, et elle change. Trafilatura fait ce travail par des heuristiques robustes, indépendantes du site : densité de texte, balises sémantiques, longueur des blocs.
Trois atouts en font un bon choix pour un pipeline RAG. Il extrait proprement sans configuration par site. Il récupère les métadonnées — titre, auteur, date — utiles pour tracer et filtrer. Et il rend plusieurs formats — texte, Markdown, JSON — directement exploitables par l'étape suivante.
Installer Trafilatura
Section intitulée « Installer Trafilatura »Trafilatura s'installe dans un environnement virtuel, comme tout projet Python.
python3 -m venv .venvsource .venv/bin/activatepip install trafilatura==2.0.0 lxml-html-clean==0.4.5Le second paquet, lxml-html-clean, n'est pas optionnel. Depuis la version 6 de lxml, le module html.clean a été sorti dans un paquet séparé ; une dépendance interne de Trafilatura en a besoin. Sans lui, le simple import trafilatura échoue.
Extraire le contenu d'une page
Section intitulée « Extraire le contenu d'une page »En production, on télécharge la page avec fetch_url, puis on l'extrait avec extract. Pour un lab reproductible, on travaille sur un fichier HTML local — l'extraction est identique.
import trafilatura
def extraire_texte(html: str) -> str: """Extrait le contenu principal d'une page HTML en texte propre.""" return trafilatura.extract(html) or ""extract renvoie le texte du contenu principal — ou None si la page n'a rien d'exploitable, d'où le or "" qui garantit toujours une chaîne. Sur une page d'article noyée dans un menu, une publicité et un pied de page, la sortie ne contient que l'article :
Un conteneur Docker est éphémère : dès qu'il est supprimé, tout ce qu'ilcontenait disparaît. Pour conserver des données au-delà de la vie d'unconteneur, Docker fournit les volumes...Le menu, la bannière « PROMOTION », le pied de page « Mentions légales » ont disparu — sans qu'on ait écrit un seul sélecteur CSS.
Pour télécharger une vraie page, on enchaîne fetch_url et extract :
html = trafilatura.fetch_url("https://exemple.fr/article")texte = extraire_texte(html)Récupérer les métadonnées
Section intitulée « Récupérer les métadonnées »Le texte seul ne suffit pas : un corpus RAG a besoin de tracer d'où vient chaque document — pour citer ses sources, filtrer par date, attribuer un auteur. Trafilatura extrait ces métadonnées en demandant le format JSON.
import json
def extraire_donnees(html: str) -> dict: """Extrait le contenu et ses métadonnées (titre, auteur, date).""" brut = trafilatura.extract(html, output_format="json", with_metadata=True) if not brut: return {} donnees = json.loads(brut) return { "titre": donnees.get("title"), "auteur": donnees.get("author"), "date": donnees.get("date"), "texte": donnees.get("text", ""), }L'option with_metadata=True demande à Trafilatura de joindre les métadonnées ; le format json les renvoie dans une structure facile à parser. Le résultat est un dictionnaire propre, prêt à être stocké :
Titre : Comprendre les volumes DockerAuteur : Équipe InfrastructureDate : 2026-03-12Conserver la structure en Markdown
Section intitulée « Conserver la structure en Markdown »Le texte brut aplatit tout : titres, listes et paragraphes se confondent. Pour un RAG, garder la structure aide — un découpage par sections (vu dans le guide sur le chunking) s'appuie dessus. Le format markdown préserve cette hiérarchie.
def extraire_markdown(html: str) -> str: """Extrait le contenu principal en Markdown — titres et listes conservés.""" return trafilatura.extract(html, output_format="markdown") or ""La sortie garde les # de titres et les puces de liste. C'est le format à privilégier quand le chunking structurel est prévu en aval.
Précision ou rappel : le compromis
Section intitulée « Précision ou rappel : le compromis »Toute extraction arbitre entre deux risques : laisser passer du bruit, ou jeter du contenu utile. Trafilatura expose ce réglage par deux options.
Le mode précision — favor_precision=True — est strict : il ne garde que ce dont il est sûr. Moins de bruit, mais quelques passages utiles peuvent être écartés. C'est le bon défaut pour un RAG : un index propre vaut mieux qu'un index complet mais bruité.
Le mode rappel — favor_recall=True — est permissif : il garde le maximum de contenu, au risque de laisser entrer du bruit. Utile quand rien ne doit être perdu, et qu'un nettoyage suivra.
# Pour un RAG : on privilégie un corpus propre.texte = trafilatura.extract(html, favor_precision=True)Traiter un lot de pages
Section intitulée « Traiter un lot de pages »Un corpus se constitue rarement page par page. Le schéma habituel est une boucle sur une liste d'URL : télécharger, extraire, collecter.
def constituer_corpus(urls: list[str]) -> list[dict]: """Télécharge et extrait une liste d'URL en documents structurés.""" corpus = [] for url in urls: html = trafilatura.fetch_url(url) if html is None: continue # page injoignable : on passe à la suivante donnees = extraire_donnees(html) if donnees.get("texte"): donnees["source"] = url corpus.append(donnees) return corpusDeux précautions comptent. On ignore les pages injoignables plutôt que de planter tout le lot. Et on conserve l'URL source dans chaque document — c'est elle que le RAG citera plus tard.
Construire un corpus pour le RAG
Section intitulée « Construire un corpus pour le RAG »L'étape se termine en écrivant le corpus sur disque — un format que l'étape de nettoyage, puis de chunking, viendra lire.
import jsonfrom pathlib import Path
def ecrire_corpus(corpus: list[dict], dossier: str) -> None: """Écrit chaque document du corpus dans un fichier JSON.""" base = Path(dossier) base.mkdir(parents=True, exist_ok=True) for i, document in enumerate(corpus): (base / f"doc_{i:03d}.json").write_text( json.dumps(document, ensure_ascii=False, indent=2), encoding="utf-8", )Un fichier JSON par document, avec son texte et ses métadonnées : c'est un corpus simple, inspectable, et stable pour la suite du pipeline. La prochaine étape — le nettoyage — partira de ces fichiers.
Dépannage
Section intitulée « Dépannage »| Symptôme | Cause probable | Solution |
|---|---|---|
ImportError: lxml.html.clean | Paquet lxml-html-clean absent | L'installer en plus de Trafilatura |
extract renvoie None | Page sans contenu principal détectable | Essayer favor_recall=True |
fetch_url renvoie None | Page injoignable, bloquée ou hors ligne | Ignorer l'URL, vérifier le réseau |
| Du bruit dans le texte extrait | Mode rappel trop permissif | Passer en favor_precision=True |
| Métadonnées vides | Page sans balises meta exploitables | Accepter les champs absents, ne pas planter |
À retenir
Section intitulée « À retenir »- Le HTML brut mêle l'article au bruit ; l'indexer dégrade tout le RAG.
- Trafilatura isole le contenu principal par heuristiques, sans configuration par site.
extractrend du texte, du Markdown ou du JSON avec métadonnées.- Pour un RAG, privilégier la précision — un corpus propre plutôt que complet.
- Un traitement par lot ignore les pages injoignables et conserve l'URL source.
- Le corpus s'écrit sur disque, un JSON par document, prêt pour le nettoyage.
Prochaines étapes
Section intitulée « Prochaines étapes »Pour aller plus loin
Section intitulée « Pour aller plus loin »- Documentation Trafilatura — la référence de la bibliothèque et de ses options.