goose3 lieferte keinen markierten Boilerplate-Inhalt zurück – und zweimal überhaupt nichts.

Zuletzt aktualisiert am August 17, 2026
goose3 lieferte keinen markierten Boilerplate-Inhalt zurück – und zweimal überhaupt nichts.
KI-Zusammenfassung
In den Fixtures, in denen sich ein Leak überhaupt definieren lässt, erreichte goose3 eine Content-Token-Präzision von 1,0000 und null störende Tokens. Kein einziges Wort aus Navigation, Werbung, Sidebar, Kommentaren oder Promo schaffte es in die Ausgabe. Kein anderes Tool im Vergleich von sechs Bibliotheken kam daran heran. Gleichzeitig hat goose3 den schlechtesten Article-Recall im Set – 0,8243 über alle 22 Fixtures hinweg, gegenüber 1,0000 bei Mozilla Readability – weil es bei zwei Fällen einfach eine leere Zeichenkette zurückgab. Diese Kennzahlen hängen durch die Bewertungsregel zusammen: Ein leeres Ergebnis trägt nichts zur bedingten Präzision bei, während der Recall den Ausfall erfasst.

In den Fixtures, in denen sich überhaupt ein Leak sinnvoll messen lässt, erreichte goose3 eine Content-Token-Präzision von 1,0000 und null störende Tokens. Kein einziges Wort aus Navigation, Werbung, Sidebar, Kommentaren oder Promo schaffte es in die Ausgabe. Kein anderes Tool im Vergleich von sechs Bibliotheken kam daran heran.

Gleichzeitig hat goose3 den schlechtesten Article-Recall im Set – 0,8243 über alle 22 Fixtures hinweg, gegenüber 1,0000 bei Mozilla Readability – weil es bei zwei Fällen einfach eine leere Zeichenkette zurückgab.

Diese Kennzahlen hängen durch die Bewertungsregel zusammen: Ein leeres Ergebnis trägt nichts zur bedingten Präzision bei, während der Recall den Ausfall erfasst.

Was goose3 ist

goose3 ist die Python-3-Fortführung einer Linie, die mit Gravity Labs' Goose in Scala begann und über python-goose weiterlief. Es ist ein Artikel-Extraktor mit Metadaten, kein reiner Text-Dumper: Man erstellt ein Goose-Objekt, ruft extract() auf und erhält ein Article-Objekt mit rund 28 zugänglichen Feldern – bereinigter Text, Titel, Autoren, Veröffentlichungsdatum, Top-Bild, Meta-Beschreibung, Tags, Links, Tweets und mehr.

Offizielle Referenz: offizielles Repository von goose3.

System diagram: From HTML to Article Fields

Getestete Version: 3.1.22, Apache-lizenziert, 912 GitHub-Sterne, zuletzt gepusht am 2026-07-23 – zum Testzeitpunkt aktiv gepflegt. Python 3.14.2.

Die API besteht aus zwei Aufrufen und einer Pflicht:

from goose3 import Goose
g = Goose()
try:
    article = g.extract(raw_html=html)
    text = article.cleaned_text
finally:
    g.close()          # nach der Nutzung explizit schließen

Dieses close() ist erwähnenswert, weil es leicht vergessen wird und keine Warnung erscheint. In diesem Review wurde kein Schleifen-Test ausgeführt, um festzustellen, ob beim Unterlassen des Schließens Sitzungen, Verbindungen oder Speicher dauerhaft hängen bleiben; „Resource Leak“ wäre also stärker als die Beweislage. Behandeln Sie das explizite Schließen als Lebenszyklus-Anforderung, die durch die API-Nutzung hier vorgegeben ist.

Der Kompromiss, gemessen

Sechs Extraktoren, ein annotiertes Fixture-Set, ein Scorer. Jeder Block jedes Fixtures ist als article oder boilerplate markiert und trägt ein eindeutiges Sentinel-Token, sodass „hat es diese Einheit wiedergefunden“ als exakte Substring-Mitgliedschaft statt als Ähnlichkeitsscore gemessen wird.

BibliothekArticle-Recall (alle 22)Boilerplate-LeakContent-Token-PräzisionStörende TokensAusgabe erzeugt
Readability1.00000.23530.91093522/22
trafilatura0.98650.05880.9411422/22
newspaper4k0.98650.00000.9452022/22
resiliparse0.90540.05880.9381722/22
jusText0.83780.47060.87607419/22
goose30.82430.00001.0000020/22

sixway-scores.json. Der Recall bezieht sich auf alle 22 Fixtures; Leak-Rate und Präzision auf die 11, die sowohl Artikel- als auch Boilerplate-Einheiten enthalten.

