← 返回 Skill 列表
extension
分类: 内容与媒体API Key 暂未确认

公众号提取 · 一键把整个公众号抓成 Markdown 归档库

"公众号提取":零依赖把整个微信公众号批量抓成干净 Markdown 归档。纯 Python 标准库 3 个脚本,Windows/macOS/Linux/安卓 Termux 通吃;自动剔除广告/评论区/推荐/引导关注,内置断点续跑、反限流、5 项独立验证。Agent 批量 500 篇全程 < 1000 token。不需要任何第三方包、浏览器或 key。

person作者: BOROadsonhubModelScope

公众号文章抓取与归档(wechat-archive)

把微信公众号文章批量抓下来,存成「一篇一个 Markdown 文件」的本地归档。

三条铁律:

  1. 只存文字,不下载图片——图片保留为 ![图片](原始URL) 链接形式。
  2. 抓完先识别正文——广告、文末预告、评论区、关联推荐、引导关注、页面脚部全部剔除。
  3. 命名固定:文章名-YYYY-MM-DD.md,UTF-8 编码;日期取不到时写 unknown-date。

特性:

  • 零第三方依赖,纯 Python 标准库(Python 3.7+ 即可)。
  • 断点续跑:批量每完成一篇写入 _state.json,中断重跑自动跳过已完成。
  • 独立 5 项验证脚本:命名 / 完整性 / 乱码 / 交叉污染 / 计数。
  • 跨平台:Windows、macOS、Linux、Termux(安卓)同一套脚本。

架构:两阶段设计

微信文章列表页需要登录态 + JS 渲染,纯 HTTP 抓不动,所以拆成两阶段:

Phase 1 采集索引(浏览器/人工)→ _index.json 或 urls.txt
Phase 2 逐篇抓取(纯 HTTP 脚本)→ *.md + _manifest.json + _state.json
Phase 3 结果验证(独立脚本)  → _verify_report.json

Agent 只做调度,脚本干重活:批量抓取几百篇时,Agent 只读 _manifest.json 和 _verify_report.json 两个摘要文件,不逐篇读正文。

退出码语义(调用方必须按此判断,不看 stdout):

  • 0 = 全部成功
  • 2 = 部分成功(有失败篇目或警告)→ 读 manifest 看哪篇失败
  • 1 = 完全失败(URL 无效 / 被拦截 / 正文为空 / 参数错误)

反限流: 批量模式每篇间隔 1.5 秒。连续失败 ≥3 篇立即停手,等 10 分钟或换网络出口再跑。

自纠错: 清洗后正文若短于原块 30%,判定清洗过度,回退用原始内容(宁多勿缺,广告残留可后处理,正文丢了补不回来)。


安装

前置条件

  • Python 3.7+,无需安装任何第三方包。
  • 网络可直连 mp.weixin.qq.com(家宽/手机流量直连效果最好;数据中心/代理 IP 被微信拦截的概率更高)。

各平台安装 Python:

| 平台 | 命令 | |------|------| | Windows | winget install Python.Python.3.12(或官网安装包) | | macOS | brew install python | | Linux | 系统自带或 sudo apt install python3 | | Termux | pkg install -y python;首次写入共享存储先 termux-setup-storage;长任务前 termux-wake-lock |

目录布局

把本仓库的 scripts/ 目录放到任意工作位置,例如:

~/wechat-archive/scripts/   ← 三个脚本
~/wechat-archive/out/       ← 抓取输出目录(可任意自定义)

Agent 集成方式(通用):把本文件(SKILL.md)放入 agent 的 skills 目录,或将其「Agent 职责边界」一节浓缩进 agent 的系统提示 / 规则文件(如 AGENTS.md)。触发词建议:抓取公众号、归档文章、公众号提取。


用法

OUT=~/wechat-archive/out   # 输出目录(Windows 用 $env:OUT;或直接写绝对路径)

# 单篇
python scripts/fetch_article.py "https://mp.weixin.qq.com/s/XXXXX" --output $OUT

# 批量 A:JSON 索引(有采集能力时用 _index.json)
python scripts/fetch_article.py --batch $OUT/_index.json --output $OUT

# 批量 B:urls.txt(每行一个 URL,可选 TAB 追加标题/日期)
#   格式:<url>  或  <url>\t标题\tYYYY-MM-DD
python scripts/fetch_article.py --urls urls.txt --output $OUT

