jusTexts Schwellenwert-Klippe bei einem Fixture mit kurzen Absätzen

Zuletzt aktualisiert am August 17, 2026
jusTexts Schwellenwert-Klippe bei einem Fixture mit kurzen Absätzen
KI-Zusammenfassung
In einem Dokument, dessen längster Absatz 151 Zeichen lang ist, liefert jusText mit den Standardeinstellungen null Zeichen. Nicht nur eine unvollständige Extraktion – sondern ein leerer String. Senkt man einen Schwellwert so, dass genau ein Absatz ihn überschreitet, ergibt dasselbe Dokument 832 Zeichen. Senkt man ihn weiter, bleiben es 832. Bei diesem Fixture wirkt das Verhalten wie eine Klippe statt wie ein sanfter Übergang. Ob der Standardwert auf der falschen Seite liegt, hängt von den Absatzlängen und der Verteilung von Boilerplate im Zielkorpus ab. Prüfen Sie jusText für mehrsprachige Korpora, weil die sprachspezifische Stoplist-Oberfläche explizit und breit ist.

In einem Dokument, dessen längster Absatz 151 Zeichen lang ist, liefert jusText mit den Standardeinstellungen null Zeichen. Nicht nur eine unvollständige Extraktion – sondern ein leerer String. Senkt man einen Schwellwert so, dass genau ein Absatz ihn überschreitet, ergibt dasselbe Dokument 832 Zeichen. Senkt man ihn weiter, bleiben es 832.

Bei diesem Fixture wirkt das Verhalten wie eine Klippe statt wie ein sanfter Übergang. Ob der Standardwert auf der falschen Seite liegt, hängt von den Absatzlängen und der Verteilung von Boilerplate im Zielkorpus ab.

Was jusText ist und warum lexikalische Dichte zählt

Im Vergleich zu den anderen Extraktoren in diesem Fixture-Set verlässt sich jusText ungewöhnlich stark auf sprachspezifische Stopwort-Dichte. Ein Block mit einem hohen Anteil an Funktionswörtern – the, and, of, was – ist eher Prosa. Dieses lexikalische Signal ist aber nicht der einzige Teil des Klassifikators: Absatzlänge, Link-Dichte, aus HTML abgeleitete Blockgrenzen, Abstand zu Überschriften, Nachbar-Klassen und ein kontextsensitiver Durchlauf beeinflussen das Ergebnis ebenfalls.

Offizielle Referenz: jusTexts offizielles Repository.

System diagram: Two-Pass Paragraph Classification

Da der Klassifikator eine sprachspezifische Stoplist verwendet, wird jusText mit 100 davon ausgeliefert. Diese explizit sprachabhängige lexikalische Oberfläche ist das deutlichste Unterscheidungsmerkmal in diesem Vergleich, auch wenn die mehrsprachige Qualität nicht getestet wurde.

Getestete Version: 3.0.2, BSD 2-Clause, 822 GitHub Stars. Python 3.14.2.

Die Klippe, gemessen

Measured results chart: Characters returned as length_high changes

jusTexts Klassifikator läuft in zwei Durchgängen. Ein kontextfreier Durchlauf ordnet jeden Absatz good, bad, short oder neargood zu. Danach hebt ein kontextsensitiver Durchlauf neargood zu good hoch – aber nur, wenn der Block neben einem Block steht, der bereits good ist. Und ein Absatz erhält good nur dann direkt, wenn er length_high überschreitet, was standardmäßig 200 Zeichen sind.

In einem Dokument, in dem niemand die 200 erreicht, gibt es keinen Ausgangspunkt für diese Hochstufung, und jeder neargood-Block fällt auf Boilerplate zurück. Die gesamte Seite kommt leer zurück.

Ich habe den Schwellwert auf einem Fixture durchgespielt, dessen längster Absatz 151 Zeichen lang ist:

length_highAls good klassifizierte AbsätzeZurückgegebene Zeichen
200 (Standard)00
1508832
1208832
1008832
808832

