rs-trafilatura: Eine Rust-Webinhalts-Extraktionsbibliothek

Murrough Foley
Murrough Foley
Author·14 min read

Ich habe rs-trafilatura gebaut, weil ich saubere Inhalte von Webseiten in großem Maßstab extrahieren musste – nicht nur Artikel, sondern Produktseiten, Foren, Dokumentationen, Landing Pages, die ganze Mischung. Die existierenden Werkzeuge waren entweder nur in Python verfügbar (zu langsam für meine Pipeline) oder Rust-Crates, die Artikel-Seiten gut verarbeiteten, aber bei allem anderen versagten.

Es begann als eine direkte Portierung der exzellenten Trafilatura Python-Bibliothek von Adrien Barbaresi zu Rust. Ich brauchte die Geschwindigkeit – die Verarbeitung tausender Seiten durch eine Python-Pipeline war ein Engpass in meinem SEO-Analyse-Workflow. Aber als ich verschiedene Seitentypen testete, stieß ich immer wieder auf dasselbe Problem: Eine Einheitslösung für die Extraktion funktioniert im modernen Web nicht.

Also wuchs es. Klassifizierung von Seitentypen. Typspezifische Extraktionsprofile. Ein Konfidenz-Score. Markdown-Ausgabe. Ein ML-Klassifizierer, wenn die regelbasierten Heuristiken an ihre Grenzen stießen.

Was es tut

rs-trafilatura extrahiert den Hauptinhalt von jeder Webseite

  • Titel, Autor, Datum und den vollständigen Artikeltext – und entfernt dabei Navigation, Werbung, Sidebars, Cookie-Banner und anderen Boilerplate. Was es von anderen Extraktionsbibliotheken unterscheidet:

  • Klassifizierung von Seitentypen: Ein dreistufiger Klassifizierer (URL-Heuristiken, HTML-Signalanalyse, XGBoost mit 181 Features) erkennt 7 Seitentypen mit 87% Genauigkeit

  • Artikel, Forum, Produkt, Kollektion, Listing, Dokumentation und Service. Jeder Typ erhält ein spezialisiertes Extraktionsprofil.

  • Extraktionskonfidenz: Jede Extraktion enthält einen Qualitäts-Score (0.0-1.0) von einem XGBoost-Regressionsmodell mit 27 Features, das den erwarteten F1-Score vorhersagt. Seiten mit einem Score unter 0.80 sind Kandidaten für einen LLM-Fallback – dazu weiter unten mehr.

  • Markdown-Ausgabe: GitHub Flavored Markdown, das Überschriften, Links, Tabellen, Fett/Kursiv, Codeblöcke und Blockzitate erhält. Das ist, was ich für die SEO-Analyse tatsächlich brauche – die strukturellen Signale sind genauso wichtig wie der Text.

  • Geschwindigkeit: 44ms pro Seite auf der CPU. Das sind 22 Seiten pro Sekunde auf Standard-Hardware, verglichen mit 1.570ms pro Seite für MinerU-HTML auf einer A100 GPU.

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}")

Das Python-Paket bündelt vier Rust-Crates zu einer einzigen nativen Erweiterung über PyO3 – kein Subprozess-Overhead, einfach kompiliert Rust, das direkt aus Python aufgerufen wird.

Für wen ist das gedacht?

Ehrlich gesagt, ich habe das für mich selbst gebaut. Ich wollte verstehen, was Google sieht, wenn es eine Webseite bewertet, und dafür musste ich saubere, strukturierte Inhalte von tausenden Seiten aus den Suchergebnissen extrahieren – nicht nur Artikel, sondern die volle Mischung von Seitentypen, die man in einer echten SERP findet. Die existierenden Werkzeuge waren dafür nicht gut genug, also habe ich eines gebaut, das es ist.

Aber Inhalts-Extraktion im großen Maßstab stellt sich als ein Problem heraus, das viele versuchen zu lösen – und einige haben daraus ernsthafte Geschäfte gemacht:

Such- und Datenunternehmen verkaufen extrahierte Webinhalte als Service. Jina AI hat ReaderLM-v2 und ihre Reader API speziell dafür gebaut – gib ihnen eine URL, erhalte sauberes Markdown zurück. Firecrawl macht dasselbe mit JS-Rendering und Anti-Bot-Behandlung. Tavily verpackt Suche + Extraktion als eine API für KI-Agenten. Diffbot macht strukturierte Web-Datenextraktion seit über einem Jahrzehnt. Zyte (ehemals ScrapingHub – dasselbe Team hinter dem Artikel-Extraktions-Benchmark) verkauft Extraktion im Unternehmensmaßstab. Der Markt existiert, weil das Problem schwierig ist und jeder es gelöst haben möchte.

RAG- und LLM-Pipeline-Ersteller brauchen saubere Inhalte, um sie an Embedding-Modelle und Kontextfenster zu verfüttern. Boilerplate in Ihrem Retrieval-Kontext bedeutet verschwendete Tokens und schlechtere Antworten. Jede RAG-Pipeline hat einen Extraktionsschritt, und die meisten verwenden Readability oder BeautifulSoup und erhalten mittelmäßige Ergebnisse bei Nicht-Artikel-Seiten.

LLM-Trainingsdaten-Teams verarbeiten Milliarden von Webseiten. Die Qualität der Extraktion beeinflusst direkt die Qualität des Modells. Common Crawl liefert das rohe HTML – aber das in sauberen Trainingstext zu verwandeln, ist, wo die Extraktionsqualität zählt. Ein paar Prozentpunkte F1 über Milliarden von Seiten bedeuten Millionen von Seiten mit Rauschen entfernt oder echtem Inhalt erhalten. Das Team hinter MinerU-HTML demonstrierte einen Ansatz dazu mit ihrem AICC-Korpus

  • Clustern von Common Crawl-Seiten nach DOM-Template-Ähnlichkeit, Ausführen eines LLM auf einer repräsentativen Seite pro Cluster, dann Destillieren dieser Entscheidungen in leichtgewichtige Regeln, die auf die verbleibenden 99,6% der Seiten angewendet werden. Intelligente Architektur.

SEO-Praktiker verwenden Extraktion, um zu approximieren, was Suchmaschinen sehen. Content-Audits, Wettbewerbsanalyse, SERP-Qualitätsbewertung, Content-Gap-Analyse – all das beginnt mit dem Extrahieren des tatsächlichen Inhalts einer Seite. Wenn Ihr Extraktionswerkzeug Navigationsmenüs und Cookie-Banner in den "Inhalt" einschließt, ist Ihre Analyse falsch, bevor Sie überhaupt angefangen haben.

Akademische Forscher in Information Retrieval, Web Mining und NLP benötigen reproduzierbare Extraktion für Experimente. Der WCXB-Benchmark existiert teilweise, weil ich keinen anständigen Benchmark finden konnte, der Extraktion über Seitentypen hinweg testete – und ich bin sicher, ich war nicht der Einzige, der danach suchte.

Wenn Sie Webseiten im großen Maßstab verarbeiten und darauf achten, was Sie tatsächlich extrahieren, ist dies für Sie.

Benchmark-Ergebnisse

Ich habe rs-trafilatura gegen andere Extraktionssysteme auf zwei Datensätzen gebenchmarkt: den ScrapingHub-Benchmark (181 Artikel) und den WCXB-Benchmark, den ich gebaut habe (2.008 Seiten über 7 Seitentypen, aufgeteilt in einen Entwicklungssatz mit 1.497 Seiten und einen zurückgehaltenen Testsatz mit 511 Seiten).

ScrapingHub-Benchmark (181 Artikel)

BibliothekF1-ScorePräzisionRecall
rs-trafilatura0,9660,9420,991
trafilatura (Python)0,9480,9330,983

WCXB-Entwicklungssatz (1.497 Seiten, 7 Seitentypen)

