手动排版一年后,我用三个开源包把公众号发布压成了一行命令

作者:程序员白大力 · 2026-09-29 01:04

封面

很多人以为,"自动发公众号"就是写个脚本模拟登录后台、点按钮、传封面。真上手才发现,这条路又脆又违规:微信反爬一改就废,账号还可能被封。但其实微信官方早就开放了草稿箱接口,正经做法根本不需要碰浏览器。

可问题来了——为什么我把文章推到草稿箱之后,群发按钮却怎么也点不动?为什么脚本报错时我不敢重跑?这篇文章把这件事的技术真相一次讲透。


一、事件复盘

事情的起因很朴素。我自己维护着一个技术公众号,每周要写一篇文章。流程是这样的:先用 AI 把稿子写成 Markdown,然后复制到公众号后台,手动调字号、行距、段间距,再一张张把本地图片上传,等微信把图片转存到它自己的 CDN,最后上传封面、填摘要、点保存。

一篇文章折腾下来,排版加上传至少二十分钟。图片多的时候,微信后台还会卡。

于是我把这条流水线拆成了三个独立的开源包:第一个负责按提示词生成文章,第二个负责把 Markdown 渲染成公众号能直接用的内联样式 HTML,第三个负责把 HTML 和封面推到草稿箱。最外层只留一条命令:

wechat-auto-publish draft 文章.md 封面.png "标题" "摘要"

跑一次,文章就出现在公众号后台的草稿箱里。剩下的"发表"动作,我自己在手机上点一下就行。

这件事本身不复杂,但它踩中了三个很多开发者都搞不清楚的坑:官方接口到底怎么用、个人号为什么不能自动群发、以及脚本为什么不能随便重试。


二、技术核心拆解

先搞懂 access_token 这把钥匙

微信公众号所有接口都挂在 https://api.weixin.qq.com/cgi-bin 下面。调用任何接口之前,你得先用 appid 和 secret 换一个 access_token。

这个 token 有效期大约两个小时,过期要重新换。它不是密码,而是一张临时通行证——谁拿着它,就能以这个公众号的身份调接口。所以 secret 绝对不能提交到 Git 仓库,泄露了别人就能拿你的号发文章。

三个包各管一段

最外层的 wechat-auto-publish 自己不生成内容,它只做编排:

  • 生成层:按领域提示词产出渠道无关的 Markdown 文章和封面图;
  • 排版层:把 Markdown 渲染成公众号 HTML。这里有个关键细节——公众号不支持外链 CSS,所有样式必须内联到每个标签上,字号、行距、段间距都得写死在 style 属性里;
  • 发布层:拿 token,上传封面,建草稿。

为什么文中图片必须先转存

公众号文章里的图片不能直接引用你自己服务器的 URL。微信会把它替换成自己 CDN 的地址。所以发布层要先调 media/uploadimg 接口,把每张本地图片上传一遍,拿回微信 CDN 的 URL,再塞进 HTML 里。封面图走的是另一个接口 material/add_material,因为封面是永久素材,需要一个 media_id。

这一步做完,文章在微信里打开才不会出现"图片加载失败"。

草稿箱和群发是两回事

建草稿用的是 draft/add 接口,只要你有 token 就能调。但真正点"群发"用的是 freepublish/submit 接口——这个接口对账号类型有要求。个人未认证的订阅号,根本没有这个权限。

所以这条流水线的定位很明确:只存草稿,不群发。文章推到草稿箱之后,人去后台点一下"发表",这一步故意留给人做。

IP 白名单是第一道门

微信要求调用接口的服务器 IP 必须在公众号后台配置的白名单里。如果你在自己笔记本上跑脚本,出口 IP 一变就会报错,错误码是 40164。这个错误不是代码写错了,是网络环境不对。


三、三个常见技术误区

误区一:自动发公众号就是模拟登录浏览器

很多人第一反应是用 Selenium 或 Playwright 打开公众号后台,模拟人点按钮。这条路有三个问题:微信后台有反爬机制,DOM 结构一改脚本就废;登录态靠 cookie,过期要重新扫码;最关键的是,这种操作本质上绕过了官方接口,账号一旦被识别就有封禁风险。

官方接口才是正路。appid + secret + access_token,稳定、合规、不会因为前端改版就挂。

误区二:建了草稿就能一键群发

draft/add 和 freepublish/submit 是两个完全不同的接口。前者谁都能调,后者需要账号具备发布权限。个人未认证订阅号没有这个权限,所以脚本只能把文章送进草稿箱,最后一步必须人来点。别指望脚本能替你完成"一键群发",这不是技术做不到,是微信的权限模型就这么设计的。

误区三:脚本报错就赶紧重跑

微信接口有个坑:有时候请求其实已经成功了——草稿建好了、图片传上去了——但网络超时或者返回包丢了,脚本看起来就像失败了。这时候如果你重跑一次,就会在草稿箱里建出两篇一模一样的文章。

所以这条流水线有一条铁律:发布命令从头到尾只跑一次。不管成功、报错还是超时,都不重跑。真出问题了,先去草稿箱看一眼,而不是盲目再跑一遍。


四、实操指引

如果你也想把自己的公众号发布流程自动化,按这五步走:

第一步,拿凭据。 登录公众号后台,在"设置与开发"里找到 appid 和 appsecret。secret 只显示一次,记得立刻存好。

第二步,配 IP 白名单。 在同一个后台把你跑脚本的服务器出口 IP 加进去。如果你在本地跑,先访问一下 ifconfig.me 看自己当前的公网 IP,加进去。报 40164 就是这一步没做。

第三步,装包。 克隆仓库后 pip install -e .,它会自动把排版和发布两个上游包装好。

第四步,写配置。 复制 config.example.json 为 config.json,把 appid、secret、作者名填进去。这个文件已经在 .gitignore 里,不会被提交。

第五步,跑一条命令。 在仓库根目录执行:

wechat-auto-publish draft 文章.md 封面.png "标题" "120字内摘要"

看到 DRAFT_MEDIA_ID 开头的输出就说明成功了。然后打开公众号后台草稿箱,检查排版和图片,确认无误后手动点"发表"。


五、结尾

自动化这件事,真正省时间的不是"让机器替你点按钮",而是把一件重复的事拆成稳定的接口调用。排版交给渲染层,图片转存交给发布层,人只保留最后那个"确认发表"的动作。

技术科普的价值就在这里:很多看起来很玄的"自动化",拆开之后就是三个 HTTP 接口加一层配置。搞懂了 access_token、草稿箱和群发接口的区别,你就不会再去写那些脆弱的模拟登录脚本。

如果你也在维护自己的公众号,不妨试试把这条流水线搭起来。觉得有用,欢迎转发给同样在手动排版的朋友——少熬一次夜,就是这篇文章最大的价值。


本文由 AI 辅助生成并经人工审核发布,内容仅供参考。