Lesen Sie die Präzisionsspalte immer zusammen mit der letzten Spalte. Präzision ist hier bedingt durch die Ausgabe – eine Bibliothek, die bei einem Fixture eine leere Zeichenkette zurückgibt, trägt weder zum Zähler noch zum Nenner bei; ein Ausweichen ist also in diesem Durchschnitt kostenlos. Der Zähler ist die Überschneidung als Multimenge zwischen extrahierten Nicht-Stoppwort-Tokens und markierten Artikel-Tokens; der Nenner sind alle extrahierten Nicht-Stoppwort-Tokens. „Störende Tokens“ ist enger gefasst: die Überschneidung nur mit den markierten Boilerplate-Tokens. Ein zusätzlich extrahiertes Token, das weder mit markierten Artikel- noch mit Boilerplate-Tokens übereinstimmt, senkt die Präzision, ohne diese Störungszahl zu erhöhen; dasselbe kann auch bei mehrfach vorkommenden Tokens jenseits der Artikel-Multimenge passieren. Deshalb kann newspaper4k 0 störende Tokens und trotzdem eine Präzision unter 1,0000 zeigen. goose3s 1,0000 wurde auf 10 der 11 Fixtures erzielt; Readability, trafilatura, newspaper4k und resiliparse wurden auf 11 von 11 bewertet.

Die 1,0000 bleibt innerhalb dieses synthetischen Sets nützlich. Über die zehn bewerteten Fixtures hinweg lieferte goose3 keines der markierten Boilerplate-Tokens; Readability lieferte auf denselben Seiten 35 davon. Wenn ein Modell die Ausgabe verarbeitet, bedeutet das: In diesen zehn Fixtures wurden keine Tokens für die Boilerplate-Labels verbraucht. Das belegt jedoch keinen Null-Abfall auf realen Seiten, und ein leeres Ergebnis kann an anderer Stelle in der Pipeline zusätzliche Fallback- oder Retry-Kosten verursachen.

Die zwei Schweigen – und was sie bedeuten

goose3 gab in genau zwei Fixtures nichts zurück. Eines davon ist vertretbar, das andere eine echte Grenze.

Das fast leere Dokument. Eine Seite mit genau einer 32-Zeichen-Artikel-Einheit. goose3 lehnt ab. jusText ebenfalls. In diesem Fixture-Set lieferte Readability auf allen 22 Seiten Ausgabe; sein Ergebnis stützt also goose3s Schweigen hier nicht. Ob die Ablehnung dieses winzigen Dokuments akzeptabel ist, hängt vom Mindestinhalt-Vertrag des Aufrufers ab.

System diagram: Treat Empty Output as Failure

Der Artikel, der ausschließlich aus <li>-Elementen besteht. Sechs Artikel-Einheiten, keine davon in einem <p>-Tag. goose3 gibt eine leere Zeichenkette zurück.

Dieser zweite Fall hat mich stutzig gemacht, denn goose3s Standardkonfiguration setzt parse_lists=True. Also habe ich es überprüft – drei Konfigurationen gegen ein funktionierendes Gegenbeispiel, denn ein einzelner erfolgloser Lauf ist noch kein Befund über eine Bibliothek:

KonfigurationSeite nur mit Listen<p>-Kontrolle
Standardwerte0 Zeichen937 Zeichen
strict=False0 Zeichen937 Zeichen
parse_lists=True (explizit)0 Zeichen937 Zeichen

list-only-probe.json.

In allen drei Fällen Null, während die Kontrolle in allen drei Fällen 937 Zeichen zurückgibt. parse_lists=True entscheidet also darüber, ob Listen innerhalb eines bereits gefundenen Artikels erhalten bleiben – es erlaubt dem Kandidaten-Scorer nicht, eine Liste selbst als Artikel zu behandeln. Das Knotenscoring von goose3 braucht blockartige Absätze, um den Haupttext überhaupt zu finden; eine Seite, deren Haupttext aus Listen besteht, hat diese nicht.

Das belegte Ergebnis ist enger: Ein Body, der wie dieses synthetische Fixture aufgebaut ist – sechs Artikel-Einheiten, alle <li>, ohne Absatzkandidat – gab eine leere Zeichenkette zurück. Changelogs, API-Referenzen, Rezepte, FAQ-Seiten und Vergleichsbeiträge sind sinnvolle Risikobeispiele für einen Real-Page-Replay, weil sie stark listenlastig sein können; aber dieses eine Fixture belegt nicht, dass diese Seitentypen generell scheitern.