BibliothekF1-ScorePräzisionRecall
rs-trafilatura0,8590,8630,890
MinerU-HTML (0,6B LLM)0,8270,8450,840
Trafilatura (Python)0,7910,8520,793
dom-smoothie0,7620,8060,768
ReaderLM-v2 (1,5B LLM)0,7410,7410,790

WCXB zurückgehaltener Testsatz (511 Seiten, nie während der Entwicklung verwendet)

BibliothekF1-ScorePräzisionRecall
rs-trafilatura0,8930,9000,910
Trafilatura (Python)0,8330,8860,828

rs-trafilatura übertrifft die ursprüngliche Python-Implementierung um 6,8 F1-Punkte im Entwicklungssatz und 6,0 Punkte im zurückgehaltenen Satz. Es schlägt auch beide LLM-basierten Extraktoren, während es mit 44ms pro Seite auf der CPU läuft – verglichen mit 1.570ms (MinerU-HTML) und 10.410ms (ReaderLM-v2) auf einer A100 GPU.

Wie Rust-Extraktion-Crates im Vergleich abschneiden

Zum Kontext, hier ist, wie die wichtigsten Rust-Extraktion-Crates im WCXB-Benchmark abschneiden:

Hauptinhalt-Extraktoren (filtern Boilerplate):

BibliothekF1-ScoreAm besten für
rs-trafilatura0,859Komplette Extraktion mit Metadaten, 7 Seitentypen
dom_smoothie0,762Readability-Artige Extraktion
dom-content-extraction0,731CETD-Algorithmus, forschungsbasiert

Volltext-Extraktoren (extrahiert alles, kein Filtern):

BibliothekF1-ScoreKompromiss
nanohtml2text0,670Schnell (606µs) aber schließt Boilerplate ein
fast_html2md0,664Markdown-Ausgabe, schließt Boilerplate ein

Der Unterschied ist wichtig: Volltext-Extraktoren erfassen alles inklusive Navigation und Fußzeilen. Hauptinhalt-Extraktoren identifizieren und geben nur den Artikeltext zurück. Für SEO-Analyse, Content-Aggregation oder LLM-Trainingsdaten wollen Sie Letzteres.

Ein Hinweis zu dom_smoothie: Es ist ein exzellenter Crate, den ich beim Bau von rs-trafilatura genau studiert habe. Es ist auch schneller – 27ms/Seite gegenüber rs-trafilatura's 44ms – weil es Readability-Artige Extraktion ohne den Klassifizierungs- und typspezifischen Profil-Overhead durchführt. Wenn Sie hauptsächlich mit Artikeln und Blogs arbeiten, ist dom_smoothie eine gute Wahl. rs-trafilatura ist langsamer, weil es den Seitentyp klassifiziert und auf jeder Seite andere Extraktionslogik anwendet – das ist der Kompromiss für die Handhabung von Nicht-Artikel-Inhalten.

Sowohl dom_smoothie als auch rs-trafilatura basieren auf niklak's dom_query – einer DOM-Manipulationsbibliothek für Rust, die CSS-Selektor-basierte Traversierung einfach macht. Es ist einer dieser grundlegenden Crates, die nicht genug Anerkennung bekommen.

Für einen tiefen Einblick in Rust-HTML-Parsing-Crates (html5ever, scraper, select.rs, dom_query) empfehle ich Evan Schwartz's umfassenden Vergleich von 13 Rust-Crates zum Extrahieren von Text aus HTML.

Warum Seitentypen wichtig sind

Das ist der Teil, der mich am meisten überrascht hat. Bei Artikeln konvergieren alle Extraktoren

  • F1 zwischen 0,88 und 0,93. Bei allem anderen divergieren sie stark:
SeitentypNrs-trafilaturaMinerU-HTMLTrafilaturaReaderLM-v2
Artikel7930,9320,9280,9260,878
Dokumentation910,9310,8380,8880,776
Service1650,8430,8240,7630,703
Forum1130,7920,7940,5850,589
Kollektion1170,7130,5060,5530,417
Listing990,7040,7100,5890,559
Produkt1190,6700,6190,5670,463