justext-length-threshold.json.

Bei diesem Schwellenwert-Fixture veränderte ein einzelner Absatz, der die Grenze überschritt, die Ausgabe aller acht Zielabsätze; weitere Lockerungen brachten nichts mehr. Der Trace passt dazu, dass der Kontextdurchlauf geeignete neargood-Nachbarn um einen vorhandenen good-Block herum hochstuft; er bedeutet aber nicht, dass auf beliebigen Seiten jeder Nachbar automatisch promotet wird.

Bevor ich den Effekt length_high zuschrieb, habe ich length_low über vier Werte und max_link_density über zwei Werte variiert: acht Kombinationen, alle mit Ergebnis null. Keine dieser beiden Einstellungen stellte auf diesem Fixture Ausgabe wieder her.

Über das gesamte 22-Fixture-Set hinweg zeigt sich dasselbe Muster: 2 von 22 Fixtures lieferten bei length_high=200 Ausgabe, 9 von 22 bei 150, 15 von 22 bei 120.

Zwei Dinge sagt das nicht aus. Es sagt nicht, dass jusText schlecht extrahiert – auf einer echten, natürlichsprachlichen Seite lieferte es mit den Standardeinstellungen 1.190 Zeichen sauberen Artikeltext, weil ein echter Nachrichtenabsatz die 200 Zeichen im ersten Anlauf überschreitet. Und es sagt nicht, dass der Standardwert falsch ist; es sagt, dass der Standard lange Absätze voraussetzt und Sie vor dem Einsatz prüfen sollten, ob Ihr Korpus solche Absätze enthält.

Die andere Seite dieses Fixture-Sets: mehr Leckage bei Standardeinstellungen

In diesem gelabelten Fixture-Set hat jusText bei Standardeinstellungen die höchste gemessene Boilerplate-Leckage.

BibliothekArtikel-Recall (alle 22)Boilerplate-LeakageContent-Token-PrecisionVerunreinigende Tokens
Readability1.00000.23530.910935
trafilatura0.98650.05880.94114
newspaper4k0.98650.00000.94520
resiliparse0.90540.05880.93817
jusText0.83780.47060.876074
goose30.82430.00001.00000

sixway-scores.json. Ein Fixture-Set, ein Scorer, jede Einheit mit einem eindeutigen Sentinel markiert, sodass die Wiederherstellung exakt über Teilstring-Mitgliedschaft erfolgt.

System diagram: Leakage and Silence Share a Boundary

47% Boilerplate-Leakage und 74 verunreinigende Tokens – doppelt so viel Leakage wie Readability und mehr als doppelt so viel Kontamination in diesem gelabelten synthetischen Set. Das ist ein Diagnoseergebnis bei Standardeinstellungen, kein stabiles Ranking über das gesamte Produkt hinweg.

Die beobachtete Leakage passt zum selben Kontextdurchlauf, der auch hinter der Klippe steckt. Geeignete neargood-Blöcke können hochgestuft werden, wenn Blockklassen und Distanzregeln es zulassen; ein prosaähnlicher Promo-Text oder Kommentar neben Artikeltext kann dadurch die Grenze überschreiten. Das Fixture-Ergebnis zeigt, welche gelabelten Blöcke ausgelaufen sind, während der vereinfachte Mechanismus weiterhin an jusTexts exakte Kontextregeln gebunden bleibt.

Der Recall liegt bei 0.8378, also drittletzter, und der gesamte Verlust ist durch den Schwellwert bedingt: Auf einem einzelnen 129-Zeichen-Artikel, auf einer Seite mit zehn kurzen Absätzen und auf dem nahezu leeren Dokument kam gar nichts zurück.

Das Inventar der Sprach-Stoplists

Neunundneunzig weitere Stoplists.

justext.get_stoplists() liefert 100 Sprachen zurück. Der Klassifikator ist bewusst sprachparametrisiert und nicht einfach eine Übersetzung einer englischen Heuristik; der Sprachwechsel ist nur ein Argument:

import justext
paragraphs = justext.justext(html, justext.get_stoplist("Czech"))
text = "\n".join(p.text for p in paragraphs if not p.is_boilerplate)

trafilatura und goose3 zeigen ebenfalls sprachbezogenes Verhalten, aber in diesem Review wurde kein Extraktor auf nicht-englische Ground Truth bewertet. JusTexts 100 mitgelieferte Stoplists machen es zu einem klaren Kandidaten für eine mehrsprachige Evaluation; allein die Inventarliste belegt jedoch weder die Extraktionsqualität in diesen Sprachen noch, dass Wettbewerber sie schlechter abdecken.

Die API besteht aus zwei Funktionen und neun fein einstellbaren Konstanten – length_low 70, length_high 200, stopwords_low 0.30, stopwords_high 0.32, max_link_density 0.20, max_heading_distance 200, plus die Kodierungsbehandlung. Klein, gut lesbar und vollständig in der Signatur dokumentiert.

Installation und Geschwindigkeit

pip install justext zieht 3 Pakete nach – die wenigsten im Vergleich – und 22,4 MiB, in unter zwei Sekunden.

Offizielle Referenz: jusText auf PyPI.

BibliothekPaketesite-packagesKaltimportExtraktion p50
resiliparse521.0 MiB0.015 s0.06 ms
jusText322.4 MiB0.777 s0.56 ms
goose31644.3 MiB2.181 s1.85 ms
newspaper4k2247.5 MiB2.812 s2.69 ms
trafilatura1769.9 MiB1.584 s0.51 ms

install-and-import.json. Jede Bibliothek in einem eigenen leeren Virtualenv.

Drei Pakete und 22,4 MiB sind in diesem Vergleich eine kleine Abhängigkeit, und 0,56 ms mediane Extraktion liegen in diesem Testaufbau nahe an trafilaturas 0,51 ms. Die Umgebungsmessung zerlegt die Paketgröße nicht nach Dateityp, daher lässt sich nicht sagen, wie viel des Speicherplatzes auf Stoplists entfällt.

Die Wartungsfrage, vorsichtig beantwortet

Die hier verwendeten Datumswerte zur Wartung sind der letzte Repository-Push und die letzte PyPI-Version, beide 2025-02-25. Das lag siebzehn Monate vor dem Test. Insgesamt acht Releases, 91 Forks, 9 offene Issues, nicht archiviert.

Die PyPI-Klassifizierer nennen Python-Support nur bis 3.9. Ich habe es auf 3.14.2 ausgeführt; es wurde installiert, importierte in 0,777 s und extrahierte auf 19 von 22 Fixtures ohne einzige Ausnahme.

Die Metadaten liegen also fünf Python-Versionen hinter der Realität, und die Realität ist: Es funktioniert. Das ist der nützliche Unterschied: Ein ruhiges Repository ist ein Signal über Support, nicht automatisch über Funktion. Für eine Bibliothek, deren gesamter Algorithmus aus einer veröffentlichten Methode von 2011 plus einer Reihe von Wortlisten besteht, ist „fertig“ ein plausibler Zustand – es bleibt nicht mehr viel zu ändern, und Stoplists veralten nicht wie ein Anti-Bot-Workaround.

Was ein ruhiges Repo allerdings bedeutet: Wenn Sie auf einen Bug stoßen, beheben Sie ihn selbst oder forken das Projekt. Das sollte man gegen neun offene Issues abwägen, also nicht gerade ein Profil einer Bibliothek, die in ungelösten Problemen versinkt.

Speicher und was kaputtes HTML damit macht

Zwei operative Fragen werden hier getrennt gemessen.

Der breitere Stresstest-Kontext ist in der Vergleichsstudie zu Speicher und fehlerhaftem HTML über zehn Bibliotheken.

