Skip to main content

Markdownee

Markdownee PyPI version PyPI downloads license

Also available as:

Online playground | Apify Actor | npm package CLI & lib | Source code on GitHub

Markdownee is a web scraper that crawls websites and saves their content as Markdown, HTML or plain text for LLMs, retrieval pipelines, and research datasets.

Choose which links to follow, set page and depth limits, and select how much page content to keep. Control tables, links, images, and user comments separately.

Boilerplate removal is powered by Trafilatura Core, our open-source fork of Trafilatura. The Core in its name means it is reduced to one task: main-content extraction and boilerplate removal. Other packages handle output conversion, including Markdown. Trafilatura Core is ported from the original Python Trafilatura, with go-trafilatura as a DOM translation aid. Crawlee handles crawling and uses Playwright for browser rendering.

Two language versions — TypeScript and Python: this library uses Crawlee Python and native Python Trafilatura Core. The npm and Actor surfaces use the TypeScript stack described above. Python provides library APIs only and does not bundle a Node product engine.

Fetch one page into memory or export a crawl as files and a manifest. Synchronous and asynchronous calls support HTTP, Chromium, and Firefox fetching, content settings, and image processing. Python coverage documents the differences. Both languages share the source repository.

Contents

Install

Use Python 3.12 or later. Markdownee pins the matching native Trafilatura Core release, which installs with the package:

pip install "markdownee==0.8.0"

For a source checkout, install both local Python packages or their built wheels.

HTTP crawling needs no browser. Chromium or Firefox crawling requires the corresponding Playwright browser:

playwright install chromium
# For crawler_type="firefox":
playwright install firefox

These are dependency setup commands. Markdownee exposes Python library APIs only, with no console script or python -m markdownee interface. Playwright manages its own browser driver; it does not run either product's Node engine.

Markdownee builds a platform-independent Python wheel and a source distribution. Crawlee, Trafilatura Core, lxml, Playwright, and pyvips[binary] are installed as dependencies. The pyvips binary extra provides libvips on supported platforms; other platforms need a compatible libvips installation and the dependencies' own installation requirements.

Quick start

fetch follows no links and returns requested content:

from markdownee import fetch

contents = fetch(
    "https://en.wikipedia.org/wiki/Web_scraping",
    crawler_type="http",
    formats=["markdown", "minified-html", "original"],
)
print(contents["markdown"])

Format selectors are txt, markdown, html, minified-html, and original. Result keys use minified_html; the other names are unchanged. Markdown is the default. Original is the captured HTML, before cleaning. Missing cleaned content is omitted; a failed single-page request raises MarkdowneeError.

Use afetch in an asynchronous application:

import asyncio
from markdownee import afetch


async def main():
    contents = await afetch(
        "https://en.wikipedia.org/wiki/Web_scraping",
        crawler_type="http",
    )
    print(contents["markdown"])


asyncio.run(main())

Crawling multiple pages

crawl writes files and a JSON manifest into an isolated directory beneath output_dir. Its CrawlSummary exposes total, succeeded, failed, skipped, output_dir, and manifest_path. Partial page failures retain successful output. acrawl has the same arguments asynchronously.

from markdownee import crawl

summary = crawl(
    ["https://en.wikipedia.org/wiki/Web_scraping"],
    output_dir="./out",
    formats=["markdown", "html"],
    selector="main a",
    max_requests_per_crawl=5,
    max_crawl_depth=1,
)
print(summary.succeeded, summary.failed, summary.manifest_path)

Link following requires a nonempty selector and remains on the seed page's origin. globs and exclude filter discovered links. Crawlee deduplicates request URLs; Python does not offer TypeScript's content-deduplication modes. Request and depth limits use None for unrestricted; depth zero means start URLs only. timeout still bounds the whole call. Concurrent requests can slightly exceed the request limit.

Options

Both APIs validate snake_case keywords before fetching. Unknown options raise MarkdowneeError; options are not translated into CLI arguments.

Option Values / default
crawler_type http (default), chromium, firefox
mode precision, balanced (default), recall, keep
output_layout minimal (default), standard, enhanced
image_handling exclude, alt-text (default), resolved-url, save
link_handling, table_handling include (default), exclude
comment_handling include, exclude (default)
language Filter conflicting declared page languages; unset by default
timeout, navigation_timeout Whole-call 120 seconds; request 30 seconds
max_retries 2
max_requests_per_crawl, max_crawl_depth None (unrestricted); depth 0 means start URLs only
initial_concurrency, max_concurrency None (Crawlee-selected) and 5; crawl only
respect_robots_txt True; checks allow/disallow, not crawl-delay
headers, user_agent Optional HTTP headers and user agent
proxy List of HTTP(S) proxy URLs; no SOCKS or Apify proxy controls
max_input_bytes 10 MiB at the captured-HTML boundary

