Files
2026-10-31 14:47:15 +08:00
..
2026-10-31 14:47:15 +08:00
2026-10-31 14:47:15 +08:00
2026-10-31 14:47:15 +08:00
2026-10-31 14:47:15 +08:00

网页文章离线下载

使用 uv 管理 Python 环境和依赖(Python 3.10 或更新版本)。将 download_article.py 与 requirements.txt 放在同一个目录,并确保已安装 uv。

安装与运行

在这两个文件所在目录打开终端,执行:

uv run --no-project --python 3.12 --with-requirements requirements.txt python download_article.py 'https://mp.weixin.qq.com/s/Jcu2J5YlaMdxbAUgLMd56A'

uv 会自动准备 Python 3.12 和所需依赖,无需手动创建或激活虚拟环境。后续运行相同命令即可复用缓存。依赖继续通过 requirements.txt 管理,无需创建 pyproject.toml。

默认在运行命令时的当前目录创建文章目录,也可以用 -o /你的/保存目录 指定父目录。

当前目录/
└── 文章标题/
    ├── 文章标题.md
    ├── image001.png
    └── image002.jpg

图片后缀按实际文件内容判断;同一地址的图片只下载一次。正文中的图片引用使用相对路径,离线阅读时请保留整个目录。支持微信的延迟加载图片和行内 CSS 背景图,保留常见的标题、段落、列表、链接、表格等 Markdown 格式;公众号的复杂视觉排版不会原样复刻。

Markdown 开头不添加原文链接和作者/公众号信息,文章末尾统一追加 来源:公众号作者,如有侵权,请联系删除。。无法获取公众号作者时使用“未知作者”。接口返回的 source_url 仍保留,方便调用方追踪来源。

文件名中系统不允许的字符会替换为 _,过长标题会截短。已有同名目录时创建 文章标题 (2)/文章标题 (2).md,不会覆盖已有内容。

其他任务通过命令行调用

uv run --no-project --python 3.12 --with-requirements requirements.txt python download_article.py 'https://mp.weixin.qq.com/s/Jcu2J5YlaMdxbAUgLMd56A' --json

也可以从标准输入读取单个 JSON 请求:

printf '%s' '{"url":"https://mp.weixin.qq.com/s/Jcu2J5YlaMdxbAUgLMd56A","output_root":".","timeout":30,"allow_missing_images":false}' | uv run --no-project --python 3.12 --with-requirements requirements.txt python download_article.py --stdin-json

每次进程处理一个网址。JSON 模式下,标准输出只有一个 JSON 对象,路径均为绝对路径。调用方应解析 JSON,不要依赖错误消息的具体文字。

成功返回退出码 0:

{
  "ok": true,
  "title": "文章标题",
  "source_url": "https://example.com/article",
  "directory": "/完整路径/文章标题",
  "markdown": "/完整路径/文章标题/文章标题.md",
  "images": ["/完整路径/文章标题/image001.png"],
  "warnings": []
}

失败返回退出码 1:

{"ok": false, "error": "错误说明", "error_type": "ArticleDownloadError"}

命令行参数格式错误由 argparse 返回退出码 2,说明写入标准错误。--stdin-json 使用 JSON 中的参数,不使用其他命令行下载选项。

其他 Python 任务直接调用

将脚本放入调用方的 Python 模块搜索路径,并在调用方的 uv 环境中安装本脚本 requirements.txt 所列依赖后:

from download_article import save_article

result = save_article(
    url="https://mp.weixin.qq.com/s/Jcu2J5YlaMdxbAUgLMd56A",
    output_root=".",
    timeout=30,
    allow_missing_images=False,
)
saved_directory = result.directory  # 已保存文件所在目录(绝对路径字符串)
print(saved_directory)
# 完整结果可调用 result.to_dict()

函数失败时抛出异常,调用方可自行捕获。默认任何图片失败都会终止保存并清理半成品。若只希望尽量保存正文,可传 allow_missing_images=True 或命令行添加 --allow-missing-images,失败图片会替换为文字提示,详情写入 warnings。

微信可能返回验证、登录或失效页面,脚本会报告未找到正文,不会绕过访问限制。普通网页使用 article/main/body 提取,不适用于必须执行 JavaScript 才出现正文的页面。原文中的外链仍需联网,文章文字及成功下载的图片可离线查看。

如果接口对外提供服务,请由调用方限制网址及重定向目的地,只允许可信站点;此脚本本身允许访问运行机器能连接的 HTTP 地址。