Maximaler Resident Memory, über /usr/bin/time -l, pro Zelle jeweils ein frischer Prozess – die Import-Basis ist das, was die Bibliothek geladen und im Leerlauf kostet, die Peaks enthalten das Dokument.

BibliothekLaufzeitImport-BasisPeak 226 KBPeak 10 MB
html2textpython3.1418.719.971.2
pyquerypython3.1430.333.9172.5
resiliparsepython3.1420.525.1225.1
markdownifypython3.1423.928.9278.5
goose3python3.1444.152.4398.5
cheerionode2266.876.5398.5
justextpython3.1430.336.6431.2
newspaper4kpython3.1452.661.8668.5
trafilaturapython3.1452.564.8927.1
turndownnode2247.868.42947.1

memory-results.json. Python- und Node-Baselines sind nicht direkt miteinander vergleichbar; der Interpreter steckt in beiden Fällen mit drin.

JusTexts Basis liegt bei 30,3 MiB und sein Peak in diesem 10-MB-Fixture bei 431,2 MiB, also etwa 14,2-mal der Import-Basis und 43,1-mal der Eingabegröße in absolutem RSS. Ein Fixture und ein Prozess belegen keine allgemeine Skalierungskurve; Python- und Node-Baselines bleiben zudem nicht direkt vergleichbar.

Fehlerhaftes HTML. Zwölf Dokumente, die jeweils genau eine Sache kaputtmachen – nicht geschlossene Tags, falsch verschachtelte Inline-Elemente, nicht gequotete Attribute mit Leerzeichen, einzelne schließende Tags, gar kein <html>, doppelte Attribute, ein mitten im Tag abgeschnittenes Dokument, fehlerhafte Entities, ein nicht geschlossenes <script>, eine gelogene Charset-Deklaration, ein Kommentar mit Markup und 600 Verschachtelungsebenen – plus zwei wohlgeformte Kontrollen in passenden Größen, denn „es kam nichts zurück“ sagt über Fehlerhaftigkeit nur dann etwas aus, wenn die Bibliothek auf einem sauberen Dokument derselben Größe nicht ebenfalls stumm bleibt.

justext warf auf 0 von 14 eine Ausnahme und gab auf 13 nichts zurück, wobei 0/33 bewertete Sentinels über die fehlerhaften Fixtures hinweg wiederhergestellt wurden (malformed-results.json). Auch die wohlgeformte kurze Kontrolle lieferte 0 Zeichen; die wohlgeformte lange Kontrolle war mit 1.333 Zeichen das einzige nicht leere Ergebnis. Die zwölf fehlerhaften Fixtures blieben alle leer, und der Fall mit dem nicht geschlossenen <script> ist von der Sentinel-Survival-Bewertung ausgenommen. Dieser Durchlauf zeigt also Parser-Toleranz – keine Ausnahme –, kann die Stille aber nicht eindeutig der Fehlerhaftigkeit statt des bereits gemessenen Größenlimits zuschreiben.

Vor- und Nachteile

Dafür. 100 sprachspezifische Stoplists und ein Klassifikator, der tatsächlich auf ihnen basiert, statt bloß in sie übersetzt zu werden. Die kleinste Abhängigkeitsanzahl im Vergleich mit 3 Paketen. 0,56 ms mediane Extraktion. Neun dokumentierte, gut lesbare Tuning-Konstanten. BSD 2-Clause. Läuft sauber auf Python 3.14, obwohl die Klassifizierer bei 3.9 enden.

Dagegen. Die höchste Boilerplate-Leakage in diesem synthetischen Test bei Standardwerten: 47% und 74 verunreinigende Tokens. Das Fixture mit kurzen Absätzen gab einen leeren String zurück, wenn kein Absatz length_high überschritt. Der Recall lag in diesem Set bei 0.8378. Der letzte dokumentierte Repository-Push und die letzte Veröffentlichung liegen siebzehn Monate vor dem Test, daher sollte die Wartungsübernahme mitbedacht werden.

