wechat-article-fetch · 公众号文章抓取
核心事实(已实测,直接执行)
- UA 是唯一准入门槛:用脚本内置浏览器 UA。不带 UA / curl / python-requests / MicroMessenger → 全部 302
- 正文极易拿:服务端渲染,在
<div id="js_content">,裸 GET 即可,无需 JS/Cookie/登录 - 图片无防盗链:真实地址在
data-src - 发现层:原文不被搜索引擎收录;搜狗给加密跳转链,清洁态纯 HTTP 可拆签名直链(窗口≥1h,尽快抓);⚠️ 连发约15~20请求/30分钟触发 IP 级验证码(需人工,浏览器无解)→ 低频率串行,触发即停
UA 示例(自行写脚本时用):Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36
用法(脚本同目录,零依赖,CLI+库双模式,错误结构化 WeChatError)
python wechat_fetch.py "<url>" [--format md|json|text] [--out FILE] # 抓正文
python wechat_discover.py "关键词" [--format table|json] # 搜元数据(跳转链拆法见通道状态)
python batch_fetch.py urls.txt [--min-delay 3] [--max-delay 8] [--daily-limit 500] # 批量:限速/断点续传/验证码停机
通道状态(2026-08 实测,防止误用死路)
| 通道 | 状态 |
|---|---|
| 公开文章页裸抓 | ✅ 长期稳定(本技能核心) |
| 搜狗搜索 | ✅ 仅近期元数据(清洁态);跳转链纯 HTTP 拆签名 URL(窗口≥1h,尽快抓);⚠️ 连发~15-20请求/30分钟触发IP验证码,需人工 |
| 合集(专辑)页 | ⚠️ 匿名可翻,仅合集内文章 |
| 公众号主页历史列表 | ❌ 匿名被拦「请在微信客户端打开链接」;getmsg 仅最近 ~10 篇 |
| 公众号后台跨号搜索 | ❌ 已死(2026-07-30 微信关闭,行业工具全瘫) |
结论:抓取层稳定;发现层上限 = 搜狗近期 + 合集(⚠️ 动态频控,低频率);全量历史无合规通道。
流程
- 已有链接 → GET(浏览器 UA)→ 取
#js_content→ 输出。失败按分诊表,勿盲重试 - 只有关键词 → 搜狗拿元数据;要正文则纯 HTTP 拆跳转链 JS 拼串拿签名 URL回抓取流程(失败/触发反爬再浏览器兜底;或找转载镜像,须告知用户可能被删改)。主页历史、后台搜索不要尝试(已死/被拦)
解析(仅自行写正则时需要,直接用脚本可跳过)
锚点:var msg_title / nickname / ct + #js_content。⚠️ msg_title/nickname 有 .html(false)/htmlDecode() 套壳——正则只匹配等号后第一个引号串,否则全部抽空;图片取 data-src 而非 src。
失败分诊(不要盲目重试)
| 现象 | 原因 | 动作 |
|---|---|---|
| 302 | UA 不合格 | 换浏览器 UA |
| 200 + 参数错误 | 链接无效 | 停,核对链接 |
| 302 → antispider | 搜狗侧拦截(IP级验证码,2026-08-13实测需人工) | 停止,不绕;低频率重试或等待恢复(浏览器同样被拦) |
| 302 → appmsgcaptcha | 链接异常/触发验证码 | 停止,不绕过 |
| 200 + 该页面不存在 | UA 被判为爬虫 | 换浏览器 UA |
| 200 + 请在微信客户端打开 | 需登录的页面 | 该通道不可用,换搜狗/合集 |
| 200 + 已删除/违规 | 文章被处理 | 跳过,记录原因 |
硬约束(违反即停)
- 不碰登录态:个人微信/公众号后台 Cookie、扫码态一律不用(封号 + 违约)
- 不绕过验证码:触发即整体停止(绕过技术措施是中国刑法 285 条红线)
- 不规模化采集:robots 整站 Disallow,定位个人研究小量取用;串行 + 秒级间隔,单日 ≤500 篇
- 不商用不传播:文章受著作权保护,个人学习研究属合理使用(前提:不传播、不商用、保留署名)
- 发现层受动态频控管制(2026-08-13 实测:
1520 请求/30 分钟触发 IP 验证码,小时级未自动解除):低频串行(建议 ≤10 次/30 分钟),触发即整体停止,等待恢复,不得尝试绕过