Foren: Eine 33-Punkte-Spanne zwischen dem Besten und dem Schlechtesten. Kollektionen: 30 Punkte. Produkte: 26 Punkte. Artikel-only-Benchmarks verstecken all dies.

Der Grund ist strukturell. Die Benutzerbeiträge eines Forum-Threads entsprechen class="comment" – was die meisten Extraktoren als Boilerplate behandeln. Eine Service-Seite verteilt ihren Inhalt über 10 verschiedene <section>-Elemente

  • Einzelknoten-Extraktion erfasst eines und verpasst den Rest. Eine Produktseite speichert ihre Beschreibung in JSON-LD Structured Data – unsichtbar für DOM-only-Extraktoren.

rs-trafilatura behandelt dies, indem es die Seite zuerst klassifiziert und dann eine typspezifische Extraktionsstrategie anwendet. Forum-Profile behandeln Kommentar-Elemente als Inhalt. Service-Seiten-Profile fassen Inhalte aus mehreren DOM-Abschnitten zusammen. Produkt-Profile greifen auf JSON-LD zurück, wenn die DOM-Extraktion scheitert.## Konfidenzbewertung und hybride Pipelines

Der Extraktionsqualitäts-Prädiktor ist die Funktion, die ich am meisten weiterentwickeln möchte. Aktuell ist es ein XGBoust-Modell mit 27 Merkmalen, das Signale betrachtet, die zum Extraktionszeitpunkt verfügbar sind – das Verhältnis von Extraktion zu HTML, Absatzstruktur, Linkdichte, Inhaltslänge im Verhältnis zu den Erwartungen für den Seitentyp, Boilerplate-Schlüsselwörter im Eröffnungstext. Bei einem Schwellenwert von 0,80 kennzeichnet es etwa 35 % der schlecht extrahierten Seiten korrekt, während es bei den restlichen Seiten eine Präzision von 97 % beibehält.

Der praktische Nutzen liegt in hybriden Pipelines. Führe rs-trafilatura für alles mit 44ms/Seite aus. Für die ~8 % der Seiten mit geringer Konfidenz leite sie zu einem neuronalen Extraktor weiter. Auf dem WCXB-Held-Out-Testsatz erhöht dies den F1-Score von 0,893 auf 0,910 – die Vorteile beider Welten.

Das Routing muss jedoch seitenartenbewusst sein. MinerU-HTML hilft bei Artikeln, Foren und Service-Seiten, schneidet aber bei Sammlungen (0.506 vs. 0.713) und Produkten (0.619 vs. 0.670) tatsächlich schlechter ab als rs-trafilatura. Seiten mit geringer Konfidenz, die Sammlungen sind, zu MinerU-HTML zu schicken, verschlechtert die Ergebnisse, anstatt sie zu verbessern.

Wohin ich dies entwickeln möchte: Anstatt alle Seiten mit geringer Konfidenz an ein einziges, allgemeines LLM zu routen, leite sie zu seitenartenspezifischen Modellen weiter, die für diese konkrete Extraktionsaufgabe trainiert wurden. Ein kleines Modell, das speziell auf die Extraktion von Produktseiten feinabgestimmt ist. Ein weiteres, das auf Forenthreads trainiert wurde. Der Seitentyp-Klassifizierer sagt einem bereits, welches Modell aufgerufen werden muss – die Infrastruktur benötigt lediglich spezialisierte Modelle am anderen Ende. Das ist die Architektur, die langfristig gewinnt: schnelle Heuristiken für 90 %+ der Seiten, spezialisierte neuronale Modelle für die Seitentypen, bei denen Heuristiken an ihre Grenzen stoßen.

Das habe ich noch nicht gebaut. Aber der Konfidenzbewerter und der Seitentyp-Klassifizierer sind das Fundament dafür.

Überschriften, SEO und die Grenzen der HTML-Extraktion