Die leere Zeichenkette ist nur dann maschinell erkennbar, wenn der Aufrufer nichtleere Ausgaben validiert. Das lässt sich leichter absichern als plausibel wirkender Text, der keinen Artikelinhalt enthält – trotzdem ist es bei reinen Exception-Monitorings ein stilles Versagen. Ein produktiver Aufruf braucht daher eine Mindestlängenprüfung und einen Fallback oder einen expliziten Datensatz für fehlgeschlagene Seiten.

Installationsrealität

pip install goose3 zieht 16 Pakete und 44,3 MiB in etwa 6 bis 9 Sekunden nach. Der Cold Import in einem frischen Subprozess lag bei 2,181 s.

Offizielle Referenz: goose3 auf PyPI.

BibliothekPaketesite-packagesCold ImportExtraktions-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 lief in einer eigenen leeren Virtualenv, es wurde also nichts von einer Nachbarbibliothek vererbt.

Gewichtsmäßig im Mittelfeld, bei der Geschwindigkeit ebenfalls. Die Installation und der Import liefen sauber auf Python 3.14.2, was in dieser Kategorie nicht selbstverständlich ist.

Drei Standardwerte, die Sie vor dem Rollout kennen sollten

System diagram: Three defaults worth knowing before you deploy

Wer das gelieferte Configuration-Objekt statt der Dokumentation liest, findet 19 Einstellungen. Drei davon werden jemanden überraschen.

Es meldet sich selbst an. browser_user_agent steht standardmäßig auf Goose/3.1.22. Wenn goose3 selbst die Abrufe übernimmt, protokolliert jeder angesprochene Server Bibliotheksnamen und exakte Version. Das ist ehrlich, aber auch ein Fingerabdruck. Setzen Sie ihn bewusst oder holen Sie das HTML selbst und übergeben Sie raw_html.

Es verweist auf ein MacPorts-Binary. imagemagick_convert_path ist standardmäßig /opt/local/bin/convert und imagemagick_identify_path /opt/local/bin/identify. Auf meinem Rechner existiert beides nicht – /opt/local gehört zu MacPorts, das die meisten nicht installiert haben; Homebrew legt Binaries unter /opt/homebrew ab. Der Standard bleibt wirkungslos, solange Sie das Bild-Fetching nicht aktivieren (enable_image_fetching ist sinnvollerweise standardmäßig False), aber wenn Sie es einschalten und auf Top-Image-Extraktion hoffen, funktioniert es hier stillschweigend nicht.

Es geht von Englisch aus. target_language steht auf en, bei use_meta_language=True; goose3 folgt also einer Sprachdeklaration der Seite, wenn vorhanden, und fällt sonst auf Englisch zurück. Für englische Inhalte okay, für alles andere sollte man es explizit setzen.

Der Rest ist vernünftig: parser_class ist lxml, http_timeout 30 Sekunden, strict aktiv, log_level ERROR, parse_headers und keep_footnotes aktiv, images_min_bytes 4.000.

Speicher – und was kaputtes HTML damit macht

Zwei Dinge, die in jedem Review dieser Reihe als ungetestet markiert waren, sind nun gemessen.

Den größeren Stress-Test-Kontext finden Sie im Vergleich zu Speicherverbrauch und fehlerhaftem HTML mit zehn Bibliotheken.

Maximaler residenter Speicher, gemessen mit /usr/bin/time -l, ein frischer Prozess pro Zelle – die Import-Basis ist das, was die Bibliothek geladen und im Leerlauf kostet, die Spitzen enthalten das Dokument.

BibliothekLaufzeitImport-Basis226 KB Spitze10 MB Spitze
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 untereinander nicht vergleichbar; der Interpreter steckt in beiden Messungen.

goose3s Basis liegt bei 44,1 MiB und es erreicht auf einem 10-MB-Dokument 398,5 MiB. Die Import-Basis ist die dritthöchste unter den gezeigten Python-Bibliotheken, was für deployments mit sensiblen Startzeiten wichtig ist.

Defektes HTML. Zwölf Dokumente, die jeweils genau eine Sache kaputt machen – nicht geschlossene Tags, falsch verschachtelte Inline-Elemente, nicht in Anführungszeichen gesetzte Attribute mit Leerzeichen, übrig gebliebene Schließtags, gar kein <html>, doppelte Attribute, ein mitten im Tag abgeschnittenes Dokument, fehlerhafte Entities, ein nicht geschlossenes <script>, eine falsche Charset-Deklaration, ein Kommentar mit Markup und 600 Verschachtelungsebenen – plus zwei wohlgeformte Kontrollen in passender Größe, denn „es gab nichts zurück“ sagt über fehlerhaftes HTML nur dann etwas, wenn die Bibliothek bei einem sauberen Dokument derselben Größe nicht ebenfalls schweigt.

