Najpopularniejsza biblioteka HTML do Markdown nie konwertuje tabel

Ostatnia aktualizacja: August 17, 2026
Najpopularniejsza biblioteka HTML do Markdown nie konwertuje tabel
Podsumowanie AI
turndown był najczęściej oznaczoną gwiazdką spośród czterech testowanych bibliotek w momencie wykonania zrzutu metadanych, z 11 386 gwiazdkami na GitHubie. Na czterech wspólnych próbkach HTML wygenerował zero tabel Markdown przy domyślnych ustawieniach i zużył o 24,6% więcej tokenów niż markdownify dla tych samych danych wejściowych. Każda z czterech bibliotek odzyskała wszystkie sygnały treści. Różnice dotyczą wyłącznie tego, co dzieje się ze strukturą — i ile ta struktura kosztuje później. Karmisz model albo zapisujesz ustrukturyzowaną treść z takich stron? Zacznij od markdownify. W tym liczniku ma taki sam wynik jak markitdown pod względem liczby wygenerowanych wierszy tabel, mieści się w najniższym klastrze tokenów, ma licencję MIT i instaluje się w 1.8 MiB.

turndown był najczęściej oznaczoną gwiazdką spośród czterech testowanych bibliotek w momencie wykonania zrzutu metadanych — miał 11 386 gwiazdek na GitHubie. Na czterech wspólnych próbkach HTML wygenerował zero tabel Markdown przy domyślnych ustawieniach i zużył o 24,6% więcej tokenów niż markdownify dla tych samych danych wejściowych.

Każda z tych czterech bibliotek odzyskała wszystkie sygnały treści. Różnice dotyczą wyłącznie tego, co dzieje się ze strukturą — i ile ta struktura kosztuje później.

Co było mierzone i na jakich próbkach

Ta baza badawcza miała już zestaw dla markitdown z pięcioma próbkami HTML i wcześniej zarejestrowanymi probe strings — dokładnymi ciągami sprawdzanymi pod kątem zachowania oraz ciągami pomocniczymi do wykrywania elementów chromu strony. Do porównania zbiorczego użyto czterech próbek wspólnych dla wszystkich czterech konwerterów: katalogu księgarni, strony z cytatami, tabeli statystyk hokejowych i artykułu Wikipedii o web scraping. Piąta próbka, Nothing but tables, służy wyłącznie jako diagnostyka mocno tabelaryczna i jest wyłączona z agregatu 24,6%.

Cztery narzędzia: turndown 7.2.4 (Node), markdownify 1.2.3, html2text 2025.4.15 oraz markitdown, którego opublikowane wyniki wykorzystano bez zmian. Strony: katalog księgarni, strona z cytatami, tabela statystyk hokejowych i artykuł Wikipedii o web scrapingu.

Każda nazwa metryki poniżej odpowiada dokładnie polu artefaktu markitdown, więc wiersze można zestawić obok siebie bez uzgadniania dwóch definicji tego samego pojęcia.

Tabela

Measured results chart: Token output vs Markdown table rows

KonwerterSygnały treściZnaki wyjścioweTokeny (o200k)Bajty/tokenWiersze tabel MarkdownLinki
turndown16/1695,18826,2363.630611
markdownify16/1676,86821,0623.6536599
html2text16/1676,45221,1763.6132545
markitdown16/1676,99521,3363.6136598

Cztery próbki — te same, które uruchomiono również dla markitdown. Pełne wyniki dla każdej próbki znajdują się w fiveway-scores.json. Tokeny policzono z użyciem o200k_base; wiersze tabel markitdown przeliczone z jego własnego zapisanego Markdowna tym samym licznikiem, co pozostałe.

Zachowanie treści jest remisowe. Wszystkie szesnaście sygnałów treści na czterech próbkach przetrwało w każdym konwerterze. Jeśli jedyne pytanie brzmi: „czy tekst przejdzie dalej?”, każdy z tych czterech odpowiada: tak.

Struktura nie jest remisowa. Na czterech wspólnych próbkach markdownify i markitdown generują po 36 wierszy tabel Markdown; html2text generuje 32; turndown nie generuje żadnego. W osobnej diagnostyce zawierającej wyłącznie tabele markdownify wygenerował 62 wiersze, a html2text 59; tych wierszy nie wliczono do agregatu powyżej.