Eine interessante Erkenntnis aus der Benchmark-Arbeit: Nur ein Teil der visuell prominenten Abschnittstitel auf Webseiten verwendet semantische <h1>-<h6>-Tags. Der Rest verwendet <strong>, gestylte <span>-Elemente oder CSS font-weight: bold, um visuelle Überschriften ohne semantisches Markup zu erstellen.

Dies ist sowohl für SEO als auch für die Extraktion relevant:

  • Googles Heading Vector Patent weist <h1>-<h6>-Überschriften numerische Vektoren für das Themenverständnis zu.
  • Googles Page Segmentation Patent beschreibt das Pseudo-Rendering von Seiten, um visuell prominenten Text unabhängig von HTML-Tags zu erkennen.
  • Reine HTML-Extraktion (was rs-trafilatura und alle heuristischen Extraktoren tun) kann nur Überschriften erkennen, die <h>-Tags verwenden. Ein <strong>Abschnittstitel</strong> wird zu Fetttext, nicht zu einer Überschrift.

Wenn Sie die HTML kontrollieren: Verwenden Sie immer semantische Überschriften-Tags. Ein <strong>-Abschnittstitel, der wie eine Überschrift aussieht, ist für die meisten Extraktionstools unsichtbar und liefert Suchmaschinen schwächere Signale.

Für Extraktions-Pipelines: Diese Lücke ist eine theoretische Obergrenze für jeden reinen HTML-zu-Markdown-Konverter – einschließlich rs-trafilatura. Ein <strong>Abschnittstitel</strong> wird in der Markdown-Ausgabe als Fetttext erscheinen, nicht als Überschrift. Daran führt kein Weg vorbei, ohne visuelles Rendering oder LLM-Interpretation. Es ist ein weiteres Argument für hybride Pipelines, die schnelle heuristische Extraktion mit LLM-Fallback für Seiten kombinieren, bei denen die Strukturerkennung unsicher ist.

Was noch verbessert werden muss

Ich möchte klarstellen, wo dies noch nicht gut genug ist.

Die Seitentyp-Klassifizierung liegt bei 87 %. Das bedeutet, dass etwa jede achte Seite das falsche Extraktionsprofil erhält. Für Artikel, Foren und Produkte liegt die Genauigkeit im niedrigen 90er-Bereich – in Ordnung. Aber Auflistungen (53 % Recall) und Service-Seiten (71 %) werden zu oft falsch klassifiziert, meist als Artikel. Ich möchte die Gesamtgenauigkeit in den niedrigen 90er-Bereich bringen, was wahrscheinlich bessere Merkmale zur Unterscheidung von redaktionellen Inhalten von Inhaltsverzeichnissen erfordert.

Die Produktextraktion (F1 = 0,670) und Sammlungsseiten (0,713) sind noch nicht da, wo ich sie haben möchte. Produkte sind schwierig, weil so viel Inhalt in JSON-LD und Tab-Interfaces steckt. Sammlungen sind schwierig, weil der "Inhalt" eine Mischung aus Produktkarten und Filter-UI ist. Dies sind die Seitentypen, bei denen der heuristische Ansatz am stärksten an seine Grenzen stößt.

Dies ist ein Nebenprojekt. Ich bin SEO-Berater – bezahlte Arbeit hat Vorrang, und es gibt Wochen, in denen rs-trafilatura überhaupt keine Aufmerksamkeit erhält. Fortschritte geschehen in Schüben, wenn ich Zeit zwischen Kundenprojekten habe. Ich erwähne dies nicht als Ausrede, sondern damit die Erwartungen kalibriert sind – dies wird nicht von einem Team oder einer Firma unterstützt, es ist eine Person, die daran arbeitet, wenn er kann.

Wenn eine dieser Einschränkungen für Ihren Anwendungsfall ein Ausschlusskriterium ist, ist MinerU-HTML eine starke Alternative für artikelintensive Workloads, und Firecrawl übernimmt die Infrastrukturseite, wenn Sie keine eigene Extraktion betreiben möchten.

Erste Schritte