goose3 warf bei 0 von 14 einen Fehler und gab bei 10 nichts zurück; es stellte 2/33 Sentinel-Werte aus den defekten Fixtures wieder her (malformed-results.json). Ein Fixture ist aus dieser Zählung ausgeschlossen: Nach HTML5 ist alles nach einem nicht geschlossenen <script> tatsächlich Script-Inhalt; dass es dort verloren geht, ist also korrekt, und das Wiederherstellen wäre die Abweichung.

Vor- und Nachteile

Dafür spricht es. Null markierte Boilerplate-Tokens in den zehn Content-Fidelity-Fixtures, in denen Ausgabe erzeugt wurde. Rund 28 Artikel-Felder sind verfügbar, auch wenn ihre Genauigkeit hier inventarisiert und nicht bewertet wurde. Sinnvolle Standard-Einstellung fürs Bild-Fetching (aus). Saubere Installation auf Python 3.14. Aktiv gepflegt. Apache-2.0. Ein leeres Ergebnis lässt sich klar abfangen, wenn der Aufrufer es explizit prüft.

Dagegen spricht es. Der niedrigste Article-Recall im Set mit 0,8243, vollständig verursacht durch „überhaupt nichts zurückgeben“ statt durch „das Falsche zurückgeben“. Eine Seite, deren Artikel nur aus Listen besteht, erzeugt unabhängig von der Konfiguration eine leere Zeichenkette. 44,3 MiB und ein Cold Import von 2,2 Sekunden sind schwer im Vergleich zu resiliparse mit 21,0 MiB und 15 ms. Erfordert close(). Zwei Standardwerte zeigen auf Dinge, die auf den meisten Maschinen falsch sind.

Wer es nutzen sollte – und wer nicht

goose3 nutzen Sie als Kandidaten, wenn extrahierter Text in ein Modell oder eine Datenbank fließt, in der markierte Boilerplate teuer ist, und wenn die Seiten konventionelle Artikel mit Absätzen sind. In diesem Fixture-Set lieferte es bei erfolgreicher Antwort keine markierten Boilerplate-Tokens. Die Metadaten-Oberfläche ist vorhanden, wurde hier aber nicht validiert; Titel-, Autoren-, Datums- und Bildgenauigkeit brauchen eigene Ground-Truth-Fixtures, bevor sie als Auswahlvorteil gelten.

Überspringen Sie es, wenn Ihr Korpus stark listenlastig ist – dann erhalten Sie leere Zeichenketten ohne Erklärung. Überspringen Sie es, wenn die Startzeit wichtig ist; resiliparse importiert 145-mal schneller. Und überspringen Sie es, wenn Sie auf jeder Seite eine Antwort brauchen, denn „keine Antwort“ ist hier ein reales Ergebnis: zwei von 22 Fixtures, und beide still, insofern eine leere Zeichenkette keine Exception ist.

Eine lohnende Kombination zum Testen: goose3 als Primärlösung mit Fallback, wenn cleaned_text leer ist oder unter Ihrer Mindestinhalts-Regel liegt. Readability stellte in diesem 22-Fixture-Set alle Artikeleinheiten wieder her, einschließlich beider leeren Fälle von goose3. Dieses synthetische Ergebnis stützt das Architektur-Muster, nicht die Behauptung, dass der Fallback auf echten Seiten nie danebenliegt.

Wo eine Managed API ins Bild passt

Dieser Benchmark testete den raw_html-Pfad von goose3: Das HTML war bereits beschafft, bevor goose3 es sah. goose3 hat auch einen eigenen Fetch-Pfad, wie die User-Agent-Einstellung zeigt, aber dieser Pfad wurde hier nicht getestet. JavaScript-Rendering und Anti-Bot-Verhalten wurden ebenfalls nicht geprüft.

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

Ein verwalteter Fetch-/Render-/Extraktionsdienst, einschließlich unseres eigenen Thunderbit, deckt eine andere Verantwortungsebene ab. Thunderbit wurde in diesem Test nicht benchmarked. Der relevante Unterschied ist: bereitgestelltes HTML artikelartig extrahieren versus ein gehosteter Dienst, der eine URL abruft und verarbeitet; dieser Artikel liefert keinen Vergleich auf gleicher Metrikbasis zu Qualität oder Leistung.