Koszt tokenów dla turndown jest o 24,6% wyższy, ale powód nie leży w tabelach. Początkowo tak zakładałem, jednak liczby dla poszczególnych próbek pokazują coś innego — patrz niżej.

Co turndown robi z tabelą

Oto próbka ze statystykami hokejowymi — te same wiersze pokazane na trzy sposoby.

turndown:

System diagram: Core Table Paths Diverge

Team Name

Year

Wins

Losses

Boston Bruins

1990

44

24

markdownify:

| Team Name | Year | Wins | Losses | ... |
| --- | --- | --- | --- | --- |
| Boston Bruins | 1990 | 44 | 24 | ... |

html2text:

Team Name  |  Year  |  Wins  |  Losses  | ...
---|---|---|---|---
Boston Bruins  |  1990  |  44  |  24  | ...

Każda wartość przechodzi przez konwersję turndown, dlatego narzędzie zdobywa 16/16 w sygnałach. To, co ginie, to informacja o tym, do której kolumny należy dana wartość. Wystarczy spojrzeć na wynik turndown, a 44 staje się po prostu liczbą w osobnej linii; nie da się już odtworzyć, że chodzi o liczbę zwycięstw Bostonu, chyba że zaczniemy liczyć pozycje i założymy, że żadne pole nie było puste. W tej próbce niektóre pola puste, więc samo liczenie pozycji też nie wystarczy.

Dla modelu czytającego wynik oznacza to różnicę między tabelą, na której da się odpowiadać na pytania, a listą liczb, które model będzie zgadywać.

To nie tyle wada, co udokumentowane ograniczenie — rdzeń turndown nie obsługuje tabel, a turndown-plugin-gfm istnieje właśnie po to, by je dodać. Jednak domyślna instalacja nie zawiera tego dodatku, a 11 386 gwiazdek sugeruje, że wiele osób korzysta właśnie z ustawień domyślnych.

Skąd naprawdę bierze się luka tokenowa

Napisałem akapit powyżej, zakładając, że różnica 24,6% tokenów wynika ze spłaszczonych tabel pojawiających się jako znaki. Potem spojrzałem na wyniki per próbka — i to nie jest prawda.

Próbkaturndown tokeny ÷ markdownify tokeny
Strona z cytatami (bez tabel)0.99×
Katalog księgarni1.06×
Statystyki hokejowe (jedna duża tabela)1.37×
Wikipedia (głównie proza, 9 wierszy tabel)1.29×
Wyłącznie tabele0.78×

W próbce, która zawiera wyłącznie tabele, turndown jest o 22% tańszy — ponieważ obramowanie w postaci pionowych kresek też kosztuje tokeny, a turndown ich po prostu nie generuje. Samo spłaszczenie tabeli nie jest więc automatycznie karą tokenową.

Próbka z Wikipedii stanowi 74% całości i zawiera dziewięć wierszy tabel. Jej luka licząca 15 378 znaków nie może wynikać z tabel. To jest to:

(function(){var className="client-js vector-feature-language-in-header-enabled…
.mw-parser-output cite.citation{font-style:inherit;word-wrap:break-word}…
(RLQ=window.RLQ||[]).push(function(){mw.config.set({"wgHostname":"mw-web…

turndown nie usuwa treści z <script> i <style>. markdownify i html2text usuwają ją oba. Zliczając znaczniki występujące wyłącznie wewnątrz tych elementów: wynik turndown zawiera 10 znaczników script i 84 znaczniki style we wszystkich próbkach; pozostałe dwa konwertery nie zawierają żadnego z nich. Na stronie Wikipedii osiem linii wewnętrznej konfiguracji JavaScript i CSS MediaWiki odpowiada za 14 644 znaki — 95% całej różnicy (script-style-stripping.json).

To jest wniosek, z którym faktycznie bym pracował. Spłaszczona tabela to problem struktury, który widać. Blok konfiguracji JavaScript w Markdownzie to czysty koszt bez żadnej informacji, a na rzeczywistej stronie internetowej przytłacza wszystko inne w tym porównaniu.

html2text zapisuje tabele, których możesz nie rozpoznać

html2text uzyskał 32 wiersze tam, gdzie markdownify i markitdown miały 36, a pierwsza wersja mojego licznika oceniła go na 1.

To była wada mojego liczenia, nie biblioteki. html2text generuje Team Name | Year | Wins bez zewnętrznych pionowych kresek — to poprawna forma tabeli Markdown, ale niewidoczna dla regexu, który wymaga ^\|.*\|$. Napisałem taki regex, uruchomiłem go i byłem gotów ogłosić, że html2text nie obsługuje tabel.

Obsługuje. Poprawiony licznik używa heurystyki: ciągu kolejnych linii zawierających pionowe kreski oraz wiersza separatora wewnątrz tego ciągu. Dzięki tej regule html2text przechodzi z 1 do 32. To nie jest pełny parser Markdown, więc liczbę wierszy trzeba czytać jako pomiar wykonany według opisanego licznika, a nie jako uniwersalny wynik renderowania.

Warto to wiedzieć, jeśli dalej przetwarzasz Markdown własnym regexem: dwie z tych czterech bibliotek dodają zewnętrzne kreski, a jedna nie.

O licencji, o której nikt nie mówi

KonwerterLicencjaInstalacjaCiepły importGwiazdkiOstatnie wydanie
turndownMIT3 pakiety npm, 8,8 MiB0.056 s11,3862026-04-03
markdownifyMIT5 pakietów, 1.8 MiB0.046 s2,2352026-06-30
html2textGPL-3.0-or-later1 pakiet, 0.2 MiB0.077 s2,1682025-04-15
markitdownZobacz metadane pakietuNie mierzone w tej instalacjiNie mierzone

install-and-import.json. Każdą bibliotekę zainstalowano w osobnym, pustym środowisku. Licencje potwierdzono w trzech miejscach: w metadanych rejestru, w repozytorium GitHub i w pliku METADATA samego zainstalowanego pakietu, który zawiera wpis License-Expression: GPL-3.0-or-later.

Najlżejsza biblioteka w tym porównaniu instalacji — 1 pakiet, 0.2 MiB — ma licencję GPL-3.0-or-later. Czy to ma znaczenie dla projektu, zależy od tego, jak oprogramowanie jest łączone i dystrybuowane. Traktuj to jako punkt decyzyjny dla osoby odpowiedzialnej za licencje; ten artykuł nie stanowi porady prawnej. markitdown pokazano tutaj jako niezmierzone, ponieważ jego instalacja i licencja nie zostały uchwycone przez ten konkretny artefakt.

Tę różnicę łatwo przeoczyć, bo licencja to jedyna właściwość, która nie pojawia się w benchmarku.

Wszystkie trzy są wyraźnie lżejsze niż biblioteki do ekstrakcji artykułów z tej samej kategorii — tamte zajmują od 21 do 70 MiB. Konwerter to dużo mniejszy element niż ekstraktor i warto rozdzielać je w budżecie zależności.

Dwa czynniki zakłócające, które musiałem naprawić, zanim ta tabela stała się prawdziwa

Powyższe liczby pochodzą z trzeciej wersji. Pierwsze dwie były błędne w sposób wart nazwania, bo oba błędy łatwo odtworzyć.

Pięć próbek kontra cztery. markitdown uruchomiono na czterech z tych pięciu plików; pozostałe trzy biblioteki przeszły wszystkie pięć. Zsumowanie wyników każdego narzędzia dla jego własnego zestawu dało markdownify 98 wierszy tabel wobec 36 markitdown i wyglądało jak luka w możliwościach. Na tych samych czterech próbkach wynik wynosi 36 wobec 36 — dokładny remis. Piąta próbka jest tą najbardziej tabelaryczną, więc zakłócenie działało w najgorszym możliwym kierunku, zawyżając wynik nowych narzędzi względem istniejącego niemal trzykrotnie.

System diagram: Make the Comparison Comparable

Dwa liczniki, jedna kolumna. Opublikowane md_table_rows markitdown pochodziło z jego własnego kodu, którego nie czytałem. Porównywanie tej liczby z moją mogło oznaczać porównywanie dwóch liczników, a nie dwóch konwerterów. Jego Markdown był zapisany na dysku, więc poprawka polegała na uruchomieniu jednego licznika na wszystkich czterech — i gdy to zrobiłem, przeliczenie markitdown dało dokładnie opublikowaną wartość dla każdej próbki (0, 0, 27, 9). Definicje się zgadzały; po prostu nie mogłem tego wiedzieć bez sprawdzenia.

Żaden z tych błędów nie byłby widoczny w samym wyniku. Oba dałyby pewną siebie, błędną tabelę.

Kto powinien używać czego

Karmisz model albo zapisujesz ustrukturyzowaną treść z takich stron? Zacznij od markdownify. W tym liczniku ma taki sam wynik jak markitdown pod względem liczby wygenerowanych wierszy tabel, mieści się w najniższym klastrze tokenów, ma licencję MIT i instaluje się w 1.8 MiB. Zweryfikuj go na własnych typach stron, zanim ustandaryzujesz wybór.

Budżet zależności liczysz w kilobajtach i niczego nie dystrybuujesz? html2text. Jeden pakiet, 0.2 MiB, tabele zachowane. Najpierw sprawdź kwestię GPL i pamiętaj, że ostatnie wydanie było w kwietniu 2025.

Już pracujesz w stosie Node? turndown, z zainstalowanym obok turndown-plugin-gfm — i usuń <script> oraz <style> z HTML zanim przekażesz go dalej, bo turndown sam tego nie zrobi. Te dwa braki kosztują jedną czwartą więcej tokenów i strukturę tabel, a nie widać ich, dopóki nie zajrzysz do wyniku.

Już konwertujesz inne formaty dokumentów? markitdown obsługuje PDF, Office i inne formaty, a jego wynik HTML jest konkurencyjny wobec dedykowanych konwerterów. Jeden zależny komponent zamiast dwóch też ma swoją wartość.

Gdzie pasuje zarządzane API

Wszystkie cztery narzędzia pracują na HTML-u, który już masz. Żadne nie pobiera strony, nie renderuje JavaScriptu ani nie obsługuje warstwy anty-bot — a dla wielu rzeczywistych celów to właśnie trudniejsza połowa.

Nasz własny stack developerski w Thunderbit obejmuje tę stronę problemu. POST /distill przyjmuje URL i zwraca czysty Markdown gotowy dla LLM, z obsługą renderowania i pobierania; POST /extract zwraca ustrukturyzowany JSON dopasowany przez AI do dostarczonego przez Ciebie JSON Schema, czyli zupełnie inny kształt wyjścia — wiersze zamiast tabeli Markdown, którą trzeba by potem parsować. Oba są dostępne przez serwer MCP i CLI (npx @thunderbit/thunderbit-cli). Cennik znajduje się na stronie cennika Thunderbit.

Uczciwe porównanie: jeśli masz HTML i chcesz Markdown, markdownify jest darmowy i robi to dobrze, a ta tabela pokazuje, które z konkurencyjnych narzędzi też sobie z tym radzą. Jeśli to Ty pobierasz strony albo chcesz ustrukturyzowanych wierszy zamiast tekstu, to już inny zakup.

Szerzej o rynku piszemy w naszym zestawieniu API do web scrapingu, a przegląd open-source scraperów obejmuje rozwiązania self-hosted. Konwersja HTML do Markdown w Pythonie to praktyczny przewodnik, a czym ma być standaryzacja llms.txt pokazuje, dokąd zmierza cała ta kategoria.

Wypróbuj Thunderbit do ekstrakcji danych z sieci

Werdykt

W tym obciążeniu obejmującym cztery próbki najlepszym domyślnym wyborem jest markdownify: taka sama liczba wygenerowanych wierszy tabel jak markitdown przy wspólnym liczniku, liczba tokenów w granicach 1,3% od pozostałych wydajnych konwerterów, licencja MIT i instalacja zajmująca 1.8 MiB.

Ta rozbieżność między popularnością a zmierzonym zachowaniem jest właściwym wnioskiem. turndown to świetna biblioteka, którą bardzo wiele osób zainstalowało bez wtyczki, która dodaje obsługę tabel, a koszt tego wyboru widać jako o jedną czwartą więcej tokenów i strukturę tabel, której już nie ma. Żadna z tych liczb nie pojawia się nigdzie, dopóki się ich nie policzy.

Jeśli masz zapamiętać tylko jedno: sprawdź, co Twój konwerter robi z tabelą, zanim zaufasz jego wynikowi w modelu. Trzy z tych czterech robią coś sensownego. Najpopularniejszy — nie, chyba że wyraźnie o to poprosiłeś.

Wypróbuj Thunderbit do ekstrakcji danych z sieci Get Started Free

FAQ

Czy turndown naprawdę nie obsługuje tabel? W swoim rdzeniu — nie. Tabele pochodzą z turndown-plugin-gfm, czyli osobnego pakietu, a zwykłe npm install turndown nie dołącza tego dodatku. Bez wtyczki każda komórka przechodzi jako osobny akapit — wartości są zachowane, ale relacje wiersz-kolumna już nie. W czterech próbkach dało to zero wierszy tabel Markdown i o 24,6% więcej tokenów niż markdownify dla tych samych danych.

Dlaczego html2text początkowo wyglądał tak, jakby nie miał tabel? Bo mój licznik wymagał zewnętrznych pionowych kresek, a html2text ich nie generuje. Team Name | Year | Wins to poprawny Markdown i renderuje się prawidłowo; to po prostu inny styl niż | Team Name | Year |. Poprawiony licznik szuka ciągu linii zawierających pionowe kreski z wierszem separatora, tak jak robi to parser, i html2text przechodzi z 1 wiersza do 32. Jeśli przetwarzasz Markdown własnym regexem, właśnie na tej różnicy się potkniesz.

Czy GPL w html2text to realny problem? To zależy od tego, jak łączysz i dystrybuujesz oprogramowanie. GPL-3.0-or-later może nakładać obowiązki, których MIT nie nakłada, więc przed wyborem do produktu dystrybuowanego skonsultuj to z osobą odpowiedzialną za licencje. To punkt zgodności, nie porada prawna; tożsamość licencji została potwierdzona w metadanych rejestru, repozytorium i pliku METADATA zainstalowanego pakietu.

Czy te liczby tokenów mają znaczenie także dla innych stron? Różnica 24,6% wynika głównie z tego, że turndown zachowuje treść z <script> i <style>, więc skala zależy od tego, ile dana strona tego ma — dużo na nowoczesnym CMS-ie, niemal zero na statycznej. Tabele działają w drugą stronę: w próbce zawierającej wyłącznie tabele turndown był o 22% tańszy, bo nie generuje żadnego obramowania w postaci pionowych kresek. Bajty na token mieściły się między 3.61 a 3.65 we wszystkich czterech narzędziach, więc gęstość wyjścia jest wszędzie podobna, a różnica dotyczy ilości. Jeśli liczba ma wpływ na budżet, zmierz własny korpus.

Czego tutaj nie testowano? Różnorodności z prawdziwego świata — cztery próbki to tylko cztery próbki. Zagnieżdżonych list, list definicyjnych, przypisów i matematyki. Błędnego HTML-a, bo właśnie tam konwertery historycznie najbardziej się różnią. Przetwarzania Markdown z powrotem do HTML. docling, który ma te same próbki na dysku, ale w opublikowanym przebiegu nie raportuje tych pól, więc został pominięty, a nie oszacowany. I konfiguracji: html2text uruchomiono z body_width=0, ponieważ domyślne 78 zawija każdą linię, co zmieniłoby każdy znak i każdą liczbę tokenów w tej tabeli.

Ke
Ke
CTO w Thunderbit | Starszy data scientist i ekspert ML Dzięki prawie dziesięciu latom doświadczenia w uczeniu maszynowym i data science, Ke Shen jest absolwentem Columbia University i byłym starszym data scientistą w Walmart Labs. Dysponując dogłębną, uznaną przez branżowych ekspertów wiedzą w zakresie Python, R, Java i statystyki, dzieli się sprawdzonymi w boju spostrzeżeniami na temat wdrażania złożonych algorytmów AI — od teorii po architekturę gotową do produkcji.
Spis treści
Thunderbit · Agent AI do danych z internetu

Wyciągaj dane z dowolnej strony w 1 klik

Zaufało nam ponad 250 000 użytkowników
dostępny darmowy plan
Od strony do arkusza kalkulacyjnego
Opisz, czego potrzebujesz — Agent AI Thunderbit zbierze to i wyeksportuje do Excela, Google Sheets, Airtable lub Notion. Start jest darmowy.
Chrome Store Rating
PRODUCT HUNT#1 Product of the Week