html2text se nainstaluje jako jeden balíček a zabere jen 0,2 MiB — je tedy devětkrát menší než nejbližší Python alternativa a čtyřicetkrát menší než ta v Node. V konverzní sadě zvládl všechny čtyři stránky a zachoval všech 16 registrovaných body probeů. Tyto testy sledují, zda vybrané texty v těle stránky přežijí převod; nehodnotí ale hierarchii, zanoření seznamů, cíle odkazů, opakovaný obsah ani úplnou přesnost tabulek.
Současně je dostupný pod licencí GPL-3.0-or-later, což je v tomto srovnání jediná vlastnost, která se v žádném benchmarku neukáže a která může knihovnu rovnou vyřadit.
Co je html2text
html2text je Python knihovna, která převádí HTML do Markdownem inspirovaného prostého textu. Její historie sahá k původní verzi od Aaron Swartz a dnešní udržovaná větev je na verzi 2025.4.15 — datumově značené vydání z dubna 2025, se 2 168 hvězdičkami na GitHubu, 95 otevřenými issue a posledním pushi v říjnu 2025.
Oficiální reference: oficiální repozitář html2text.
import html2text
h = html2text.HTML2Text()
h.body_width = 0 # viz níže; výchozí hodnota vás překvapí
md = h.handle(html)
pip install html2text stáhne 1 balíček a 0,2 MiB, přičemž cold import trvá 0,077 s. Žádné závislosti. V kontejnerovém image nebo Lambda layeru je to citelný rozdíl oproti markdownify s 1,8 MiB a turndown s 8,8 MiB.
Výchozí nastavení, které změní všechna čísla

body_width má výchozí hodnotu 78. html2text tedy tvrdě zalamuje každý řádek výstupu na 78 znaků, pokud to nevypnete.
To je rozumné nastavení pro knihovnu, jejímž původním účelem bylo vytvářet čitelný prostý text pro terminály a e-mail. Pro cokoli, co posíláte do modelu nebo porovnáváte diffem, je to ale špatná výchozí volba — vložené nové řádky mění tokenizaci, lámou dlouhé odkazy a dělají porovnávání výstupů bezcenným.
Pro všechno níže jsem nastavil body_width = 0 a říkám to otevřeně, ne schovaně: se zapnutým zalamováním by se v tomto článku změnil každý počet znaků i tokenů. Pokud si benchmarkujete převodníky sami, právě tohle nastavení vám potichu udělá čísla neporovnatelná.
Měření
Spustil jsem html2text na pojmenované čtyřstránkové konverzní sadě, kterou jsem použil i pro porovnání markitdown, se vopřed registrovanými probe stringy — vybranými texty v těle stránky, které musí přežít, a boilerplate texty, jejichž přítomnost potvrzuje, že se na výstup dostal i okolní rámec stránky. Stejné čtyři soubory, stejné proby, jeden scorer pro všechny čtyři převodníky. Přežití probeů měří přítomnost registrovaných řetězců, ne strukturální správnost; sloupce s tabulkami a odkazy jsou oddělené právě z tohoto důvodu.
| Převodník | Body probeů | Počet znaků ve výstupu | Tokeny (o200k) | Řádky Markdown tabulek | Odkazy |
|---|---|---|---|---|---|
| html2text | 16/16 | 76 452 | 21 176 | 32 | 545 |
| markdownify | 16/16 | 76 868 | 21 062 | 36 | 599 |
| markitdown | 16/16 | 76 995 | 21 336 | 36 | 598 |
| turndown | 16/16 | 95 188 | 26 236 | 0 | 611 |
fourway-scores.json. Čtyři fixture, tokeny počítané s o200k_base.
Nejmenší výstup ze všech čtyř s 76 452 znaky a prakticky shoda v tokenech s markdownify a markitdown — 21 176 oproti 21 062 a 21 336, tedy rozptyl 1,3 %, který bych za rozdíl nepovažoval.
32 řádků tabulek oproti 36 u markdownify a markitdown ve čtyřstránkové sadě. Čtyřřádkový rozdíl vzniká na nepravidelné Wikipedii, ne ve vnější pipe formě, o které píšu níže.
Nejméně odkazů: 545, oproti 598 až 611 u ostatních. Pokud je pro vás zachování odkazů důležité, stojí za to to ověřit na vlastních stránkách — v tomto sloupci je html2text zřetelně pod skupinou, ne uvnitř ní.
Tabulky, které můj regex neviděl

