Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

markdownee

Markdownee PyPI version PyPI downloads license

Also available as:

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

Crawl pages and extract content with native Python Crawlee and Trafilatura Core.

Alpha / experimental. This maintained Python library is not fully tested or officially supported. TypeScript remains Markdownee's primary implementation.

Python performs crawling, extraction, conversion, and image processing without a bundled Markdownee or Trafilatura Core Node engine. Both languages live in the same source repository. Their supported controls differ; see Python coverage.

Contents

Install

Use Python 3.12 or later. The native alpha requires matching native Trafilatura Core 0.1.0a5. For a source checkout, install both local Python packages, or install their built wheels together. For published native prereleases, select the native version explicitly:

pip install --pre "markdownee==0.5.0a1"

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://www.iana.org/help/example-domains",
    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://www.iana.org/help/example-domains",
        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://www.iana.org/help/example-domains"],
    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 accept zero for unlimited; 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 100 and 3; crawl only
initial_concurrency, max_concurrency 1 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 a fetching method, select the content to retain, and export the result for your application. Markdownee supports research corpora, retrieval pipelines, and training-data preparation. Its Markdown output removes HTML syntax; the token saving depends on the page and extraction settings.

  • Boilerplate removal is powered by Trafilatura Core, our open-source pure-TypeScript port of Trafilatura. Its extraction core is a direct port of Python Trafilatura — with go-trafilatura used only as a DOM translation aid — and applies Trafilatura's own heuristics to strip navigation, sidebars, footers, and similar clutter
  • Fetch JavaScript-rendered pages with Playwright before extracting their HTML, or choose HTTP-only fetching
  • Use the primary TypeScript implementation on Node.js or the maintained alpha native Python library with Crawlee Python and Python Trafilatura Core; neither extraction path requires a GPU
  • Choose self-hosted execution through the npm CLI or npm library, run the hosted Apify Actor; the open-source code is on GitHub
  • Enable image downloading when your output needs local image files
Markdownee Firecrawl Jina Reader Crawl4AI
Content processing Trafilatura Core heuristics Scraping and optional model extraction Readability and Markdown conversion profiles Markdown generation and optional filters
Runtime Node (primary TypeScript) · native Python (alpha) hosted API / self-host hosted API Python
Surfaces Online playground · Apify Actor · npm CLI · npm library · PyPI (alpha) API · SDKs · self-hosted · MCP API Python library · crwl CLI · Docker REST API · MCP
Output formats txt · markdown · html · minified-html · original markdown · html · etc. markdown · html · text · screenshot · etc. markdown · etc.
Crawling Crawlee + Playwright (adaptive / browser / HTTP) built-in none (single URL) built-in

The comparison describes available interfaces, not measured quality or speed. See the Firecrawl documentation, Jina Reader architecture, and Crawl4AI Markdown documentation for each project's options. Jina Reader's ReaderLM profile is optional; the API and the ReaderLM model are distinct products.

Contributing

Use the issue tracker for reports and the source repository for proposed changes.

License

Apache-2.0

Metadata

Release files for markdownee 0.5.0a5

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.5.0a5
File Interpreter ABI Platform
markdownee-0.5.0a5-py3-none-any.whl Python 3 none any Details

Release files / markdownee-0.5.0a5-py3-none-any.whl

Download URL markdownee-0.5.0a5-py3-none-any.whl
Size 28.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
244a11b5031071bd8889d467b5011685b85640aea011f230002459467208e75f
BLAKE2b-256 checksum
How to use checksums
17aa333ebd36067d14a5ff3ab18901384ef5228a69a2dfce0392e61a3d663f7f
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 18, 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

0.8.3

1 release file

0.8.2

1 release file

0.8.1

1 release file

This release

0.5.0a5 This release

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