Wer es nutzen sollte und wer nicht

jusText prüfen sollten Sie für mehrsprachige Korpora, weil die sprachspezifische Stoplist-Oberfläche explizit und breit ist. Dieser Test hat 100 Stoplists inventarisiert, die mehrsprachige Qualität aber nicht gemessen. Es ist auch dann ein Kandidat, wenn eine Abhängigkeit aus nur drei Paketen und explizite Schwellenwertkontrollen zur geplanten Umgebung passen.

Lieber nicht, wenn Sie ein Modell tokenweise füttern und 74 verunreinigende Tokens im Vergleich zu null bei goose3 und newspaper4k ein direkter Kostenfaktor sind. Ebenfalls nicht für Seiten mit kurzen Absätzen – Produkttexte, Listen, Changelogs, FAQ-Einträge – außer Sie setzen length_high bewusst. Und nicht, wenn Sie aus Compliance- oder Beschaffungsgründen eine aktiv gepflegte Abhängigkeit brauchen; das ist eine reale Einschränkung, selbst wenn der Code funktioniert.

Wenn Sie es verwenden, stimmen Sie length_high gegen eine gelabelte Validierungsstichprobe ab, statt den Standardwert oder eine Perzentilregel zu übernehmen. Testen Sie plausible Schwellenwerte und messen Sie sowohl Artikel-Recall als auch Boilerplate-Precision; ein niedrigerer Grenzwert kann kurze Prosa retten, aber zugleich unerwünschte Nachbarblöcke hochstufen.

Wo eine Managed API passt

jusText verarbeitet HTML, das Sie bereits haben – wie alles in diesem Vergleich. Keine dieser Bibliotheken ruft Seiten ab, rendert JavaScript oder umgeht eine Anti-Bot-Schicht.

Für dieselben Fixtures über alle sechs Extraktoren hinweg siehe den Vergleich der sechs Extraktionsbibliotheken.

Ein gehosteter Fetch-/Render-/Extraktionsdienst, einschließlich unseres eigenen Thunderbit, deckt eine andere Zuständigkeitsgrenze ab. Thunderbit wurde hier nicht benchmarked. Der Unterschied ist: aus gelieferten HTML-Inhalten Prosa klassifizieren versus eine URL abrufen und verarbeiten; dieser Artikel bietet keinen Qualitätsvergleich auf identischer Messbasis.

Die ehrliche Einordnung: JusTexts mehrsprachige Stoplists sind eine echte und kostenlose Fähigkeit. Wenn Ihr Problem darin besteht, Seiten in vielen Sprachen abzurufen statt Prosa darin zu klassifizieren, dann ist das ein anderer Einkauf.

Für das breitere Feld deckt unser Roundup zu Web-Scraping-APIs gehostete Optionen ab, und der Pillar zu Open-Source-Scrapern behandelt selbst gehostete Lösungen. Wenn die Ausgabe in ein Modell wandert, geht beim Konvertieren von HTML zu Markdown in Python am meisten Treue verloren.

Thunderbit für Web-Datenextraktion testen

Sollten Sie jusText verwenden?

Es ist ein Kandidat, wenn der Korpus mehrsprachig ist oder seine Absatzlängenverteilung von einer expliziten Schwellenwert-Tuning profitiert. Prüfen Sie beide Eigenschaften vor dem Einsatz.

Die 100 mitgelieferten Stoplists sind ein echtes Designmerkmal, aber die mehrsprachige Genauigkeit wurde nicht getestet. Die Threshold-Klippe ist justierbar; ob ein niedrigerer Wert akzeptabel ist, hängt von Recall und Boilerplate-Precision auf einer gelabelten Stichprobe ab.

In diesem englischen synthetischen Set bei Standardeinstellungen leakte newspaper4k null gelabelte Boilerplate-Einheiten und erfasste 0.9865 der Artikeleinheiten. Das macht es zu einem Vergleichskandidaten für diesen Workload, aber nicht zu einer allgemeinen Ersatzempfehlung.