Tohle je důležité zmínit, protože jsem málem publikoval špatný závěr.
Můj první počítadlo řádků tabulek vyžadovalo úvodní i koncové pipe znaky — ^\|.*\|$. Podle tohoto pravidla měl html2text 1 řádek tabulky v pěti souborech: čtyřstránkové sadě plus samostatné syntetické složité tabulkové fixture. Tenhle počítadlo ale měřil jen jeden Markdown styl, ne tabulky.

Převodník je tam skutečně vytvoří. Vypadá to takto:
Team Name | Year | Wins | Losses | Win %
---|---|---|---|---
Boston Bruins | 1990 | 44 | 24 | 0.55
Bez vnějších pipe znaků. Je to běžná pipe-table syntaxe, ale náš harness ji napříč Markdown renderery neověřoval. Regex, který čeká styl s vnějšími pipe, ji tedy nevidí. Přepsání počítadla tak, aby hledalo blok řádků s pipes a s oddělovacím řádkem uvnitř, posunulo html2text z 1 řádku na 32 ve čtyřstránkové sadě a 91 napříč všemi pěti soubory.
Závěr tedy není, že html2text tabulky nemá. Jde o to, že dva ze čtyř převodníků generují outer pipes a jeden ne, což je podstatné, pokud Markdown dál zpracováváte vlastními pattern matchery. To je přesně ten druh informace, který bych při důvěře v první číslo úplně minul.
Co odstraňuje a kde ztrácí řádky
Dva poznatky, které jdou proti sobě.
Odstraňuje <script> a <style>. Podle markerů, které se vyskytují jen uvnitř těchto elementů, html2text ve všech fixturech nese žádné script markery a žádné style markery. turndown naopak nese 10 a 84 — na Wikipedii jde o osm řádků inline JavaScript konfigurace MediaWiki a CSS v hodnotě 14 644 znaků (script-style-stripping.json). Pro výstup určený pro modely to byl na této fixture největší pozorovaný zdroj zbytečného textu. Žádný downstream cost model se ale neměřil.
Ztrácí řádky tabulek na náročné stránce. Čtyřstránková sada vychází takto:
| Fixture | html2text | markdownify |
|---|---|---|
| Books to Scrape | 0 řádků | 0 řádků |
| Quotes to Scrape | 0 řádků | 0 řádků |
| Hockey statistics | 27 řádků | 27 řádků |
| Wikipedia | 5 řádků | 9 řádků |
| Celkem za čtyři stránky | 32 řádků | 36 řádků |
Samostatná syntetická komplexní tabulková fixture přidává 59 řádků html2text a 62 řádků markdownify, takže součet za pět souborů je 91 a 98. Nejde o část hlavního porovnání čtyř stránek. U čisté hokejové tabulky se shodují. Na Wikipedii, kde jsou tabulky zanořené a nepravidelné, html2text vrací pět řádků, zatímco markdownify devět.
Vzorec je tedy tento: jednoduché tabulky jsou stejné; nepraktické tabulky si html2text poradí hůř. Pokud vaše stránky obsahují tabulky podobné Wikipedii, ověřte to před nasazením. Pokud jsou spíš jako statistická stránka, jsou si v této oblasti zaměnitelné.
Licence
| Knihovna | Licence | Balíčky | Velikost na disku |
|---|---|---|---|
| html2text | GPL-3.0-or-later | 1 | 0,2 MiB |
| markdownify | MIT | 5 | 1,8 MiB |
| turndown | MIT | 3 (npm) | 8,8 MiB |
Oficiální reference: html2text na PyPI.
Potvrzeno na třech místech: v metadatech PyPI, v repozitáři na GitHubu a ve vlastním souboru METADATA nainstalovaného balíčku, kde je uvedeno License-Expression: GPL-3.0-or-later.
Co to znamená, závisí na tom, jak je software integrován, předáván a distribuován. Interní nebo čistě síťové použití je obvykle jiný GPL scénář než dodání softwaru, který balíček obsahuje nebo kombinuje, ale tento článek nedělá právní analýzu. Týmy, které software distribuují, by měly nechat konkrétní integrační a distribuční model zkontrolovat právníkem.
Nepříjemná je ta korelace. Knihovna s nejmenší stopou, kterou byste zvolili právě proto, aby byl distributovatelný artefakt co nejmenší, má zároveň licenci, která distribuci nejvíc omezuje. Obě alternativy jsou MIT.
Nejsem právník a tohle není právní rada — jen fakt s uvedeným zdrojem, protože jde o vlastnost, která bude nejspíš nejvíc rozhodovat a v porovnávacích tabulkách se objevuje nejméně.
Údržba
Poslední release 2025.4.15, poslední push do repozitáře v říjnu 2025 — tedy zhruba deset měsíců před testem, se 41 vydáními za sebou. requires_python >= 3.9 a na Pythonu 3.14.2 se nainstaloval i spustil bez problémů.
To působí klidněji než markdownify (poslední vydání šest týdnů před testem) a turndown (čtyři měsíce) a rozhodně aktivněji než nic. U knihovny, která převádí HTML na text — což není problém, který by se rychle měnil — zní desetiměsíční pauza spíš jako stabilita než opuštění. Větší červenou vlajkou je 95 otevřených issue; před nasazením se vyplatí projít ty, které připomínají váš use case.
Paměť a co s ní dělá rozbité HTML
Dvě provozní otázky tu měřím odděleně.
Širší kontext stress testu je v porovnání paměti a neplatného HTML mezi deseti knihovnami.
Maximální resident memory, přes /usr/bin/time -l, vždy jeden čerstvý proces na buňku — import floor je cena knihovny po načtení a v klidu, maxima už zahrnují dokument.
| Knihovna | Runtime | Import floor | Maximum při 226 KB | Maximum při 10 MB |
|---|---|---|---|---|
| html2text | python3.14 | 18,7 | 19,9 | 71,2 |
| pyquery | python3.14 | 30,3 | 33,9 | 172,5 |
| resiliparse | python3.14 | 20,5 | 25,1 | 225,1 |
| markdownify | python3.14 | 23,9 | 28,9 | 278,5 |
| goose3 | python3.14 | 44,1 | 52,4 | 398,5 |
| cheerio | node22 | 66,8 | 76,5 | 398,5 |
| justext | python3.14 | 30,3 | 36,6 | 431,2 |
| newspaper4k | python3.14 | 52,6 | 61,8 | 668,5 |
| trafilatura | python3.14 | 52,5 | 64,8 | 927,1 |
| turndown | node22 | 47,8 | 68,4 | 2947,1 |
memory-results.json. Základy pro Python a Node nejsou navzájem přímo srovnatelné; interpret je uvnitř obou.
html2text je zde na obou měřených osách nejlehčí položka. Jeho import floor 18,7 MiB a maximum 71,2 MiB na 10MiB fixture dávají inkrementální RSS 52,5 MiB: (71.2 - 18.7) / 10 = 5,25× velikost fixture. Srovnejte to s absolutními i inkrementálními řádky v tabulce a mějte přitom na paměti uvedené upozornění k baseline Python/Node.
Rozbité HTML. Dvanáct dokumentů, z nichž každý poruší přesně jednu věc — neuzavřené tagy, špatně zanořené inline prvky, atributy bez uvozovek s mezerami, osamělé koncové tagy, žádné <html>, duplicitní atributy, dokument uříznutý uprostřed tagu, špatné entity, neuzavřený <script>, lživé charset prohlášení, komentář s markupem a 600 úrovní zanoření — plus dva dobře vytvořené kontrolní dokumenty stejné velikosti, protože tvrzení „vrátilo nic“ říká něco o chybovosti jen tehdy, když knihovna na čistém dokumentu stejné velikosti také mlčí.
html2text nevyhodil chybu na 0 ze 14 a nevrátil prázdný výstup na 0, přičemž obnovil 33/33 sentinelů napříč rozbitými fixturemi (malformed-results.json). Jeden fixture se z tohoto počtu vyjímá: podle HTML5 je vše po neuzavřeném <script> skutečně scriptový obsah, takže jeho ztráta je správná a jeho obnova by byla odchylka.
Klady a zápory
Ve prospěch. Jeden balíček, 0,2 MiB, nulové závislosti — zdaleka nejmenší v porovnání. Nejmenší výstup ze všech čtyř a prakticky shoda v tokenech s markdownify a markitdown. Vytváří rozpoznatelnou pipe-table syntaxi. Běží na Pythonu 3.14. Dlouhá, stabilní historie.
Proti. GPL-3.0-or-later, na rozdíl od alternativ. Výchozí body_width=78, který tvrdě zalamuje výstup a mění měření i diffy, pokud ho nevypnete. Nejméně zachovaných odkazů (545 oproti 598–611). Tabulky používají styl bez vnějších pipes, což rozbíjí naivní downstream regex. 95 otevřených issue a klidnější tempo vydávání než markdownify.
Kdo by ho měl použít a kdo ne
Použijte html2text, když je rozpočet na závislosti opravdu napjatý a zamýšlený integrační i distribuční model prošel licenční kontrolou. Jeden balíček bez závislostí je reálná provozní výhoda: menší plocha, kterou je třeba auditovat a nasazovat.
Nastavte body_width = 0 hned na prvním řádku, pokud výslovně nechcete zalomený prostý text.
Vyhněte se mu, pokud software distribuujete a copyleft je problém — markdownify je MIT, v tokenech je tady prakticky shodný a v tabulkách odpovídá markitdown, přitom zabírá o 1,6 MiB víc. Vyhněte se mu i tehdy, když vám záleží na zachování odkazů, protože jich uchoval nejméně. A vyhněte se mu, pokud vaše downstream nástroje předpokládají u řádků tabulek vnější pipes.
Kde dává smysl spravované API
html2text převádí HTML, které už máte. Nestahuje stránky, nespouští JavaScript ani neřeší anti-bot vrstvu — to nedělá žádný ze čtyř převodníků a na mnoha reálných cílech je to právě ta těžší polovina práce.
Pro stejné fixture napříč všemi pěti převodníky se podívejte na pětistranné porovnání HTML do Markdownu.
Hostovaná služba pro fetch/render/extraction, včetně našeho Thunderbit, pracuje v jiné vrstvě. Thunderbit zde nebyl benchmarkován. Rozhraní je mezi převodem dodaného HTML a službou, která URL sama získá a zpracuje; tento článek neposkytuje srovnání kvality, latence ani ceny na stejné metrice.
Spravedlivé shrnutí: pokud máte HTML, chcete Markdown a GPL vám nevadí z hlediska způsobu distribuce, html2text je zdarma a pozoruhodně malý. Pokud stránky teprve stahujete, nebo chcete spíš řádky než prózu, jde o jiný nákup.
Pro širší přehled se podívejte na naše shrnutí web scraping API, které pokrývá hostované možnosti, a na pillar open-source scraperů pro self-hosted nástroje. Praktický postup najdete v článku Převod HTML na Markdown v Pythonu.
Vyzkoušet Thunderbit pro extrakci webových dat
Měli byste použít html2text?
Je to silný kandidát, pokud záleží na malé stopě, záměrně vypnutém zalamování a distribuční model projde licenční kontrolou.
Ve čtyřstránkové sadě měl počet tokenů do 1,3 % od markdownify a markitdown. To ale neznamená stejnou celkovou kvalitu: html2text zachoval méně odkazů a méně řádků u nepravidelné Wikipedie. Dva provozní detaily jsou důležité hned: body_width = 0 a styl tabulek bez vnějších pipes.
Pokud ho vyřadí kontrola GPL, markdownify je pod MIT, v tomto testu měl podobnou velikost výstupu i počet tokenů, zachoval více odkazů i řádků nepravidelných tabulek a v tomto prostředí zabral o 1,6 MiB více místa na disku.
Vyzkoušet Thunderbit pro extrakci webových dat Get Started Free
Často kladené otázky
Umí html2text převádět tabulky?
Ano. Můj první počítadlo tvrdilo, že napříč pěti soubory vytvořil jeden řádek tabulky, ale to bylo špatně — vyžadovalo totiž úvodní a koncové pipe znaky, zatímco html2text vypisuje Team Name | Year | Wins i bez nich. To je běžný Markdown pipe-table formát, i když tento harness netestoval kompatibilitu napříč renderery. S opraveným počítadlem vytvořil html2text 32 řádků oproti 36 u markdownify ve čtyřstránkové sadě a 91 oproti 98 po započtení samostatné složité tabulkové fixture.
Co dělá body_width a proč ho měnit?
Ve výchozím stavu tvrdě zalamuje výstup na 78 znaků, což je rozumné pro text čitelný v terminálu a nevhodné téměř pro všechno ostatní. Zalamování vkládá nové řádky doprostřed vět, láme dlouhé URL a mění tokenizaci. Všechna čísla v této recenzi používají body_width = 0; s výchozí hodnotou by byla všechna jiná.
Je licence GPL skutečně omezení?
Záleží na přesném integračním a distribučním modelu. Interní nebo čistě síťové použití a samotné předávání softwaru jsou různé situace, ale tento článek nerozhoduje o jejich právním výsledku. Týmy, které software vydávají, by měly nechat podmínky GPL-3.0-or-later zkontrolovat právníkem; markdownify a turndown jsou MIT. Licenční výraz html2text je potvrzen v metadatech PyPI, na GitHubu i ve METADATA nainstalovaného balíčku.
Je vydání z dubna 2025 problém? Samo o sobě asi ne. Převod HTML na text je stabilní problém, knihovna se na Pythonu 3.14.2 nainstalovala a běžela bez potíží a má za sebou 41 vydání. 95 otevřených issue je ale číslo, které bych skutečně kontroloval — projděte si je kvůli čemukoli podobnému vašemu vstupu, protože tichý repozitář může znamenat, že opravy budou na vás.
Co se zde netestovalo?
Čtyři konverzní fixture a jedna samostatná složitá tabulková fixture jsou pořád malá sada. Test ale pokryl dvanáct syntetických rozbitých dokumentů plus dvě kontroly: html2text nevyhodil chybu v 0/14, nevrátil prázdný výstup v 0/14 a obnovil všech 33 hodnocených sentinelů. Nepokrývá to reálné poškozené stránky, širší typy chyb v HTML, zanořené seznamy, definiční seznamy, poznámky pod čarou ani matematický obsah. Celá sada možností — ignore_links, ignore_images, unicode_snob, single_line_break a další — zůstala kromě body_width na výchozích hodnotách. Rozdíl v počtu odkazů byl pozorován, ale nebyl diagnostikován, a round-trip zpět do Markdownu se netestoval.


