Extracting the main content from web pages is harder than it looks. A page contains not just the article or blog post you want, but also headers, footers, sidebars, navigation menus, ads, and social media widgets — collectively known as boilerplate. The goal of main content extraction (also called boilerplate removal, DOM-based content extraction, or web page cleaning) is to return the central text while discarding everything else. This page documents how Trafilatura performs on this task compared to other Python tools, and explains how to reproduce the benchmark yourself.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/adbar/trafilatura/llms.txt
Use this file to discover all available pages before exploring further.
External evaluations
Trafilatura has been independently assessed across multiple benchmarks and academic studies:ScrapingHub Article Extraction Benchmark
Trafilatura is the most efficient open-source library in ScrapingHub’s article extraction benchmark, which measures accuracy across a large and diverse set of web pages.
Lejeune & Barbaresi 2020
Ranked as the best overall tool in Bien choisir son outil d’extraction de contenu à partir du Web, a comparative study of content extraction tools for French web pages.
Bevendorff et al. 2023
Achieved the best single-tool score by ROUGE-LSum Mean F1 Page Score in An Empirical Comparison of Web Content Extraction Algorithms (Webis group, 2023).
Polish news comparison
Evaluated on a sample of Polish news texts and forums. This test set has since been incorporated into the internal benchmark; Trafilatura has improved further since then.
Benchmark results (2022-05-18)
The table below shows results on 750 documents containing 2,236 text segments and 2,250 boilerplate segments, measured with Python 3.8. Bold values indicate the best result in each column.| Python package | Precision | Recall | Accuracy | F-Score | Speed (vs. baseline) |
|---|---|---|---|---|---|
| raw HTML | 0.527 | 0.874 | 0.546 | 0.658 | — |
| html2text 2020.1.16 | 0.486 | 0.709 | 0.481 | 0.577 | 7.6× |
| html_text 0.5.2 | 0.529 | 0.958 | 0.554 | 0.682 | 2.2× |
| inscriptis 2.2.0 | 0.534 | 0.959 | 0.563 | 0.686 | 3.5× |
| newspaper3k 0.2.8 | 0.895 | 0.593 | 0.762 | 0.713 | 12× |
| jusText 3.0.0 (custom) | 0.865 | 0.650 | 0.775 | 0.742 | 5.2× |
| boilerpy3 1.0.6 (article mode) | 0.814 | 0.744 | 0.787 | 0.777 | 4.1× |
| baseline (text markup) | 0.757 | 0.827 | 0.781 | 0.790 | 1× |
| goose3 3.1.9 | 0.934 | 0.690 | 0.821 | 0.793 | 22× |
| readability-lxml 0.8.1 | 0.891 | 0.729 | 0.820 | 0.801 | 5.8× |
| news-please 1.5.22 | 0.898 | 0.734 | 0.826 | 0.808 | 61× |
| readabilipy 0.2.0 | 0.877 | 0.870 | 0.874 | 0.874 | 248× |
| trafilatura 1.2.2 (fast) | 0.914 | 0.886 | 0.902 | 0.900 | 4.8× |
| trafilatura 1.2.2 (precision) | 0.932 | 0.874 | 0.905 | 0.902 | 9.4× |
| trafilatura 1.2.2 (standard) | 0.914 | 0.904 | 0.910 | 0.909 | 7.1× |
The Diff column shows execution time relative to the simple baseline. Lower is faster. The baseline extracts raw text from paragraph, code, and quote elements — a meaningful but unsophisticated approach.
Older results (2021-06-07) — 500 documents
Older results (2021-06-07) — 500 documents
| Python package | Precision | Recall | Accuracy | F-Score | Speed |
|---|---|---|---|---|---|
| raw HTML | 0.527 | 0.878 | 0.547 | 0.659 | — |
| html2text 2020.1.16 | 0.488 | 0.714 | 0.484 | 0.580 | 8.9× |
| html_text 0.5.2 | 0.526 | 0.958 | 0.548 | 0.679 | 1.9× |
| inscriptis 1.1 | 0.531 | 0.958 | 0.556 | 0.683 | 2.4× |
| jusText 2.2.0 (custom) | 0.870 | 0.584 | 0.749 | 0.699 | 6.1× |
| newspaper3k 0.2.8 | 0.921 | 0.574 | 0.763 | 0.708 | 12.9× |
| boilerpy3 1.0.2 (article mode) | 0.851 | 0.696 | 0.788 | 0.766 | 4.8× |
| goose3 3.1.9 | 0.950 | 0.644 | 0.806 | 0.767 | 18.8× |
| baseline (text markup) | 0.746 | 0.804 | 0.766 | 0.774 | 1× |
| dragnet 2.0.4 | 0.906 | 0.689 | 0.810 | 0.783 | 3.1× |
| readability-lxml 0.8.1 | 0.917 | 0.716 | 0.826 | 0.804 | 5.9× |
| news-please 1.5.21 | 0.924 | 0.718 | 0.830 | 0.808 | 60× |
| trafilatura 0.8.2 (fast) | 0.925 | 0.868 | 0.899 | 0.896 | 3.9× |
| trafilatura 0.8.2 | 0.934 | 0.890 | 0.914 | 0.912 | 8.4× |
Older results (2020-07-16) — 400 documents
Older results (2020-07-16) — 400 documents
| Python package | Precision | Recall | Accuracy | F-Score | Speed |
|---|---|---|---|---|---|
| raw HTML | 0.524 | 0.879 | 0.543 | 0.657 | — |
| html2text 2020.1.16 | 0.485 | 0.718 | 0.480 | 0.579 | 8.4× |
| html_text 0.5.1 | 0.521 | 0.962 | 0.542 | 0.676 | 1.8× |
| inscriptis 1.0 | 0.527 | 0.965 | 0.551 | 0.681 | 1.9× |
| newspaper3k 0.2.8 | 0.916 | 0.577 | 0.763 | 0.708 | 11.8× |
| jusText 2.2.0 (tweaked) | 0.867 | 0.651 | 0.777 | 0.744 | 4.9× |
| goose3 3.1.6 | 0.953 | 0.635 | 0.803 | 0.762 | 17.3× |
| baseline (text markup) | 0.738 | 0.804 | 0.760 | 0.770 | 1× |
| boilerpy3 1.0.2 (article mode) | 0.847 | 0.711 | 0.792 | 0.773 | 4.4× |
| dragnet 2.0.4 | 0.906 | 0.704 | 0.816 | 0.792 | 2.8× |
| readability-lxml 0.8.1 | 0.913 | 0.739 | 0.835 | 0.817 | 5.4× |
| news-please 1.4.25 | 0.918 | 0.739 | 0.837 | 0.819 | 56.4× |
| trafilatura 0.5.1 | 0.927 | 0.854 | 0.894 | 0.889 | 3.1× |
| trafilatura 0.5.1 (+ fallbacks) | 0.933 | 0.885 | 0.911 | 0.908 | 6.8× |
Understanding precision and recall
Content extraction always involves a trade-off:- High precision means less noise in the output, but you risk missing some relevant content. Tools like
goose3lean heavily in this direction. - High recall means you capture more of the main text, but at the cost of including some boilerplate. Tools like
html_textandinscriptis— which simply strip all HTML tags — achieve near-perfect recall but cannot distinguish main content from sidebars or footers. - Balanced F-Score is what matters most in practice. Trafilatura’s standard mode achieves the best F-Score by combining a rule-based approach with algorithmic fallbacks.
favor_precision and favor_recall parameters, letting you shift the balance for your specific use case.
Alternatives
The following Python packages are relevant alternatives for HTML-to-text conversion and main content extraction.Structure-preserving converters (no main-content focus)
These tools convert the entire HTML document to text or markup, without attempting to identify and isolate the main content area:| Package | Description |
|---|---|
| html2text | Converts HTML pages to Markdown-formatted text |
| html_text | Converts HTML to plain text; achieves high recall but no content filtering |
| inscriptis | HTML to text with particular emphasis on nested tables |
Main content extraction tools
These packages, like Trafilatura, attempt to identify and return only the primary content of a page:| Package | Notes |
|---|---|
| boilerpy3 | Python port of the boilerpipe boilerplate removal algorithm |
| goose3 | Highest precision of the tested tools, but low recall; does not preserve markup |
| jusText | Designed for linguistic resources; highly configurable |
| newspaper3k | Oriented towards news articles; additional functions but no structured output |
| news-please | News crawler with structured information extraction; very slow |
| readability-lxml | Cleans the page and preserves some markup |
| readabilipy | Python wrapper for Mozilla’s Readability (Node.js); extremely slow |
The benchmark also includes boilerpy3, newspaper3k, and readabilipy with error handling enabled — these packages produce errors on some HTML files in the test set (malformed HTML, encoding bugs). Errors are silently ignored to complete the run, which may slightly inflate their apparent performance.
Benchmark methodology
Test set: Documents typical of Internet articles and blog posts, drawn primarily from large German web page collections (DWDS). For completeness, documents in English, French, and other European languages, as well as Chinese and Arabic (~20–30% of the total), are included. Some documents are deliberately challenging due to mixed content (lists, tables) or invalid HTML. Evaluation: Key document segments are annotated as either text (wanted content) or boilerplate (navigation, headers, footers, sidebars, social links, addresses). The evaluation measures how accurately each tool makes this distinction. Reproducibility: Clone the repository, install all packages, and run the evaluation script:tests/README.rst.