DEV Community

bao001 xiao
bao001 xiao

Posted on

Turn Any Web Page into Markdown from Your Terminal (Build a web2md CLI)

We've all been there: you're mid-flow in the terminal, and you want to grab the content of a web page — to read it, save it, or feed it to another tool. Opening a browser, waiting for it to load, hunting for a "reader mode," and copy-pasting is a chore that breaks your flow.

What if you could just run:

web2md https://example.com/great-article > note.md
Enter fullscreen mode Exit fullscreen mode

...and get clean, readable Markdown straight into your terminal — no browser, no ads, no nav bars, no cookie banners?

In this article, you'll build a tiny web2md command-line tool on top of the Web to Markdown/JSON API — and see why piping web content through the Unix toolchain is a superpower.

The API at a glance

One HTTP call turns any URL into clean Markdown, JSON, or plain text.

Endpoint:

POST https://web2md-api-production-d822.up.railway.app/extract
Enter fullscreen mode Exit fullscreen mode

Request body:

{
  "url": "https://example.com/great-article",
  "format": "markdown",
  "max_length": 50000
}
Enter fullscreen mode Exit fullscreen mode
  • format — markdown, json, or text
  • max_length — cap the response size in characters (up to 50000)
  • Free tier: 50 requests/day
  • Get your key on RapidAPI

Response:

{
  "success": true,
  "title": "The Great Article",
  "content": "# The Great Article\n\n## Introduction\n\n...",
  "description": "A short summary",
  "word_count": 1523,
  "response_time_ms": 210
}
Enter fullscreen mode Exit fullscreen mode

The content field is the page already converted to clean Markdown — headings, paragraphs, lists, and code blocks, with scripts, nav, and ads stripped away.

Build the CLI

Create web2md (no dependencies beyond requests):

#!/usr/bin/env python3
"""web2md — turn any URL into clean Markdown from your terminal."""

import argparse
import json
import sys

import requests

API_URL = "https://web2md-api-production-d822.up.railway.app/extract"


def extract(url: str, fmt: str = "markdown", max_length: int = 50000) -> dict:
    resp = requests.post(
        API_URL,
        json={"url": url, "format": fmt, "max_length": max_length},
        timeout=30,
    )
    resp.raise_for_status()
    return resp.json()


def main() -> int:
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument("url", nargs="+", help="One or more URLs to extract")
    parser.add_argument(
        "-f", "--format", choices=["markdown", "json", "text"], default="markdown"
    )
    parser.add_argument("-o", "--output", help="Write output to a file instead of stdout")
    parser.add_argument("-m", "--max-length", type=int, default=50000)
    args = parser.parse_args()

    for url in args.url:
        data = extract(url, args.format, args.max_length)
        if not data.get("success"):
            print(f"error: {data.get('message', 'extraction failed')}", file=sys.stderr)
            return 1

        if args.format == "json":
            out = json.dumps(data, indent=2)
        else:
            out = data["content"]

        if args.output:
            with open(args.output, "w", encoding="utf-8") as fh:
                fh.write(out)
            print(f"saved {url} -> {args.output}", file=sys.stderr)
        else:
            print(out)

    return 0


if __name__ == "__main__":
    raise SystemExit(main())
Enter fullscreen mode Exit fullscreen mode

Make it executable and you're off:

chmod +x web2md
./web2md https://example.com/great-article
Enter fullscreen mode Exit fullscreen mode

The part that makes it fun: piping

Because the CLI writes to stdout by default, it slots right into the Unix pipeline:

# Save any article as a note
web2md https://example.com/post > note.md

# Grep the clean text for a keyword
web2md https://example.com/post | grep -i "docker"

# Preview it nicely in the terminal with glow
web2md https://example.com/post | glow -

# Pull machine-readable data for a script
web2md -f json https://example.com/post | jq '{title, word_count}'

# Batch-extract several pages into one file
web2md https://a.com/1 https://b.com/2 https://c.com/3 > combined.md
Enter fullscreen mode Exit fullscreen mode

You can even pipe it straight into an LLM for a summary:

web2md https://example.com/post | llm "Summarize this in three bullet points"
Enter fullscreen mode Exit fullscreen mode

That's the whole point: once web content becomes clean Markdown on stdout, every tool you already have suddenly works on the open web.

Wrapping up

The Web to Markdown/JSON API does the hard part — turning messy HTML into clean, structured content — so your tools stay tiny and your workflow stays in the terminal. A 50-line CLI is all it takes to make the entire web grep-able, save-able, and LLM-friendly.

  • Docs / free tier (50 requests/day): RapidAPI
  • Endpoint: https://web2md-api-production-d822.up.railway.app/extract

Happy piping. 🚀

Top comments (0)