Thunderbit für Web-Datenextraktion testen Get Started Free

FAQs

Warum gibt jusText einen leeren String statt einer Teil-Extraktion zurück? Der Klassifikator läuft in zwei Durchgängen. Ein Absatz erhält die Klasse good nur oberhalb von length_high (Standard: 200 Zeichen); im zweiten Durchlauf werden dann benachbarte neargood-Blöcke hochgestuft. Wenn kein Absatz die Schwelle überschreitet, gibt es keinen Startpunkt, daher fällt jeder Kandidat auf Boilerplate zurück und das Ergebnis bleibt leer. Das ist konstruktionsbedingt ein Alles-oder-nichts-Verhalten, kein Versagen bei der Suche nach einer Teilantwort.

Ist jusText aufgegeben? Der letzte Repository-Push und die letzte PyPI-Veröffentlichung liegen beide auf dem 2025-02-25 – also siebzehn Monate vor dem Test – und die PyPI-Klassifizierer enden bei Python 3.9. Aber es ließ sich auf Python 3.14.2 installieren und ohne Ausnahme ausführen, und 9 offene Issues sind kein großer Rückstand. Lesen Sie die Daten als Wartungsrisiko, nicht als Beweis für fehlerhaftes Verhalten; das praktische Risiko ist, dass Sie Ihre Bugs eventuell selbst beheben müssen.

Warum leakt es mehr Boilerplate als Readability? In diesem Fixture-Set überschritten prosaähnliche Nachbarblöcke unter den Standard-Kontextregeln die Ausgabeschwelle. Die Hochstufung hängt von Blockklasse, Distanz und Kontext ab, nicht automatisch von jedem Nachbarn. Das gemessene Ergebnis waren 47% Boilerplate-Unit-Leakage und 74 verunreinigende Tokens bei Standardeinstellungen.

Wie nutze ich es für eine andere Sprache? justext.justext(html, justext.get_stoplist("German")). get_stoplists() gibt alle 100 verfügbaren zurück. Die Stoplist ist der sprachspezifische lexikalische Input für einen Klassifikator, der außerdem Absatzlänge, Link-Dichte, aus HTML abgeleitete Segmentierung, Abstand zu Überschriften und den Kontext benachbarter Blöcke verwendet. Dadurch ändert sich die Spracheingabe; die Qualität der deutschen Extraktion ist damit noch nicht automatisch belegt.

Was wurde hier nicht getestet? Echte Seiten – hier wurden ausschließlich kontrollierte Fixtures mit gelabelten Einheiten verwendet. Die mehrsprachige Fähigkeit, das Hauptverkaufsargument der Bibliothek, wurde zwar mit 100 Stoplists inventarisiert, aber nicht auf nicht-englischem Text bewertet. Randfälle bei der Kodierung, obwohl jusText die Parameter encoding, default_encoding und enc_errors anbietet. Und max_heading_distance sowie die beiden Stopwort-Verhältnisschwellen blieben durchgehend auf Standardwerten.

Ke
Ke
CTO bei Thunderbit | Senior Data Scientist & ML-Experte Mit fast zehn Jahren Erfahrung in Machine Learning und Data Science ist Ke Shen Absolvent der Columbia University und ehemaliger Senior Data Scientist bei Walmart Labs. Mit tiefgreifender, von Fachkollegen anerkannter Expertise in Python, R, Java und Statistik teilt er praxiserprobte Einblicke dazu, wie sich komplexe KI-Algorithmen von der Theorie in eine produktionsreife Architektur überführen lassen.
Inhaltsverzeichnis
Von der Webseite zur Tabelle
Beschreibe, was du brauchst — Thunderbits KI-Agent erfasst es und exportiert es nach Excel, Google Sheets, Airtable oder Notion. Kostenlos loslegen.
Chrome Store Rating
PRODUCT HUNT#1 Product of the Week