微信公众号
一篇文章直接取文章页:正文、号名、署名、发布时间、原图都在页面里,不花钱。一个号的最新几篇,先用 TikHub 翻出文章列表,再一篇篇取文章页。阅读量只有 TikHub 给。
脚本
python3 scripts/wechat_mp.py <文章链接或整段分享文案>... --out <目录>
python3 scripts/wechat_mp.py --account <号名、gh_ 号或这个号的一篇文章链接> --limit 5 --out <目录>
wechat_mp.py就是下面这套。文章链接认mp.weixin.qq.com/s/<短码>和带__biz的长链;长链要整条传,截掉chksm这些参数,页面只回「未知错误」- 一篇文章免费:页面没有正文时退回 TikHub,0.01 美元,
warnings里写着页面标题 - 文件夹:
meta.json的kind是article,视频、音频、贴图类的是video、audio、image,正文照样取;author里name是号名,id是gh_号,writer是文章署名。另有article.md、images/NN.<ext>、cover.jpg,没有视频;raw/page.json是从页面取到的字段和正文的原始 HTML article.md:标题、来源一行,下面是正文。图片换成本地路径;文中的视频、视频号卡片写成[视频]、[视频号视频];代码块保留换行,不带语言标记 —— 页面上的标记是编辑器猜的,shell 命令标成apache--account:取这个号最新的 N 篇,--limit默认 20。列表约 25 篇一页,每页 0.01 美元;重跑会重新翻列表,取过的文章跳过- 按名字找号先搜一次,0.01 美元:只认名字一字不差的,记进
wechat_mp_accounts/accounts.json,下次不再搜;对不上时error里列出搜到的前 5 个号和gh_号,挑一个重传 --limit 0翻完整个号:大号上百页,要加--yes--stats:每篇另调一次 TikHub,0.01 美元,stats里是read、like、wow(在看)、share、collect、comment--no-images不下图,article.md里留原链接- 一个号的文章隔一秒取一篇;文件夹格式和续跑见解析分享链接,
list.json见作者主页
底层:文章页
curl -sS -m 30 -A "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126 Safari/537.36" "<文章链接>"
- 不经中转,不用 key,带浏览器的 User-Agent。页面 3 MB 左右,大半是脚本
- 字段在页面变量里:
og:title是标题,og:description是摘要;var nickname = htmlDecode("…")是号名,var user_name是gh_号,var author是署名;var create_time是秒级时间戳;var msg_cdn_url是封面;ip_wording里的province_name是 IP 属地;var item_show_type是 0 的是文章 biz、mid、idx拼起来是文章的唯一 ID:页面写成var biz = "" || "MzA3…==";,取第一个非空值- 正文在
id="js_content"的 div 里,图片地址在data-src,不在src - 原图把末段
/640换成/0:mmbiz.qpic.cn的/640最大给 1080 宽,/0是原图,实测一张从 1080 宽变成 1610 宽。下图不用带 Referer
底层:TikHub
照 TikHub 官方文档的路径调,只把 https://api.tikhub.io 换成 https://tikhub-proxy.liuhetian.work。公众号这组接口都是 POST JSON,不像小红书、抖音那样 GET:
curl -sS -m 60 https://tikhub-proxy.liuhetian.work/api/v1/wechat_mp/v2/fetch_account_articles \
-H "Authorization: Bearer $MY_API_KEY" -H "Content-Type: application/json" \
-d '{"username": "<gh_ 号>", "offset": "", "raw": false}'
| 接口 | 传 | 看 |
|---|---|---|
wechat_search/v2/fetch_search | keyword,business_type 传 account | 找号:items[].title 是号名,带 <em> 高亮;items[].jumpInfo.userName 是 gh_ 号,@finder 结尾的是视频号 |
wechat_search/v2/fetch_search | keyword,business_type 传 article | 搜文章:items[].doc_url 是链接,source.title 是号名,source.tag 里有「阅读 3万+」这类标签;sort、publish_time 可以按最新、最近一周筛 |
wechat_mp/v2/fetch_account_articles | username、offset | 文章列表 articles[]:title、digest、url、cover、create_time、idx、item_show_type,没有阅读量 |
wechat_mp/v2/fetch_article_stats | url | read_num、like_count、old_like_count(在看)、share_count、collect_count、comment_count |
wechat_mp/v2/fetch_article_detail_h5 | url、raw: true | content.content_noencode 是正文 HTML,content 下其余字段和文章页的变量同名 |
- 每次 0.01 美元,返回什么都一样收
- 列表翻页:第一页
offset传空串,以后传上一页的next_offset,直到is_end为 1。page_size微信不认,一页几篇由号决定,实测 25、28 篇 - 超时设 30 秒以上:文档说微信那边慢,超时短了会扣了钱收不到结果;实测 3~9 秒
- 64 位 ID 当字符串传:
comment_id这类过 JavaScript 的Number会丢精度
视频号没接:视频文件是加密的,见维护记录。