HTML to Markdown Converter — Clean conversion with batch
Pricing
from $0.01 / actor start
HTML to Markdown Converter — Clean conversion with batch
Clean, AI-ready Markdown from any HTML source. Converts web pages or raw HTML to well-structured Markdown — preserving headings, lists, tables, code blocks, links, and images. Clean mode strips ads and navigation. Batch convert up to 50 items via URL fetch or direct HTML input.
Pricing
from $0.01 / actor start
Rating
0.0
(0)
Developer
Perry AY
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
6 hours ago
Last modified
Categories
Share
HTML to Markdown Converter 📝
Clean, AI-ready Markdown from any HTML source — with noise-stripping clean mode
Converting HTML to clean, readable Markdown is a common but surprisingly tricky task. Inline styles, complex nested layouts, navigation elements, ads, and sidebar content all get in the way of producing clean output. HTML to Markdown Converter handles the entire conversion pipeline — fetch from a URL or paste raw HTML, strip unwanted noise, preserve document structure, and produce clean Markdown ready for LLM ingestion, documentation migration, content archiving, or web scraping pipelines.
Supports batch processing of up to 50 items per request, two conversion modes, and multiple output formats. Every result includes metadata — title, word count, image count — alongside the full Markdown content.
✨ Features
-
URL or raw HTML input — Fetch content from any public URL with automatic redirect following, or paste raw HTML directly for offline conversion without network requests
-
Structure preservation — Headings (H1–H6), ordered and unordered lists, tables, code blocks, inline code, links, blockquotes, and images are all accurately preserved in the Markdown output using the markdownify library
-
Clean mode — Premium mode that strips ads, navigation bars, sidebars, footers, cookie notices, popups, social share buttons, comment sections, and other non-content elements before conversion; uses 20+ CSS selectors to identify noise elements
-
Metadata extraction — Automatically extracts the page title from
<title>tags, counts the number of words in the output, and reports the number of images found in the original HTML -
Batch processing — Convert up to 50 items in a single run, mixing URL and raw HTML inputs with independent mode settings per item
-
Flexible output — JSON for programmatic consumption (contains full Markdown + metadata), plain text for quick review with truncated Markdown preview, or CSV for spreadsheet-friendly metadata export
-
Clean Mode Selectors — 20+ CSS/jQuery-style selectors used to remove noise: structural elements (nav, footer, aside), advertising containers (.ad, .advertisement, .banner, .promo), social widgets (.social-share, .share-buttons), technical markup (script, style, iframe), and notification overlays (.cookie, .popup)
-
Comprehensive summaries — Every run appends a summary row with total items converted, total word count across all documents, clean mode usage count, and error count
🚀 Quick Start
Convert from URL — Standard Mode
{"source": "https://example.com/article","sourceType": "url","mode": "standard"}
Response example (standard mode):
{"original_url": "https://example.com/article","markdown": "# Article Title\n\nThis is the article content converted to clean Markdown.\n\n## Section One\n\n- Bullet point one\n- Bullet point two\n\n> A blockquote from the article.\n\n| Header 1 | Header 2 |\n|----------|----------|\n| Cell A | Cell B |\n","title": "Article Title | Example Site","word_count": 845,"images_count": 3,"error": ""}
Convert Raw HTML
{"source": "<h1>Hello World</h1><p>Welcome to <strong>Markdown</strong> conversion.</p><ul><li>Item A</li><li>Item B</li></ul>","sourceType": "raw","mode": "standard"}
Response example (raw HTML):
{"original_url": "","markdown": "# Hello World\n\nWelcome to **Markdown** conversion.\n\n- Item A\n- Item B\n","title": "","word_count": 14,"images_count": 0,"error": ""}
Convert URL with Clean Mode
{"source": "https://example.com/article","sourceType": "url","mode": "clean"}
Response example (clean mode — notice ad/content noise removed):
{"original_url": "https://example.com/article","markdown": "# Article Title\n\nClean article body without navigation, ads, or sidebars.\n\n## Main Content\n\nThe article text converted directly.\n","title": "Article Title | Example Site","word_count": 620,"images_count": 2,"error": ""}
Batch Mode — Mixed Inputs
{"batchMode": true,"batchData": [{"source": "https://site1.com/article","sourceType": "url","mode": "clean"},{"source": "<h2>Offline Content</h2><p>Raw HTML snippet</p>","sourceType": "raw","mode": "standard"}]}
📋 Input Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
source | string | "" | HTML content or URL to convert. For url sourceType, must be a valid HTTP(S) URL. For raw sourceType, must be valid HTML markup. |
sourceType | string | "url" | Input type: url (fetch from the web) or raw (treat source as raw HTML string) |
mode | string | "standard" | Conversion mode: standard (full HTML → Markdown) or clean (strips noise before conversion, premium feature) |
outputFormat | string | "json" | Output format: json (full results with Markdown content), plain (truncated Markdown for quick review), or csv (metadata only) |
batchMode | boolean | false | Enable batch processing for multiple independent conversion jobs in a single run |
batchData | array | [] | Array of per-item input objects, each with its own source, sourceType, and mode. Maximum 50 entries. |
📤 Output Format
Each conversion produces one result row:
| Field | Type | Description |
|---|---|---|
original_url | string | Source URL (only populated when sourceType is url). Empty for raw HTML input. |
markdown | string | The converted Markdown content. Full document in json format, truncated to 2000 characters in plain format. Not included in csv format. |
title | string | Page title extracted from the HTML <title> tag. Empty string if no title found. |
word_count | integer | Number of words in the output Markdown |
images_count | integer | Number of <img> tags found in the original HTML |
error | string | Error description if fetching or conversion failed. Empty string on success. |
CSV Format Fields
When outputFormat is csv, the output includes: original_url, title, word_count, images_count, and error. The full Markdown content is excluded from CSV format for spreadsheet compatibility.
Summary Row
A _summary row is appended at the end with aggregate statistics:
| Field | Type | Description |
|---|---|---|
_summary | boolean | Always true for the summary row |
total_items | integer | Number of items processed |
total_words | integer | Total word count across all converted documents |
clean_mode_used | integer | Number of items converted with clean mode enabled |
error_count | integer | Number of items that failed conversion |
⚙️ Technical Details
Conversion Pipeline
The conversion process follows five steps:
-
Input acquisition: If
sourceTypeisurl, the actor fetches the page with async HTTP (urllib) using a 30-second timeout and automatic redirect following. IfsourceTypeisraw, thesourcestring is used directly as HTML without any network request. -
Title extraction: The
<title>tag content is extracted from the HTML using BeautifulSoup'sfind("title")method. If no title tag exists, an empty string is returned. -
Image counting: All
<img>tags are counted using a regex pattern (<img[^>]+>) applied to the raw HTML. This counts all images regardless of whether they would render in the Markdown output. -
Clean mode (optional): When
modeisclean, the HTML is parsed with BeautifulSoup and elements matching 20+ CSS selectors are removed viatag.decompose(). This includes structural elements (nav, footer, aside), advertising containers, social widgets, comment sections, cookie notices, popups, and technical markup (script, style, iframe). -
Markdown conversion: The HTML (cleaned or original) is converted to Markdown using the
markdownifylibrary with ATX heading style (#through######), dash (-) bullet markers, and automatic code block detection.
Clean Mode Selectors
Clean mode removes all elements matching these CSS selectors:
| Category | Selectors | Purpose |
|---|---|---|
| Structural | nav, footer, aside, .header, .footer | Remove page chrome |
| Navigation | .nav, .navigation, .menu, [role=navigation] | Remove menus/breadcrumbs |
| Advertising | .advertisement, .ads, .ad, .banner, .promo | Remove ad content |
| Social | .social-share, .share-buttons | Remove sharing widgets |
| Content noise | .sidebar, .related-posts, .comments, #comments, [role=complementary] | Remove side content |
| Technical | script, style, noscript, iframe | Remove non-content markup |
| Notifications | .cookie, .popup | Remove overlays |
Markdown Element Mapping
| HTML Element | Markdown Output | Example |
|---|---|---|
<h1>–<h6> | ATX headings | # Title, ## Section |
<p> | Paragraph text | blank-line-separated |
<ul>, <ol> | List items | - item / 1. item |
<table> | Pipe table | pipe-separated columns |
<pre><code> | Fenced code block | triple backtick wrap |
<code> | Inline code | backtick-wrapped text |
<a> | Inline link | [text](url) |
<img> | Inline image |  |
<blockquote> | Blockquote | > quoted text |
<strong>, <b> | Bold | **bold text** |
<em>, <i> | Italic | *italic text* |
<br> | Line break | two trailing spaces |
Error Handling
- URL fetch failures: If a URL cannot be fetched (timeout, DNS error, 4xx/5xx), the result contains an
errordescription and all other fields are empty or zero - Conversion errors: If markdownify encounters malformed HTML, the actor catches the exception and returns it in the
errorfield - Batch isolation: Individual item failures do not block processing of remaining items in the batch
- Empty input: If
sourceis empty, the item is silently skipped
🎯 Use Cases
-
LLM data preparation — Convert web content to clean Markdown for RAG pipelines, AI training datasets, and fine-tuning corpora; clean mode strips navigation noise so only the article content is processed
-
Documentation migration — Bulk-convert HTML documentation to Markdown for static site generators (Jekyll, Hugo, Docusaurus, MkDocs) — preserves headings, code blocks, tables, and link structure
-
Content archiving — Save stripped, readable versions of web articles and blog posts as clean Markdown files for long-term archival, offline reading, and cross-referencing
-
Web scraping pipelines — Integrate with crawlers and web scrapers to produce clean, structured Markdown output ready for further processing, NLP analysis, or content extraction
-
Email to Markdown conversion — Convert HTML-formatted emails to clean Markdown for note-taking systems, CRM logging, or knowledge base ingestion
-
Newsletter preparation — Clean and reformat web content for inclusion in email newsletters, stripping promotional elements while preserving the core article body
-
Static site generation — Convert legacy HTML content for use with Hugo, Jekyll, or Gatsby static sites that require Markdown source files
Choosing Between Standard and Clean Mode
The choice between standard and clean mode depends on your use case:
| Scenario | Recommended Mode | Rationale |
|---|---|---|
| LLM data preparation | clean | Remove navigation noise for clean training data |
| Documentation migration | standard | Preserve all page structure including navigation |
| Content archiving | clean | Store only the article body for compact archives |
| Web scraping pipeline | clean | Produce focused Markdown for downstream processing |
| Full page capture | standard | Keep a complete record of the page as rendered |
Clean mode is particularly valuable when the output Markdown will be fed into LLM pipelines, as navigation text and advertisements can confuse model training and RAG retrieval.
❓ FAQ & Troubleshooting
Q: What is the difference between standard and clean mode?
A: standard mode converts the entire HTML document to Markdown, including navigation, sidebars, and ads. clean mode (premium) pre-processes the HTML to remove these non-content elements before conversion, producing a cleaner, more focused document.
Q: Does clean mode work on all websites? A: Clean mode uses a comprehensive set of CSS selectors targeting common class names and element types used by most websites. It works well on news sites, blogs, documentation sites, and articles. Highly customized or JavaScript-rendered sites may retain some navigation elements.
Q: How are tables converted? A: HTML tables are converted to GitHub-flavored Markdown pipe tables with header row, separator row, and data rows. Complex tables (colspan/rowspan, nested tables) may have simplified representation.
Q: Can I process JavaScript-rendered pages? A: The actor fetches raw HTML from the URL and does not execute JavaScript. Pages that require JavaScript to render their content may produce incomplete Markdown. For JS-rendered content, consider a headless browser scraper first.
Q: Why is the word count different between standard and clean mode? A: Clean mode removes navigation, ads, sidebars, and other non-content elements, so the word count is typically lower than standard mode which includes all visible text on the page.
Q: What is the maximum input size for raw HTML? A: Raw HTML input is limited only by the Apify platform's input size constraints. Very large HTML documents (>1 MB) may be subject to platform-level limits. For large documents, consider converting via URL instead.
Q: How is the title extracted?
A: The actor extracts text from the first <title> tag in the HTML using BeautifulSoup. If the page uses JavaScript to set the title, the static HTML <title> value is used.
Q: Can I convert multiple URLs with different modes in one run?
A: Yes. Use batch mode (batchMode: true) with batchData array. Each entry in the array can have its own source, sourceType, and mode settings.
Q: What image formats are counted?
A: The actor counts all <img> tags regardless of src format (jpg, png, gif, svg, webp, etc.). Image counting happens on the raw HTML before conversion, so even images that would not render in Markdown are counted.
Q: Does clean mode remove inline styles? A: No. Clean mode removes structural elements (nav, aside, footer, etc.) and containers identified by class/id/role selectors. Inline styles and formatting within the remaining content are preserved and converted to Markdown formatting.
Q: How are nested lists converted? A: The markdownify library preserves nested list structures with appropriate indentation. Unordered sub-lists use dashes, and ordered sub-lists use numbers with correct nesting.
Q: Can I convert an HTML file from my local machine?
A: The actor runs on the Apify cloud platform and cannot access local files. To convert a local HTML file, either upload it to a publicly accessible URL and use sourceType: "url", or paste the HTML content directly as sourceType: "raw".
Q: What happens if the URL returns a non-HTML content type?
A: If the URL returns a non-HTML response (e.g., PDF, image, JSON), the actor still attempts conversion. Results may be unpredictable or empty. The error field will describe the issue if conversion fails.
Q: Does the actor preserve HTML comments?
A: No. HTML comments (<!-- -->) are stripped during conversion and do not appear in the Markdown output.
Q: How are <pre> blocks with code converted?
A: <pre><code> blocks are converted to fenced code blocks using triple backticks. If the <code> tag has a class attribute with a language hint (e.g., class="language-python"), the language identifier is included after the opening backticks.
Q: Can I control the heading style in the output?
A: The conversion uses ATX heading style (# through ######) by default. Setext style (underlined with = and -) is not currently supported.
Q: How are <hr> horizontal rules converted?
A: Horizontal rules (<hr>) are converted to three dashes (---) on a separate line.
Q: Are <br> line breaks preserved?
A: Yes. <br> tags are converted to two trailing spaces followed by a newline, which is the Markdown convention for a hard line break.
Q: How does the actor handle <table> elements with colspan/rowspan?
A: Complex table attributes like colspan and rowspan may not be fully preserved in the pipe-table Markdown output. Simple tables with aligned columns convert cleanly; highly complex layouts may produce simplified representations.
Q: Can I use the actor to clean up email HTML for archiving?
A: Yes. Copy the HTML source of an email (most email clients have a "show original" or "view source" option) and paste it as sourceType: "raw" input for conversion to clean Markdown suitable for archiving and search.
Q: What is the difference between sourceType: "url" and sourceType: "raw"?
A: url fetches the HTML from a live web URL using an async HTTP client. raw treats the source string directly as HTML content without making any network request. Use raw for offline HTML files, email sources, or pre-fetched content.