minimal returns body text and HTML fragments. standard adds ordinary metadata as flat YAML front matter and a complete HTML document. enhanced adds allowlisted page and crawl fields. TXT preserves preformatted content and table cells; Markdown includes headings, links, tables, and image references.

Browser controls include headless=True, block_media=True, ignore_https_errors=False, and wait_until="domcontentloaded". max_scroll_height bounds scrolling; wait_for_dynamic_content bounds a network-idle wait. wait_for_selector is required and soft_wait_for_selector is optional. Durations are seconds. HTTP supports the required selector as a presence check and rejects dynamic waits or scrolling.

Python coverage

The native API implements HTTP and explicit Chromium/Firefox crawling, retries, proxies, headers, request/depth limits, link selectors and filters, declared-language filtering, all five product formats, three layouts, and image saving. It calls Python Trafilatura Core once per page and renders the selected formats from that result.

TypeScript additionally provides adaptive crawler selection, consent-wall recovery, served-Markdown discovery, sitemap seeding, configurable content deduplication, persistent session stores, custom cookies, and Apify storage routes. These controls are not accepted by the Python API. cheerio is a TypeScript crawler name; select http in Python. Python does not promise byte-identical HTML/Markdown serialization or performance parity.

Cancellation stops awaiting the crawl. CPU work already running in an extraction/image worker may finish; byte and pixel limits bound its input. HTTP responses and browser documents are captured before the HTML size check; max_input_bytes is not a network download limit.

Images

Use image_handling="save" with crawl or acrawl; return-only calls reject it. Images download through the crawl's session/proxy channel with a 10 MiB per-image stream limit. Failures retain the resolved URL and add a manifest warning.

JPEG, PNG, WebP, GIF, TIFF, and AVIF images become metadata-stripped WebP (first frame for animation). Other raster formats retain their source URL. max_image_edge=2048 limits the long edge without upscaling; zero keeps raster dimensions. Images smaller than 64 pixels on both edges are dropped. SVG geometry passes a static allowlist before it is rasterized to PNG, with a 1568-pixel edge ceiling. rasterize_svg=False stores the cleaned SVG instead. External SVG resources, scripts, events, and style attributes are removed. max_image_bytes and max_image_pixels customize resource caps.

Selecting original also retains downloaded source image bytes as *-original.bin; these files are unprocessed originals. Output HTML and Markdown reference the transformed local files.

Why Markdownee

Choose what to fetch, what content to retain, and where to save it. Markdown output removes HTML syntax; token savings depend on the page and extraction settings.

Boilerplate removal is powered by Trafilatura Core. Trafilatura Core is ported from the original Python Trafilatura, with go-trafilatura as a DOM translation aid. Crawlee handles crawling and uses Playwright for browser rendering.

Two language versions — TypeScript and Python: self-host with the npm CLI, npm library, or native Python library, or use the hosted Apify Actor. The npm surfaces use Crawlee and TypeScript Trafilatura Core; Python uses Crawlee Python and Python Trafilatura Core. Neither extraction path requires a GPU. Source is on GitHub.

Optional image downloading keeps local images with extracted content.

Report problems through the issue tracker.

License

Apache-2.0

Metadata

Release files for markdownee 0.8.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Built distribution (wheel)

Table of built distributions (wheels) for markdownee 0.8.3
File Interpreter ABI Platform
markdownee-0.8.3-py3-none-any.whl Python 3 none any Details

Release files / markdownee-0.8.3-py3-none-any.whl

Download URL markdownee-0.8.3-py3-none-any.whl
Size 27.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
2e14bd1f632a206ac35339d6b4b7820a077d110b37655c3001fdeb7b38df4afe
BLAKE2b-256 checksum
How to use checksums
9eeab7c3922e3cdf4b4954d0ab256147f3b929d3d47757c1ceeee63c03ab56ab
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 21, 2026.

Transparency log

Release history Release notifications | RSS feed

0.8.11

1 release file

0.8.10

1 release file

0.8.9

1 release file

0.8.6

1 release file

0.8.5

1 release file

0.8.4

1 release file

This release

0.8.3 This release

1 release file

0.8.2

1 release file

0.8.1

1 release file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page