Skip to main content

Convert public article links into configurable Markdown packages.

Project description

MagicMD

PyPI npm CI Docs License: MIT

中文 | English

把散落在网页里的好文章,变成你仓库里的 Markdown。

MagicMD 是一个面向公开文章链接的 Markdown 转换工具。你给它一条 URL,或者一整个 URL 列表,它把文章正文、图片、来源信息和转换报告整理成一个可长期保存的内容包。

uv tool install magicmd
# 或者
npm install -g magicmd
magicmd "https://mp.weixin.qq.com/s/example"
magicmd batch urls.txt -o output/

输出不是一段临时文本,而是一份可以直接进入内容工作流的目录:

output/article-title/
├── article.md
├── metadata.json
├── extraction-report.json
└── images/
    ├── cover.jpg
    ├── share_cover.jpg
    ├── img_001.png
    └── img_002.png

MagicMD 可以当 CLI 用,也可以作为 Agent Skill 使用。人负责给链接,工具负责落盘;Agent 负责批量整理时,也走同一套规则。

在线文档和配置生成器:magicmd.cn

适合做什么

  • 把微信公众号文章保存为 Markdown。
  • 把掘金、CSDN 技术文章沉淀到本地知识库。
  • 把公开文章批量整理到 GitHub、Hugo、Docusaurus、HaoGit 或自己的站点。
  • 给 Agent 一个稳定的“文章链接转 Markdown”能力,而不是每次重新写提示词。

MagicMD 不是浏览器收藏夹,也不是通用爬虫框架。它的目标更窄:把公开文章页面尽量干净、可追踪、可复用地转成 Markdown 内容包。

和同类工具有什么不同

很多工具可以把网页或文件转成 Markdown。MagicMD 更关心另一个问题:中文内容平台里的文章,怎么稳定变成能长期维护的 Markdown。

类型 常见特点 MagicMD 的差异
通用网页转 Markdown 工具 更适合标准网页、文档页、英文站点或 LLM 输入清洗。 MagicMD 针对微信公众号、掘金、CSDN 做平台适配,重点处理中文内容平台常见的富文本、跳转链接、代码控件和编辑器噪声。
微信文章转换脚本 往往能抓正文和图片,但配置、批量、报告和多平台扩展有限。 MagicMD 不只转微信,还保留 metadata.jsonextraction-report.json、批量报告和可配置 Markdown 输出,方便后续发布或自动化处理。
爬虫框架 能力强,但通常需要自己写解析逻辑、清洗规则和输出结构。 MagicMD 直接给文章采集场景一个可用 CLI:链接进去,内容包落盘。
手动复制到 Markdown 可控,但慢,图片、链接、代码块和来源信息很容易丢。 MagicMD 自动处理图片本地化、标题层级、代码块、链接、来源信息和失败 warning。

MagicMD 的优势不是“抓全网”,而是把中文技术内容归档这件事做细:微信视频会提取链接并尝试下载;掘金外链会尽量还原真实目标地址;CSDN 代码块会清理复制按钮、行号和编辑器控件;批量转换会留下报告,方便你知道哪篇文章需要人工复核。

安装

推荐用 uv 全局安装:

uv tool install magicmd
magicmd doctor

如果你习惯 pipx

pipx install magicmd
magicmd doctor

参与开发或想使用当前源码时,再使用 editable 安装:

git clone https://github.com/didilili/MagicMD.git
cd MagicMD
uv sync --extra dev
uv run magicmd doctor

还没有安装成全局命令时,把下面命令里的 magicmd 换成 uv run magicmd 即可。

uv run magicmd batch urls.txt -o output/

PyPI 和 npm

MagicMD 已发布到 PyPI:

uv tool install magicmd
pipx install magicmd

也可以通过 npm 安装。npm 包是一个轻量入口,底层仍调用 PyPI 版 MagicMD CLI,所以需要本机能使用 uvx

npm install -g magicmd
npx magicmd --version