Rust

[dependencies]
rs-trafilatura = "0.2"

Python

  • Installation von PyPI:
pip install rs-trafilatura

Oder verwenden Sie die CLI-Binärdatei:

curl -s https://example.com/article | extract_stdin

Die Ausgabe ist JSON mit Titel, Autor, Datum, Hauptinhalt, Seitentyp, Klassifizierungskonfidenz und Extraktionskonfidenz.

Verwandtes


Zitate & Referenzen

Google-Patente zur Inhaltextraktion & Seiten-Segmentierung

  • Page Segmentation — Mehta, B., et al. (2011). "Segmenting Web Pages." US Patent 7,930,307. Google. — Beschreibt das Pseudo-Rendering von Seiten, um visuell unterschiedliche Inhaltsbereiche unabhängig von der HTML-Tag-Struktur zu identifizieren. SEO by the Sea Analyse
  • Heading Vectors — Google-Patent zur Zuweisung numerischer Vektoren zu <h1><h6>-Überschriften für thematisches Verständnis und Dokumentstrukturanalyse. MarketBrew Analyse
  • DOM Distiller — Googles produktionelles Inhaltextraktionssystem, das den Chrome Reader Mode antreibt. Basierend auf Boilerpipe mit Readability-style Fallback. Quellcode

Grundlegende Extraktionsforschung

  • Boilerpipe — Kohlschutter, C., Fankhauser, P., Nejdl, W. (2010). "Boilerplate Detection using Shallow Text Features." WSDM 2010. — Das grundlegende Paper zur inhaltsdichtebasierten Extraktion. Behandelt Extraktion als binäre Klassifizierung von Textblöcken.
  • Trafilatura — Barbaresi, A. (2021). "Trafilatura: A Web Scraping Library and Command-Line Tool for Text Discovery and Retrieval." ACL 2021. GitHub — Die am weitesten verbreitete Python-Extraktionsbibliothek. rs-trafilatura begann als Portierung davon.
  • Readability — Mozilla (2010). Der Algorithmus hinter Firefox Reader View. Bewertet DOM-Knoten nach Textdichte und Linkverhältnis. GitHub
  • jusText — Pomikalek, J. (2011). "Removing Boilerplate and Duplicate Content from Web Corpora." PhD thesis, Masaryk University. GitHub

Neuronale / LLM-Extraktion

  • MinerU-HTML (Dripper) — Liu, M., et al. (2025). "Dripper: Token-Efficient Main HTML Extraction with a Lightweight LM." arXiv:2511.23119 | GitHub — Feinanpassung von Qwen3-0.6B für binäre Elementklassifizierung.
  • ReaderLM-v2 — Jina AI (2025). "ReaderLM-v2: HTML to Markdown with a Small Language Model." arXiv:2503.01151 | HuggingFace — 1,5B-Parameter-Modell, das Markdown direkt aus HTML generiert.
  • 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.

Vergleichende Studien & Benchmarks

  • Bevendorff et al. — Bevendorff, J., Gupta, S., Kiesel, J., Stein, B. (2023). "An Empirical Comparison of Web Content Extraction Algorithms." SIGIR 2023. GitHub — Der umfassendste bestehende Vergleich. Kombinierte 8 Datensätze, evaluierte 14 Extraktoren. Wichtige Erkenntnis: "Die Leistung ist stark genreabhängig."
  • ScrapingHub — (2019). Article Extraction Benchmark. 181 Seiten. GitHub
  • Evan Schwartz — (2024). "Comparing 13 Rust Crates for Extracting Text from HTML." Blog — Umfassender Vergleich von Rust-HTML-Parsing-Optionen.

Diese Arbeit


Murrough Foley (ORCID: 0009-0008-3127-2101) ist SEO-Berater und der Autor von rs-trafilatura. Der WCXB-Benchmark ist verfügbar unter DOI 10.5281/zenodo.19316874.

Murrough Foley
Kontakt aufnehmen

Finden Sie mich auf LinkedIn oder X.