A powerful tool to scrape and download documentation sites (Mintlify, GitBook, MkDocs, ReadMe.com, Docusaurus, Stoplight, and more) to local Markdown files. This tool automatically discovers all documentation pages and downloads their source code while preserving the directory structure.
- � Automatic URL Discovery: Starts from a base URL and recursively crawls all documentation pages
- 📁 Structure Preservation: Maintains the exact directory structure from the website
- ⚡ High Performance: Asynchronous downloads with configurable concurrency
- � Smart Source Detection: Automatically tries
.mdxand.mdsuffixes to get source code (Mintlify), or parses HTML for GitBook, MkDocs, ReadMe.com, and others - � Flexible Output: Force all files to
.mdextension or keep original extensions - 📈 Incremental Downloads: Skip existing files to resume interrupted downloads
- 🛡️ Content Validation: Verifies downloaded content is valid Markdown (not HTML error pages)
- 🌐 Proxy Support: Works with system proxy settings (HTTP, HTTPS, SOCKS)
- 📊 Rich Progress: Beautiful progress bars and detailed statistics
- 🖥️ SPA Support: Uses Playwright for JavaScript-rendered documentation sites (Bitget, Docusaurus, Stoplight)
| Platform | Command | Discovery Method |
|---|---|---|
| Mintlify | mintlify-download |
mint.json / sitemap / HTML crawling |
| GitBook | gitbook-download |
sitemap / HTML navigation |
| MkDocs | mkdocs-download |
sitemap / HTML navigation |
| ReadMe.com | readme-download |
Recursive navigation crawling |
| Docusaurus | docusaurus-download |
sitemap + Playwright rendering |
| Stoplight | stoplight-download |
sitemap + Playwright rendering |
| Nextra / Webshare | webshare-download |
HTML crawling + html2text |
| Arc Blog | arc-blog-download |
JSON-LD + HTML parsing |
| Circle OpenAPI | circle-openapi-download |
OpenAPI JSON manifest |
| CoinW | coinw-download |
sitemap + markdownify |
| HTX | htx-download |
API category tree + endpoint details |
| Bitget | bitget-download |
Playwright sidebar expansion |
| PancakeSwap | pancakeswap-download |
Vocs framework sidebar extraction |
- Python 3.10 or higher
- uv package manager (recommended) or pip
# Clone the repository
git clone https://github.com/akjong/docs-download.git
cd docs-download
# Install dependencies and the package
uv sync
# All CLI commands are now available# Clone the repository
git clone https://github.com/akjong/docs-download.git
cd docs-download
# Install the package in editable mode
pip install -e .mintlify-download --help
gitbook-download --help
mkdocs-download --help
readme-download --help
stoplight-download --help
docusaurus-download --help
webshare-download --help
arc-blog-download --help
circle-openapi-download --help
coinw-download --help
htx-download --help
bitget-download --help
pancakeswap-download --help# Download with force .md conversion and verbose output
uv run mintlify-download https://orderly.network/docs/build-on-omnichain \
--output ./orderly-docs \
--force-md \
--verbose
# Skip existing files to resume download
uv run mintlify-download https://docs.example.com/ --output ./docs --skip-existing
# Use more workers for faster download
uv run mintlify-download https://docs.example.com/ --concurrency 20 --output ./fast-downloadOptions:
| Parameter | Short | Description | Default |
|---|---|---|---|
url |
- | Required. Base URL of the Mintlify documentation site | - |
--output |
-o |
Output directory for downloaded files | ./downloaded_docs |
--force-md |
-f |
Force all files to be saved with .md extension |
False |
--concurrency |
-c |
Number of concurrent download workers | 10 |
--skip-existing |
-s |
Skip downloading files that already exist | False |
--verbose |
-v |
Enable verbose logging output | False |
# Download with verbose output
uv run gitbook-download https://hyperliquid.gitbook.io/hyperliquid-docs \
--output ./hyperliquid-docs --verbose
# Skip existing files to resume download
uv run gitbook-download https://docs.example.com/ --output ./docs --skip-existingOptions:
| Parameter | Short | Description | Default |
|---|---|---|---|
url |
- | Required. Base URL of the GitBook documentation site | - |
--output |
-o |
Output directory for downloaded files | ./downloaded_docs |
--concurrency |
-c |
Number of concurrent download workers | 5 |
--skip-existing |
-s |
Skip downloading files that already exist | False |
--verbose |
-v |
Enable verbose logging output | False |
# Download MkDocs Material documentation
uv run mkdocs-download https://squidfunk.github.io/mkdocs-material/ \
--output ./mkdocs-docs --verbose
# Download custom MkDocs site
uv run mkdocs-download https://docs.example.com/guide -o ./my-docsOptions: Same as GitBook (without --force-md).
# Download API reference documentation
uv run readme-download https://developer.rise.trade/reference/ \
--output ./rises-api --verboseOptions: Same as GitBook.
# Download Docusaurus-based documentation (uses Playwright for SPA rendering)
uv run docusaurus-download https://docs.example.com/ --output ./docsOptions: Same as GitBook.
# Download Stoplight documentation (uses Playwright for SPA rendering)
uv run stoplight-download https://docs.stoplight.io/docs/prism/ --output ./prism-docsOptions: Same as GitBook, but concurrency defaults to 10.
# Download Nextra-based documentation
uv run webshare-download https://apidocs.webshare.io/ --output ./webshare-docsOptions: Same as GitBook, but concurrency defaults to 10.
# Download all Arc blog articles
uv run arc-blog-download --output ./arc-blog --verbose
# Custom blog URL
uv run arc-blog-download --base-url https://www.arc.network/blog -o ./arc-blogOptions:
| Parameter | Short | Description | Default |
|---|---|---|---|
--base-url |
-u |
Base URL of the Arc blog | https://www.arc.network/blog |
--output |
-o |
Output directory | arc/blog |
--verbose |
-v |
Enable verbose output | False |
# Download Circle OpenAPI files
uv run circle-openapi-download --output ./circle-openapiOptions:
| Parameter | Description | Default |
|---|---|---|
--url |
URL to openapi.json | https://developers.circle.com/openapi.json |
--output |
Output directory | ./circle-openapi |
--base-url |
Base URL for downloading OpenAPI files | https://developers.circle.com/openapi |
--skip-existing |
Skip products that already exist | False |
# Download CoinW API docs
uv run coinw-download https://www.coinw.com/api-doc/en/common/introduction \
--output ./coinw-docs -c 10Options:
| Parameter | Short | Description | Default |
|---|---|---|---|
url |
- | Required. Base URL of CoinW API docs | - |
--output |
-o |
Output directory | ./downloaded_docs |
--concurrency |
-c |
Number of concurrent downloads | 5 |
--skip-existing |
-s |
Skip existing files | False |
--verbose |
-v |
Enable verbose output | False |
# Download HTX API docs (fetches category tree from HTX API)
uv run htx-download --output ./htx-docsOptions:
| Parameter | Short | Description | Default |
|---|---|---|---|
--output |
-o |
Output directory | ./htx/docs |
--concurrency |
-c |
Number of concurrent downloads | 5 |
--skip-existing |
-s |
Skip existing files | False |
--verbose |
-v |
Enable verbose output | False |
# Download Bitget API docs (uses Playwright for sidebar discovery)
uv run bitget-download https://www.bitget.com/api-doc/uta -o ./bitget
# Download contract API docs
uv run bitget-download https://www.bitget.com/api-doc/contract -o ./bitget-contractOptions:
| Parameter | Short | Description | Default |
|---|---|---|---|
url |
- | Required. Base URL of the documentation section | - |
--output |
-o |
Output directory | ./downloaded_docs |
--concurrency |
-c |
Number of concurrent downloads | 10 |
--skip-existing |
-s |
Skip existing files | False |
--verbose |
-v |
Enable verbose output | False |
# Download PancakeSwap Infinity docs (Vocs framework)
uv run pancakeswap-download --output ./pancakeswap-docsOptions:
| Parameter | Short | Description | Default |
|---|---|---|---|
--base-url |
-u |
Base URL of PancakeSwap Infinity docs | https://developer.pancakeswap.finance/contracts/infinity/overview |
--output |
-o |
Output directory | ./pancakeswap |
--base-path |
-p |
Base path to filter URLs (auto-detected) | None |
--verbose |
-v |
Enable verbose output | False |
- Start with Base URL: Add the provided base URL to the processing queue
- Parse Configuration/HTML: Attempt to fetch and parse configuration files (mint.json for Mintlify) or HTML pages to find all documentation links
- Link Filtering: Only keep links that:
- Belong to the same domain
- Are under the base URL path
- Don't match excluded patterns (images, API routes, etc.)
- Deduplication: Use a set to avoid processing the same URL multiple times
For each discovered URL, the tool:
- Try Source Access: For Mintlify, try
{url}.mdxfirst, then{url}.md; for GitBook/MkDocs/ReadMe, parse HTML content - Content Validation: Check that the response contains valid content
- Path Mapping: Convert URL path to local file path
- File Saving: Write content to appropriate location with correct extension
- AsyncIO Queue: Manages URLs to be processed
- Semaphore: Limits concurrent downloads to prevent overwhelming servers
- Worker Pool: Multiple async workers process URLs from the queue
- Progress Tracking: Real-time progress bars show download status
For SPA (Single Page Application) documentation sites like Bitget, Docusaurus, and Stoplight:
- Launch headless Chromium browser
- Expand sidebar navigation to discover all links
- Navigate to each page and extract rendered HTML
- Convert HTML to Markdown using html2text
The tool preserves the URL structure in the local filesystem:
# URL Structure
https://docs.example.com/
├── guide/
│ ├── getting-started.md
│ └── advanced/
│ └── configuration.md
└── api/
├── rest-api.md
└── websocket.md
# Becomes Local Structure
./downloaded_docs/
├── guide/
│ ├── getting-started.md
│ └── advanced/
│ └── configuration.md
└── api/
├── rest-api.md
└── websocket.md
- Python 3.10+: Modern Python with advanced async features
- httpx[socks]: Asynchronous HTTP client with proxy support
- beautifulsoup4: HTML parsing and link extraction
- rich: Beautiful terminal UI and progress bars
- click: Command-line interface framework
- playwright: Headless browser for SPA documentation sites
- markdownify / html2text: HTML to Markdown conversion
- uv: Fast Python package manager
This project uses Ruff for linting and formatting.
# Check for linting issues
uv run ruff check .
# Auto-fix linting issues
uv run ruff check --fix .
# Format code
uv run ruff format .
# Run both linting and formatting
uv run ruff check --fix . && uv run ruff format .src/
├── mintlify_download/ # Mintlify documentation scraper
├── gitbook_download/ # GitBook documentation scraper
├── mkdocs_download/ # MkDocs documentation scraper
├── readme_download/ # ReadMe.com documentation scraper
├── stoplight_download/ # Stoplight documentation scraper (Playwright)
├── docusaurus_download/ # Docusaurus documentation scraper (Playwright)
├── webshare_download/ # Nextra/Webshare documentation scraper
├── arc_blog_download/ # Arc blog scraper
├── circle_openapi_download/# Circle OpenAPI files downloader
├── coinw_download/ # CoinW API documentation scraper
├── htx_download/ # HTX API documentation scraper
├── bitget_download/ # Bitget API documentation scraper (Playwright)
├── pancakeswap_download/ # PancakeSwap Infinity docs scraper
├── docs_download/ # Core documentation utilities
├── download-gitbook/ # Legacy GitBook download script
└── download-lobehub/ # Legacy LobeHub blog download script
"No source found" for some pages
- Some pages might be dynamically generated or not have source files
- For SPA sites, try using the Playwright-based scrapers
Rate limiting
- Reduce
--concurrencyvalue - CoinW and HTX scrapers have built-in rate-limit handling with retries
Proxy issues
- The tool automatically uses system proxy settings
- For SOCKS proxies, ensure
socksiopackage is installed
Large documentation sites
- Use
--skip-existingfor resumable downloads - Increase
--concurrencyfor faster downloads (if allowed by server)
Use --verbose flag to see detailed information about:
- URLs being discovered
- Download attempts and results
- Content validation decisions
- File saving operations
MIT License - see LICENSE file for details.
Bob Liu (akagi201@gmail.com)