# 验证(5 项:命名/完整性/乱码/交叉污染/计数)
python scripts/verify.py --output $OUT

可选环境变量 WX_UA:覆盖默认 User-Agent(一般不用动)。

Phase 1:采集 URL 清单(三选一)

  1. 人工收集(推荐起步):微信里打开公众号 → 历史文章 → 每篇右上角「复制链接」→ 粘进 urls.txt。适合 <100 篇,抓取/验证全自动。
  2. 浏览器控制台:crawl_index.py 生成可执行的 JS 采集脚本 + 指令文件,在能登录列表页的浏览器里跑,输出 JSON 存为 _raw_articles.json,再跑:
    python scripts/crawl_index.py --url <列表页URL> --output <dir>
    
    过滤生成 _index.json(支持 --max / --from / --to / --keyword)。
  3. 只要单篇 URL 收集流程:跳过列表页采集,架构不变。

列表页 URL(profile_ext 带 __biz 参数)通常几分钟过期且需登录态,不要尝试纯 HTTP 硬抓列表页——这正是两阶段设计存在的原因。

Agent 职责边界

  • 收到文章 URL(或 urls.txt)→ 确保输出目录存在 → 跑 fetch_article.py → 跑 verify.py → 只读 _manifest.json 和 _verify_report.json 汇报结果。
  • 用户没指定输出目录 → 先问,不自作主张选目录。
  • 验证 FAIL → 读 report 里 issues 列表定位到具体文件,如实汇报,不隐瞒。
  • 禁止把整篇抓到的正文读进模型上下文(浪费 token 且无必要)。

输出文件说明

| 文件 | 说明 | |------|------| | 文章名-YYYY-MM-DD.md | 正文归档,含 frontmatter:title / account / author / date / source / fetched_at | | _manifest.json | 批量抓取清单(done/failed/skipped + 每篇状态) | | _state.json | 断点续跑状态(done/failed 列表) | | _index.json | Phase 1 索引(account + articles 数组) | | _verify_report.json | 5 项验证报告(overall: PASS/WARN/FAIL) |

错误恢复速查

| 症状 | 根因 | 处置 | |------|------|------| | blocked_by_wechat | 触发验证页/限流 | 停 10 分钟;换网络出口(Wi-Fi↔流量);降低批量节奏 | | content_empty / markdown_too_short | 链接失效或页面改版 | 记录到 manifest,人工开链接确认 | | fetch_failed | 网络/域名解析失败 | 检查网络权限;换流量重试 | | 验证报告 pollution WARN | A 文末出现 B 标题 | 大概率文末关联推荐没滤净,人工核对涉事文件 | | 中断后续跑 | _state.json 已记录进度 | 直接重跑同一命令,自动跳过 done |


验收自测清单

  1. python -m py_compile scripts/*.py(Termux 用 find scripts -name '*.py' -exec python -m py_compile {} \;)全部通过。
  2. 用任意一篇真实公众号文章跑单篇:exit=0,目录里出现 文章名-YYYY-MM-DD.md,frontmatter 含 title/account/date/source。
  3. 故意混一条坏链接跑 --urls:exit=2,_manifest.json 中好链接 ok、坏链接 failed。
  4. python scripts/verify.py --output $OUT:exit=0 或 2(pollution 仅 WARN 可接受),_verify_report.json 生成。
  5. 重跑同一批量命令:全部 skipped(断点续跑生效)。

多平台适配说明

| 平台 | 差异点 | |------|--------| | Windows | 直接 python scripts/xxx.py;路径用反斜杠或正斜杠均可 | | macOS / Linux | python3 scripts/xxx.py | | Termux (安卓) | pkg install python;共享存储需 termux-setup-storage;长任务 termux-wake-lock;终端默认 UTF-8 | | 无 Agent 环境 | 脚本独立可跑,不依赖任何 agent 框架;Agent 部分仅影响 Phase 1 的自动化程度 |

跨平台一致性:脚本仅用 Python 标准库(urllib、re、json、html、pathlib 风格 os.path),状态与控制台输出一律 ASCII([OK] / PASS / FAIL),中文内容只出现在文件内部(UTF-8),避免任何终端编码问题。

License

Apache-2.0。