npm wrapper 位于 npm/magicmd。它不会重新实现转换逻辑,只会把命令转发给:

uvx --from magicmd magicmd

Agent Skill

MagicMD 也可以作为 Agent Skill 安装。Skill 不复制转换逻辑,只规定 Agent 什么时候调用 MagicMD、怎么批量运行、转换后检查哪些文件,以及遇到失败时查看哪些报告。

如果你不想记命令,可以直接对支持 Skill 的 Agent 说:

请用 MagicMD 把这个公开文章链接转换成 Markdown 内容包,并告诉我输出了哪些文件和 warning。

安装源:

Repository: didilili/MagicMD
Skill path: skills/magicmd

使用 Codex 的 skill installer:

python3 ~/.codex/skills/.system/skill-installer/scripts/install-skill-from-github.py \
  --repo didilili/MagicMD \
  --path skills/magicmd

安装后重启 Codex,让 $magicmd 生效。

快速使用

转换单篇文章:

magicmd "https://mp.weixin.qq.com/s/example"

指定输出目录:

magicmd convert "https://juejin.cn/post/example" -o output/

批量转换:

magicmd batch urls.txt -o output/

urls.txt 一行一个链接:

https://mp.weixin.qq.com/s/example
https://juejin.cn/post/example
https://blog.csdn.net/user/article/details/123

重复跑同一批链接时,跳过已经生成过的内容包:

magicmd batch urls.txt -o output/ --skip-existing

确认要重新生成时,覆盖同名输出包:

magicmd batch urls.txt -o output/ --overwrite

覆盖时会先清理旧内容包里的生成文件,避免上一轮留下的图片或 DOCX 混进本次结果。

只要正文,不下载图片:

magicmd convert "https://blog.csdn.net/user/article/details/123" --no-images

同时生成 Word 文档:

magicmd convert "https://mp.weixin.qq.com/s/example" -o output/ --format docx

DOCX 导出会保留默认 Markdown 内容包,并额外写出 article.docx。它依赖本机安装的 Pandoc;如果你希望每次转换都生成 Word,可以在 .magicmd.toml 里设置 [docx] enabled = true

Python SDK 使用方式

除了 CLI,MagicMD 也可以被其他 Python 项目直接 import。这适合 Web 后端、内容管理系统、定时任务或 Agent Runtime:你不需要额外启动一个 MagicMD 服务,也不需要从命令行解析输出目录。

只在内存中返回结果:

from magicmd import convert_article

result = convert_article(
    url="https://mp.weixin.qq.com/s/example",
    platform="auto",
    output_dir=None,
    download_images=True,
    config_path=None,
)

print(result.title)
print(result.markdown)
print(result.metadata)

同时生成内容包:

from magicmd import convert_article

result = convert_article(
    url="https://juejin.cn/post/example",
    output_dir="output",
)

print(result.package_dir)
print(result.report)

convert_article() 返回的是稳定的 Pydantic 对象 ArticleConversionResult,常用字段包括:

字段 说明
title / author / published_at 文章标题、作者和发布时间。
platform wechatjuejincsdngeneric 等平台标识。
source_url / canonical_url 原始链接和规范链接。
excerpt 页面能提取到的摘要。
markdown 转换后的 Markdown 字符串。
content_hash 基于正文内容生成的 hash,方便去重。
metadata.cover_image 微信文章封面图资产,包含 source_urllocal_pathalt;没有提取到时为空。默认会插入正文开头,可用 markdown.include_cover_image = false 关闭。
metadata.share_cover_image 微信 1:1 分享缩略图资产,字段结构同 cover_image;没有提取到时为空。
images 图片资产列表,包含 source_urllocal_pathmarkdown_pathaltmarkdown_path 是 Markdown 中实际引用的路径;local_path 是本地已下载图片的文件系统路径,方便外部系统复制到自己的 media 目录后重写链接。
warnings 抓取、解析、媒体下载中的 warning。
metadata metadata.json 对齐的结构化数据。
report extraction-report.json 对齐的转换报告。
package_dir 只有传入 output_dir 并成功写出内容包时才有值。
docx_path 生成 DOCX 时的本地 Word 文件路径;未启用 DOCX 或未写出文件时为空。