Der faire Vergleich: goose3 hat ein festes, artikelorientiertes Feldset – genau richtig, wenn Ihre Seiten Artikel sind, und falsch, wenn es Produktlisten sind. Wenn Sie das HTML bereits haben und Ihre Seiten Artikel sind, ist goose3 kostenlos und sehr sauber.

Für den gehosteten Bereich ist unser Überblick über Web-Scraping-APIs die breitere Perspektive; für selbst gehostete Alternativen der Open-Source-Scraper-Leitfaden. Wenn der Text in ein Modell geht, zeigt HTML in Python nach Markdown konvertieren, wo Fidelity tatsächlich verloren geht.

Thunderbit für Web-Datenextraktion ausprobieren

Sollten Sie goose3 verwenden?

Ja, wenn artikelartige Absätze zu Ihrem Workload passen und der Aufrufer leere Ausgaben als Fehlextraktion und nicht als Erfolg behandelt.

In diesem Fixture-Set lieferte goose3 bei Erfolg keine markierten Boilerplate-Tokens und zwei leere Zeichenketten zurück. Eine war eine fast leere Seite, die andere der reine Listen-Body. Das ist ein Trade-off zwischen Präzision und Abdeckung, kein Beleg für ein generelles Produktverhalten.

Wenn Recall wichtiger ist, testen Sie einen Fallback mit einer expliziten Mindestlängenprüfung. Readability stellte in diesen 22 Fixtures alle Artikeleinheiten wieder her; newspaper4k zeigte null markierte Boilerplate-Einheiten und 0,9865 Recall bei Ausgabe auf allen 22 Seiten. Diese Ergebnisse ordnen dieses synthetische Set nach Standardwerten ein, nicht unbekannte Produktions-Workloads.

goose3 verdient seinen Platz, wenn die Kosten eines falschen Wortes höher sind als die Kosten einer fehlenden Seite.

Thunderbit für Web-Datenextraktion ausprobieren Get Started Free

FAQs

Ist goose3s perfekte Präzision echt oder nur ein Effekt davon, dass es oft ablehnt? Beides, und beides lässt sich trennen. Bewertet wurde es auf 10 der 11 Fixtures mit Boilerplate, also fehlt ein Fixture im Durchschnitt – das ist der Ablehnungs-Effekt. Aber auf diesen zehn lieferte es null störende Tokens gegen absichtlich adversariale Boilerplate, während Readability 35 davon durchsickern ließ. Die Präzision ist für Seiten, die goose3 beantwortet, real; der Recall zeigt den Effekt des Ablehnens.

Warum gibt goose3 auf einer Seite nichts zurück, deren Artikel aus einer Liste besteht? Das Kandidaten-Scoring braucht absatzartige Blöcke, um den Artikelkörper zu finden, und eine Seite aus <li>-Elementen hat solche nicht. Der Standard parse_lists=True ändert daran nichts – ich habe es ausdrücklich getestet, ebenso strict=False, und in allen drei Konfigurationen 0 Zeichen erhalten, während eine <p>-Kontrolle in allen drei Fällen 937 zurückgab. parse_lists entscheidet nur, ob Listen innerhalb eines bereits gefundenen Artikels erhalten bleiben.

Muss ich close() aufrufen? Ja, und zwar explizit mit try/finally, wie oben gezeigt. Dieses Review hat nicht gemessen, was sich bei fehlendem Schließen ansammelt, und behauptet deshalb keinen quantifizierten Schleifen-Leak; es zeigt aber, dass Goose einen Lebenszyklus hat, den der Aufrufer verwalten muss.

Welchen User-Agent sendet goose3? Standardmäßig Goose/3.1.22 – also Bibliotheksname und exakte Version. Das gilt nur, wenn goose3 selbst abruft; bei Übergabe von raw_html entfällt es komplett. Wenn Sie goose3 abrufen lassen, setzen Sie den User-Agent bewusst; der Standard verrät jedem Server genau, was anklopft.

Was hat dieses Review nicht getestet? Reale Webseiten – überhaupt nicht; es handelt sich um kontrollierte Fixtures. Mehrsprachige Extraktion, obwohl target_language eine First-Class-Einstellung ist. Die Metadaten-Felder (Titel, Autoren, Datum, Top-Bild) wurden inventarisiert, aber nicht auf Genauigkeit bewertet. Bild-Fetching, das standardmäßig aus ist und dessen ImageMagick-Pfade auf einen Paketmanager zeigen, den die meisten Maschinen nicht haben. Gleichzeitiges oder anhaltendes Speicherverhalten sowie Durchsatz unter Last; die Speichertabelle misst einen frischen Prozess mit einem Dokument.

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