rs-trafilatura : Une bibliothèque d'extraction de contenu web en Rust

J'ai créé rs-trafilatura parce que j'avais besoin d'extraire du contenu propre à partir de pages web à grande échelle — pas seulement des articles, mais des pages produits, des forums, de la documentation, des pages de destination, tout le mélange. Les outils existants étaient soit limités à Python (trop lents pour mon pipeline), soit des crates Rust qui géraient bien les pages d'articles mais échouaient sur tout le reste.
Cela a commencé comme un portage direct de l'excellente bibliothèque Python Trafilatura d'Adrien Barbaresi vers Rust. J'avais besoin de vitesse — traiter des milliers de pages via un pipeline Python était un goulot d'étranglement dans mon flux de travail d'analyse SEO. Mais en testant sur différents types de pages, je rencontrais toujours le même problème : l'extraction universelle ne fonctionne pas sur le web moderne.
Alors cela a évolué. Classification du type de page. Profils d'extraction spécifiques au type. Un score de confiance. Une sortie Markdown. Un classifieur ML lorsque les heuristiques basées sur des règles atteignaient leurs limites.
Ce qu'il fait
rs-trafilatura extrait le contenu principal de n'importe quelle page web — titre, auteur, date et le corps complet de l'article — tout en éliminant la navigation, les publicités, les barres latérales, les bannières de cookies et autres éléments standard. Ce qui le différencie des autres bibliothèques d'extraction :
-
Classification du type de page : Un classifieur en trois étapes (heuristiques d'URL, analyse des signaux HTML, XGBoost avec 181 caractéristiques) détecte 7 types de pages avec une précision de 87 % — article, forum, produit, collection, liste, documentation et service. Chaque type bénéficie d'un profil d'extraction spécialisé.
-
Confiance d'extraction : Chaque extraction inclut un score de qualité (0.0-1.0) provenant d'un modèle de régression XGBoost à 27 caractéristiques qui prédit le score F1 attendu. Les pages avec un score inférieur à 0,80 sont candidates pour un recours à un LLM — plus de détails ci-dessous.
-
Sortie Markdown : Markdown GitHub Flavored préservant les titres, liens, tableaux, gras/italique, blocs de code et citations. C'est ce dont j'ai réellement besoin pour l'analyse SEO — les signaux structurels sont aussi importants que le texte.
-
Vitesse : 44ms par page sur CPU. Soit 22 pages par seconde sur du matériel standard, contre 1 570 ms par page pour MinerU-HTML sur un GPU A100.
use rs_trafilatura::{extract_with_options, Options};
let html = std::fs::read_to_string("page.html")?;
let result = extract_with_options(&html, &Options::default())?;
println!("Title: {:?}", result.metadata.title);
println!("Author: {:?}", result.metadata.author);
println!("Content: {}", result.content_text);
println!("Page type: {:?}", result.metadata.page_type);
println!("Confidence: {:.2}", result.extraction_quality);
import rs_trafilatura
html = open("page.html").read()
result = rs_trafilatura.extract(html, url="https://example.com")
print(f"Title: {result.title}")
print(f"Content: {result.main_content[:200]}...")
print(f"Page type: {result.page_type}")
print(f"Confidence: {result.extraction_quality:.2f}")
Le package Python regroupe quatre crates Rust en une seule extension native via PyO3 — pas de surcharge de sous-processus, juste du Rust compilé appelé directement depuis Python.
Pour qui est-ce ?
Honnêtement, je l'ai créé pour moi-même. Je voulais comprendre ce que Google voit lorsqu'il évalue une page web, et pour cela j'avais besoin d'extraire un contenu propre et structuré à partir de milliers de pages dans les résultats de recherche — pas seulement des articles, mais l'ensemble des types de pages que l'on trouve dans un vrai SERP. Les outils existants ne faisaient pas l'affaire, alors j'en ai construit un qui le faisait.
Mais l'extraction de contenu à grande échelle s'avère être un problème que beaucoup essaient de résoudre — et certains en ont fait de sérieuses entreprises :
Les entreprises de recherche et de données vendent le contenu web extrait en tant que service. Jina AI a construit ReaderLM-v2 et leur Reader API spécifiquement pour cela — donnez-leur une URL, récupérez du markdown propre. Firecrawl fait de même avec le rendu JavaScript et la gestion anti-bots. Tavily commercialise la recherche + l'extraction sous forme d'API pour les agents IA. Diffbot fait de l'extraction de données web structurées depuis plus d'une décennie. Zyte (anciennement ScrapingHub — la même équipe derrière le benchmark d'extraction d'articles) vend l'extraction à l'échelle entreprise. Le marché existe parce que le problème est difficile et que tout le monde a besoin qu'il soit résolu.
Les créateurs de pipelines RAG et LLM ont besoin de contenu propre à fournir aux modèles d'embedding et aux fenêtres de contexte. Les éléments standard dans votre contexte de récupération signifient des tokens gaspillés et des réponses moins bonnes. Chaque pipeline RAG a une étape d'extraction, et la plupart utilisent Readability ou BeautifulSoup et obtiennent des résultats médiocres sur les pages non-articles.
Les équipes de données d'entraînement LLM traitent des milliards de pages web. La qualité de l'extraction impacte directement la qualité du modèle. Common Crawl fournit le HTML brut — mais transformer cela en texte d'entraînement propre est là où la qualité d'extraction compte. Quelques points de pourcentage de F1 sur des milliards de pages signifie des millions de pages de bruit supprimées ou du vrai contenu préservé. L'équipe derrière MinerU-HTML a démontré une approche de cela avec leur corpus AICC — regroupement des pages Common Crawl par similarité de template DOM, exécution d'un LLM sur une page représentative par cluster, puis distillation de ces décisions en règles légères appliquées aux 99,6 % de pages restantes. Architecture intelligente.
Les praticiens du SEO utilisent l'extraction pour approximer ce que les moteurs de recherche voient. Les audits de contenu, l'analyse concurrentielle, le scoring de qualité SERP, l'analyse des écarts de contenu — tout cela commence par l'extraction du contenu réel d'une page. Si votre outil d'extraction inclut les menus de navigation et les bannières de cookies dans le "contenu", votre analyse est fausse avant même d'avoir commencé.
Les chercheurs académiques en recherche d'information, exploration web et NLP ont besoin d'une extraction reproductible pour les expériences. Le benchmark WCXB existe en partie parce que je ne trouvais pas de benchmark décent qui testait l'extraction sur plusieurs types de pages — et je suis sûr que je n'étais pas le seul à chercher.
Si vous traitez des pages web à grande échelle et que vous vous souciez de ce que vous extrayez réellement, cet outil est pour vous.
Résultats des benchmarks
J'ai comparé rs-trafilatura à d'autres systèmes d'extraction sur deux jeux de données : le benchmark ScrapingHub (181 articles) et le benchmark WCXB que j'ai construit (2 008 pages sur 7 types de pages, divisé en un jeu de développement de 1 497 pages et un jeu de test retenu de 511 pages).
Benchmark ScrapingHub (181 articles)
| Bibliothèque | Score F1 | Précision | Rappel |
|---|---|---|---|
| rs-trafilatura | 0,966 | 0,942 | 0,991 |
| trafilatura (Python) | 0,948 | 0,933 | 0,983 |
Jeu de développement WCXB (1 497 pages, 7 types de pages)
| Bibliothèque | Score F1 | Précision | Rappel |
|---|---|---|---|
| rs-trafilatura | 0,859 | 0,863 | 0,890 |
| MinerU-HTML (LLM 0,6B) | 0,827 | 0,845 | 0,840 |
| Trafilatura (Python) | 0,791 | 0,852 | 0,793 |
| dom-smoothie | 0,762 | 0,806 | 0,768 |
| ReaderLM-v2 (LLM 1,5B) | 0,741 | 0,741 | 0,790 |
Jeu de test retenu WCXB (511 pages, jamais utilisées pendant le développement)
| Bibliothèque | Score F1 | Précision | Rappel |
|---|---|---|---|
| rs-trafilatura | 0,893 | 0,900 | 0,910 |
| Trafilatura (Python) | 0,833 | 0,886 | 0,828 |
rs-trafilatura surpasse l'implémentation Python originale de 6,8 points F1 sur le jeu de développement et de 6,0 points sur le jeu retenu. Il bat également les deux extracteurs basés sur LLM tout en s'exécutant à 44 ms par page sur CPU — contre 1 570 ms (MinerU-HTML) et 10 410 ms (ReaderLM-v2) sur un GPU A100.
Comparaison des crates d'extraction Rust
Pour contexte, voici comment les principales crates d'extraction Rust se classent sur le benchmark WCXB :
Extracteurs de contenu principal (filtrent les éléments standard) :
| Bibliothèque | Score F1 | Convient le mieux à |
|---|---|---|
| rs-trafilatura | 0,859 | Extraction complète avec métadonnées, 7 types de pages |
| dom_smoothie | 0,762 | Extraction de style Readability |
| dom-content-extraction | 0,731 | Algorithme CETD, fondé sur la recherche |
Extracteurs de texte intégral (extraient tout, pas de filtrage) :
| Bibliothèque | Score F1 | Compromis |
|---|---|---|
| nanohtml2text | 0,670 | Rapide (606 µs) mais inclut les éléments standard |
| fast_html2md | 0,664 | Sortie Markdown, inclut les éléments standard |
La distinction est importante : les extracteurs de texte intégral capturent tout, y compris la navigation et les pieds de page. Les extracteurs de contenu principal identifient et renvoient uniquement le corps de l'article. Pour l'analyse SEO, l'agrégation de contenu ou les données d'entraînement LLM, vous voulez le second.
Une note sur dom_smoothie : c'est une excellente crate que j'ai étudiée de près lors de la construction de rs-trafilatura. Elle est aussi plus rapide — 27 ms/page contre 44 ms pour rs-trafilatura — parce qu'elle fait une extraction de style Readabilité sans la classification et la surcharge des profils spécifiques au type. Si vous travaillez principalement avec des articles et des blogs, dom_smoothie est un bon choix. rs-trafilatura est plus lent parce qu'il classe le type de page et applique une logique d'extraction différente sur chaque page — c'est le compromis pour gérer le contenu non-article.
dom_smoothie et rs-trafilatura sont tous deux construits sur dom_query de niklak — une bibliothèque de manipulation DOM pour Rust qui rend la traversée par sélecteurs CSS simple. C'est l'une de ces crates fondamentales qui ne reçoit pas assez de crédit.
Pour une analyse approfondie des crates d'analyse HTML Rust (html5ever, scraper, select.rs, dom_query), je recommande la comparaison complète d'Evan Schwartz de 13 crates Rust pour extraire le texte du HTML.
Pourquoi les types de page sont importants
C'est la partie qui m'a le plus surpris. Sur les articles, tous les extracteurs convergent — F1 entre 0,88 et 0,93. Sur tout le reste, ils divergent radicalement :
| Type de page | N | rs-trafilatura | MinerU-HTML | Trafilatura | ReaderLM-v2 |
|---|---|---|---|---|---|
| Article | 793 | 0,932 | 0,928 | 0,926 | 0,878 |
| Documentation | 91 | 0,931 | 0,838 | 0,888 | 0,776 |
| Service | 165 | 0,843 | 0,824 | 0,763 | 0,703 |
| Forum | 113 | 0,792 | 0,794 | 0,585 | 0,589 |
| Collection | 117 | 0,713 | 0,506 | 0,553 | 0,417 |
| Listing | 99 | 0,704 | 0,710 | 0,589 | 0,559 |
| Produit | 119 | 0,670 | 0,619 | 0,567 | 0,463 |
Forums : un écart de 33 points entre le meilleur et le pire. Collections : 30 points. Produits : 26 points. Les benchmarks limités aux articles masquent tout cela.
La raison est structurelle. Les messages d'un utilisateur dans un fil de forum correspondent à class="comment" — que la plupart des extracteurs traitent comme du contenu standard. Une page de service répartit son contenu sur 10 éléments <section> différents — l'extraction à nœud unique en capture un et en rate les autres. Une page produit stocke sa description dans des données structurées JSON-LD — invisibles pour les extracteurs DOM uniquement.
rs-trafilatura gère cela en classant d'abord la page, puis en appliquant une stratégie d'extraction spécifique au type. Les profils forum traitent les éléments de commentaire comme du contenu. Les profils page de service fusionnent le contenu de plusieurs sections du DOM. Les profils page produit recourent au JSON-LD lorsque l'extraction DOM échoue.## Évaluation de la Confiance et Pipelines Hybrides
Le prédicteur de qualité d'extraction est la fonctionnalité que je suis le plus intéressé à développer davantage. Actuellement, c'est un modèle XGBoost à 27 caractéristiques qui examine les signaux disponibles au moment de l'extraction — ratio d'extraction-vers-HTML, structure des paragraphes, densité des liens, longueur du contenu par rapport aux attentes du type de page, mots-clés de contenu standard dans le texte d'introduction. Avec un seuil de 0,80, il identifie correctement environ 35 % des pages mal extraites tout en maintenant une précision de 97 % sur les autres.
L'utilisation pratique concerne les pipelines hybrides. Exécutez rs-trafilatura sur tout à raison de 44 ms/page. Pour les ~8 % de pages où la confiance est faible, dirigez-les vers un extracteur neuronal. Sur l'ensemble de test réservé WCXB, cela fait passer le F1 de 0,893 à 0,910 — le meilleur des deux mondes.
Mais le routage doit être conscient du type de page. MinerU-HTML aide sur les articles, forums et pages de service, mais en réalité performe moins bien que rs-trafilatura sur les collections (0,506 vs 0,713) et les produits (0,619 vs 0,670). Envoyer les pages de collections à faible confiance vers MinerU-HTML empire les choses, ne les améliore pas.
Là où j'aimerais aller : au lieu de router toutes les pages à faible confiance vers un seul LLM généraliste, les router vers des modèles spécifiques au type de page entraînés pour cette tâche d'extraction précise. Un petit modèle affiné spécifiquement pour l'extraction de pages produits. Un autre entraîné sur les fils de forum. Le classificateur de type de page vous indique déjà quel modèle appeler — l'infrastructure a juste besoin de modèles spécialisés à l'autre bout. C'est l'architecture qui, je pense, gagnera à long terme : des heuristiques rapides pour 90 %+ des pages, des modèles neuronaux spécialisés pour les types de pages où les heuristiques atteignent leur plafond.
Je n'ai pas encore construit cela. Mais l'évaluateur de confiance et le classificateur de type de page en sont la fondation.
Titres, SEO, et les Limites de l'Extraction HTML
Une découverte intéressante issue du travail de référencement : seule une bonne partie des titres de section visuellement proéminents sur les pages web utilisent les balises sémantiques <h1>-<h6>. Les autres utilisent <strong>, des éléments <span> stylisés, ou du CSS font-weight: bold pour créer des titres visuels sans balisage sémantique.
Cela importe à la fois pour le SEO et l'extraction :
- Le Brevet des Vecteurs de Titres de Google assigne des vecteurs numériques aux titres
<h1>-<h6>pour la compréhension thématique. - Le Brevet de Segmentation de Page de Google décrit le pseudo-rendu des pages pour détecter le texte visuellement proéminent indépendamment des balises HTML.
- L'extraction HTML uniquement (ce que font rs-trafilatura et tous les extracteurs heuristiques) ne peut détecter que les titres utilisant des balises
<h>. Un<strong>Titre de Section</strong>devient du texte en gras, pas un titre.
Si vous contrôlez le HTML : utilisez toujours des balises de titre sémantiques. Un titre de section <strong> qui ressemble à un titre est invisible pour la plupart des outils d'extraction et fournit des signaux plus faibles aux moteurs de recherche.
Pour les pipelines d'extraction : cet écart est un plafond théorique pour tout convertisseur pur HTML-vers-markdown — y compris rs-trafilatura. Un <strong>Titre de Section</strong> ressortira comme du texte en gras dans la sortie markdown, pas comme un titre. Il n'y a pas de solution à cela sans rendu visuel ou interprétation par LLM. C'est un argument de plus en faveur des pipelines hybrides combinant une extraction heuristique rapide avec un repli sur LLM pour les pages où la détection structurelle est incertaine.
Ce Qui Demande Encore du Travail
Je veux être transparent sur les points qui ne sont pas encore suffisants.
La classification du type de page est à 87 %. Cela signifie qu'environ 1 page sur 8 reçoit le mauvais profil d'extraction. Pour les articles, forums et produits, la précision est dans le bas des 90 — bien. Mais les listes (rappel de 53 %) et les pages de service (71 %) sont mal classées trop souvent, généralement en tant qu'articles. J'aimerais pousser la précision globale vers le bas des 90, ce qui nécessite probablement de meilleures caractéristiques pour distinguer le contenu éditorial des index de contenu.
L'extraction de produits (F1 = 0,670) et les pages de collection (0,713) ne sont pas au niveau souhaité. Les produits sont difficiles car beaucoup de contenu vit dans du JSON-LD et des interfaces à onglets. Les collections sont difficiles car le "contenu" est un mélange de fiches produits et d'interface de filtrage. Ce sont les types de pages où l'approche heuristique atteint le plus son plafond.
C'est un projet parallèle. Je suis consultant SEO — le travail rémunéré a la priorité, et il y a des semaines où rs-trafilatura ne reçoit aucune attention. Les progrès se font par à-coups quand j'ai du temps entre les projets clients. Je mentionne cela non pas comme une excuse mais pour calibrer les attentes — ce projet n'est pas soutenu par une équipe ou une entreprise, c'est une personne qui y travaille quand il le peut.
Si l'une de ces limitations est rédhibitoire pour votre cas d'usage, MinerU-HTML est une alternative solide pour les charges de travail centrées sur les articles, et Firecrawl gère le côté infrastructure si vous préférez ne pas exécuter votre propre extraction.
Pour Commencer
Rust — installez depuis crates.io :
[dependencies]
rs-trafilatura = "0.2"
Python — installez depuis PyPI :
pip install rs-trafilatura
Ou utilisez le binaire CLI :
curl -s https://example.com/article | extract_stdin
La sortie est du JSON avec le titre, l'auteur, la date, le contenu principal, le type de page, la confiance de classification et la confiance d'extraction.
Liens Associés
- Site de référencement : webcontentextraction.org — classement, méthodologie, téléchargements
- Article de blog sur le référencement : J'ai Construit un Référencement d'Extraction de Contenu Web de 2 000 Pages
- Étude de qualité SERP : La Qualité du Contenu Prédit-elle Réellement les Classements Google ?
- Jeu de données : GitHub | HuggingFace | Zenodo
- rs-trafilatura : crates.io | PyPI | GitHub
- Guides d'intégration : Crawl4AI | Spider-rs | Scrapy | Firecrawl
- Article : prépublication arXiv (à venir)
Citations et Références
Brevets Google sur l'Extraction de Contenu et la Segmentation de Page
- Segmentation de Page — Mehta, B., et al. (2011). "Segmenting Web Pages." US Patent 7,930,307. Google. — Décrit le pseudo-rendu des pages pour identifier les régions de contenu visuellement distinctes, indépendamment de la structure des balises HTML. Analyse SEO by the Sea
- Vecteurs de Titres — Brevet Google sur l'attribution de vecteurs numériques aux titres
<h1>–<h6>pour la compréhension thématique et l'analyse de la structure des documents. Analyse MarketBrew - DOM Distiller — Le système d'extraction de contenu en production de Google alimentant le mode lecteur de Chrome. Basé sur Boilerpipe avec un repli de type Readability. Code source
Recherche Fondamentale sur l'Extraction
- Boilerpipe — Kohlschutter, C., Fankhauser, P., Nejdl, W. (2010). "Boilerplate Detection using Shallow Text Features." WSDM 2010. — L'article fondateur sur l'extraction de contenu basée sur la densité de texte. Traite l'extraction comme une classification binaire des blocs de texte.
- Trafilatura — Barbaresi, A. (2021). "Trafilatura: A Web Scraping Library and Command-Line Tool for Text Discovery and Retrieval." ACL 2021. GitHub — La bibliothèque d'extraction Python la plus utilisée. rs-trafilatura a commencé comme un portage de celle-ci.
- Readability — Mozilla (2010). L'algorithme derrière la vue lecteur de Firefox. Note les nœuds DOM par densité de texte et ratio de liens. GitHub
- jusText — Pomikalek, J. (2011). "Removing Boilerplate and Duplicate Content from Web Corpora." PhD thesis, Masaryk University. GitHub
Extraction Neuromimétique / LLM
- MinerU-HTML (Dripper) — Liu, M., et al. (2025). "Dripper: Token-Efficient Main HTML Extraction with a Lightweight LM." arXiv:2511.23119 | GitHub — Affine Qwen3-0.6B pour la classification binaire d'éléments.
- ReaderLM-v2 — Jina AI (2025). "ReaderLM-v2: HTML to Markdown with a Small Language Model." arXiv:2503.01151 | HuggingFace — Modèle de 1,5 milliard de paramètres qui génère directement du Markdown à partir du HTML.
- BoilerNet — Leonhardt, J., Anand, A., Khosla, M. (2020). "Boilerplate Removal using a Neural Sequence Labeling Model." WWW 2020 Companion.
- Web2Text — Vogels, T., Ganea, O.E., Eickhoff, C. (2018). "Web2Text: Deep Structured Boilerplate Removal." ECIR 2018.
Études Comparatives et Références
- Bevendorff et al. — Bevendorff, J., Gupta, S., Kiesel, J., Stein, B. (2023). "An Empirical Comparison of Web Content Extraction Algorithms." SIGIR 2023. GitHub — La comparaison existante la plus complète. Combinaison de 8 jeux de données, évaluation de 14 extracteurs. Constatation clé : "la performance dépend beaucoup du genre."
- ScrapingHub — (2019). Article Extraction Benchmark. 181 pages. GitHub
- Evan Schwartz — (2024). "Comparing 13 Rust Crates for Extracting Text from HTML." Blog — Comparaison complète des options d'analyse HTML en Rust.
Ce Travail
- WCXB — Foley, M. (2026). Web Content Extraction Benchmark. 2 008 pages, 7 types de pages. Site web | DOI : 10.5281/zenodo.19316874
- rs-trafilatura — Foley, M. (2026). Extraction de contenu web consciente du type de page. crates.io | PyPI | GitHub
Murrough Foley (ORCID : 0009-0008-3127-2101) est consultant SEO et l'auteur de rs-trafilatura. Le référencement WCXB est disponible avec le DOI 10.5281/zenodo.19316874.