错误类型也可以被后端明确捕获:

from magicmd import FetchError, ParseError, UnsupportedPlatformError, convert_article

try:
    result = convert_article("https://mp.weixin.qq.com/s/example")
except UnsupportedPlatformError:
    ...
except FetchError:
    ...
except ParseError:
    ...

公开错误类型包括 UnsupportedPlatformErrorFetchErrorParseErrorMediaDownloadErrorConversionError。MagicMD 不包含 HaoGit 专属字段;HaoGit 或其他系统可以自行把 result.markdownresult.metadataresult.images 写入自己的数据表和媒体目录。

更完整的接入说明见 docs/integrations/python-sdk.md。如果你要接入 CMS、Django 或 HaoGit 一类业务系统,可以参考 docs/integrations/haogit-import.mdexamples/python

支持站点

站点 状态 默认抓取 说明
微信公众号 mp.weixin.qq.com 稳定主目标 camoufox v0.1 最主要的验证对象,已做多轮真实样本格式修复。
掘金 juejin.cn 实验支持 camoufox 已验证首页样本和复杂技术文章,重点看图片、代码块、外链和标题层级。
CSDN blog.csdn.net 实验支持 camoufox 已人工检查 10 篇复杂样本,重点修过代码块、Mermaid/SVG、目录链接和控件噪声。
通用网页 尽力支持 http 对标准 articlemain 或 Open Graph 元信息页面做基础提取。

更多站点说明见 docs/supported-sites.md

MagicMD 会生成什么

单篇文章会生成一个内容包:

output/
└── article-title/
    ├── article.md              # Markdown 正文
    ├── metadata.json           # 标题、作者、时间、来源、封面、hash 等
    ├── extraction-report.json  # 抓取、解析、媒体和 warning
    └── images/                 # 下载后的本地图片

微信公众号文章如果能提取到文章卡片封面,metadata.json 会包含 cover_imageshare_cover_image。开启图片下载时,它们会随正文图片保存到 images/;默认 Markdown 会把 cover_image 放在来源信息块下方,并用分割线和正文隔开。

批量转换会额外生成:

output/
├── batch-report.json           # 适合程序读取
└── batch-report.md             # 适合人工检查

默认的 article.md 类似这样:

---
title: "Example Article"
author: "Example Author"
platform: "wechat"
source_url: "https://mp.weixin.qq.com/s/example"
---

# Example Article

> Source: wechat
> Author: Example Author
> Original: https://mp.weixin.qq.com/s/example

正文内容...

CLI 和 Skill

MagicMD 有两个入口。

第一个是给人用的 CLI:

magicmd batch urls.txt -o output/

第二个是给 Agent 用的 skills/magicmd/SKILL.md。Skill 把“什么时候使用 MagicMD、怎么运行、检查哪些文件、遇到失败看什么报告”写成固定流程。这样 Agent 不需要每次猜命令,也不会把登录页、付费墙、验证码页面当成正常文章处理。

安装 Skill 时使用仓库路径 didilili/MagicMD,Skill 路径 skills/magicmd。更多可复制的 Agent 使用示例见 Agent Skill 文档

如果你未来要把 MagicMD 接入 HaoGit,建议让 Agent 先调用 Skill 完成采集和转换,再把 article.mdmetadata.json 和图片交给发布流程。

配置

生成配置文件:

magicmd config init

配置文件示例见 .magicmd.example.toml

常用配置:

[output]
directory = "output"
overwrite = false
save_debug_html = "on_failure"

[markdown]
template = "default"
front_matter = "yaml"
include_source_block = true
include_cover_image = true
heading_offset = 0

[images]
download = true
directory = "images"
filename_pattern = "img_{index:03d}.{ext}"

[docx]
enabled = false
pandoc_path = "pandoc"
reference_doc = ""

