first commit
This commit is contained in:
14 files changed
+1627
No files matched your search
@@ -0,0 +1,89 @@
|
||||
# 网页文章离线下载
|
||||
|
||||
使用 uv 管理 Python 环境和依赖(Python 3.10 或更新版本)。将 `download_article.py` 与 `requirements.txt` 放在同一个目录,并确保已安装 uv。
|
||||
|
||||
## 安装与运行
|
||||
|
||||
在这两个文件所在目录打开终端,执行:
|
||||
|
||||
```sh
|
||||
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 /你的/保存目录` 指定父目录。
|
||||
|
||||
```text
|
||||
当前目录/
|
||||
└── 文章标题/
|
||||
├── 文章标题.md
|
||||
├── image001.png
|
||||
└── image002.jpg
|
||||
```
|
||||
|
||||
图片后缀按实际文件内容判断;同一地址的图片只下载一次。正文中的图片引用使用相对路径,离线阅读时请保留整个目录。支持微信的延迟加载图片和行内 CSS 背景图,保留常见的标题、段落、列表、链接、表格等 Markdown 格式;公众号的复杂视觉排版不会原样复刻。
|
||||
|
||||
Markdown 开头不添加原文链接和作者/公众号信息,文章末尾统一追加 `来源:公众号作者,如有侵权,请联系删除。`。无法获取公众号作者时使用“未知作者”。接口返回的 `source_url` 仍保留,方便调用方追踪来源。
|
||||
|
||||
文件名中系统不允许的字符会替换为 `_`,过长标题会截短。已有同名目录时创建 `文章标题 (2)/文章标题 (2).md`,不会覆盖已有内容。
|
||||
|
||||
## 其他任务通过命令行调用
|
||||
|
||||
```sh
|
||||
uv run --no-project --python 3.12 --with-requirements requirements.txt python download_article.py 'https://mp.weixin.qq.com/s/Jcu2J5YlaMdxbAUgLMd56A' --json
|
||||
```
|
||||
|
||||
也可以从标准输入读取单个 JSON 请求:
|
||||
|
||||
```sh
|
||||
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`:
|
||||
|
||||
```json
|
||||
{
|
||||
"ok": true,
|
||||
"title": "文章标题",
|
||||
"source_url": "https://example.com/article",
|
||||
"directory": "/完整路径/文章标题",
|
||||
"markdown": "/完整路径/文章标题/文章标题.md",
|
||||
"images": ["/完整路径/文章标题/image001.png"],
|
||||
"warnings": []
|
||||
}
|
||||
```
|
||||
|
||||
失败返回退出码 `1`:
|
||||
|
||||
```json
|
||||
{"ok": false, "error": "错误说明", "error_type": "ArticleDownloadError"}
|
||||
```
|
||||
|
||||
命令行参数格式错误由 argparse 返回退出码 `2`,说明写入标准错误。`--stdin-json` 使用 JSON 中的参数,不使用其他命令行下载选项。
|
||||
|
||||
## 其他 Python 任务直接调用
|
||||
|
||||
将脚本放入调用方的 Python 模块搜索路径,并在调用方的 uv 环境中安装本脚本 `requirements.txt` 所列依赖后:
|
||||
|
||||
```python
|
||||
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 地址。
|
||||
Reference in new issue
Block a user