[fetch]
timeout_seconds = 20
browser_timeout_seconds = 15
browser_attempts = 2

[ui]
language = "zh-CN"

常见选项:

配置 说明
output.directory 默认输出目录。
output.overwrite 是否覆盖同名内容包。
output.save_debug_html alwayson_failurenever,控制是否保存 debug.html
markdown.front_matter yamlnone
markdown.template defaultclean
markdown.include_cover_image 是否把微信文章卡片封面插入 Markdown 正文开头。
markdown.heading_offset 统一调整 Markdown 标题层级。
images.download 是否下载图片。
docx.enabled 是否在 Markdown 内容包旁额外生成 article.docx
docx.pandoc_path Pandoc 可执行文件路径,默认使用 PATH 中的 pandoc
docx.reference_doc 可选 Word 样式模板,用 Pandoc 的 reference docx 控制样式。
fetch.browser_attempts 浏览器模式失败后的总尝试次数。
ui.language CLI 终端语言,默认中文优先;设置为 en-US 可切换为英文提示。
platforms.<name>.browser 使用 httpcamoufox
platforms.<name>.wait_selector 浏览器抓取时等待的选择器。

检查环境:

magicmd doctor

doctor 会检查 Python 版本、MagicMD 版本、配置文件解析、输出目录可写性、Camoufox 是否可用,以及各平台默认抓取方式。脚本、CI 或 Agent 可以使用 JSON 输出:

magicmd doctor --json

使用前知道

MagicMD 只处理公开文章页面。它不会绕过登录、付费墙、私有内容、验证码或平台访问限制。

如果遇到 403、验证码、登录限制、视频防盗链或动态资源失效,MagicMD 会尽量保留已经能提取的内容,并在报告里记录 warning 或失败原因。

如果某个平台的页面结构变化导致转换效果下降,建议先保留输出目录里的 extraction-report.json,再用同一链接复现问题。真实样本记录放在 docs/wechat-regression-corpus.mdtests/fixtures/site_validation_manifest.json,不放在首页展开。

开发文档

接下来

v0.5.0 已补齐 DOCX 导出、微信封面图、真实回归清单和手动 Trusted Publishing 发布流程。下一步会继续评估把转换后的文章发布到 GitHub 仓库等可选工作流。完整计划见 ROADMAP.md

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

magicmd-0.6.0.tar.gz (372.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

magicmd-0.6.0-py3-none-any.whl (56.6 kB view details)

Uploaded Python 3

File details

Details for the file magicmd-0.6.0.tar.gz.

File metadata

  • Download URL: magicmd-0.6.0.tar.gz
  • Upload date:
  • Size: 372.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for magicmd-0.6.0.tar.gz
Algorithm Hash digest
SHA256 e65b20e303092e059703dd67e402b95ee95d1961d4d2d36b5bcaa15e3d11b72e
MD5 167f4c49cb7de82c7dd49fb22001bd6f
BLAKE2b-256 71f895df8880694cd30e8b7cfbdb7b046b5f7186ff1afbfbe485ac7eebd9fb72

See more details on using hashes here.

Provenance

The following attestation bundles were made for magicmd-0.6.0.tar.gz:

Publisher: publish.yml on didilili/MagicMD

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file magicmd-0.6.0-py3-none-any.whl.

File metadata

  • Download URL: magicmd-0.6.0-py3-none-any.whl
  • Upload date:
  • Size: 56.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for magicmd-0.6.0-py3-none-any.whl
Algorithm Hash digest
SHA256 3cec8388f3ee44458f77bb5a7025a84008d8dafa7093ede471c6fb6610752488
MD5 c4db5ef6cd38f8e900bbf4ce8c7c9c7b
BLAKE2b-256 cac3934625e50719394895491a3a2b27003e41e5c7e71398a86d2aefb8985d8c

See more details on using hashes here.

Provenance

The following attestation bundles were made for magicmd-0.6.0-py3-none-any.whl:

Publisher: publish.yml on didilili/MagicMD

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page