资讯动态

OpenClaw+Skill驱动的公众号自动化发布实战

发布时间:2026/10/14 23:40:57 来源:尧图企业网站定制
我今年连续更新了四十多篇公众号文章每天最烦的不是写稿反而是发布那一步复制标题、贴正文、传封面、填摘要、预览、定时群发动作不复杂但磨人。后来我把整套流程接到 OpenClaw 上配了几个自定义 Skill让代理自己去公众号后台上操作实测一篇图文从内容就绪到进入草稿箱只需要两三分钟。这篇文章就把这套方案的架构、Skill 拆分逻辑、完整实现步骤和踩过的坑全部摊开讲一遍适合日更或周更的内容创作者、给团队搭自动化发布管线的同学以及对自主代理有兴趣的技术朋友。1. 为什么要把公众号发布流程自动化1.1 手动发布一篇图文到底要花多久很多人觉得发布公众号不就点几下鼠标能有多慢我实测过一个比较常见的完整流程从本地 Markdown 文件开始先打开公众号后台新建图文然后复制标题、把正文粘贴进编辑器重新调一遍格式接着上传封面图、勾选封面展示、填自定义摘要最后预览一次确认排版没乱再设置定时群发。整个过程最快也要 15 分钟如果文章里图片多、代码块多、需要反复调整排版20 分钟都打不住。这里面真正吃时间的不是点击本身而是两个隐性成本一是重复但凡一周更新三篇以上同一套机械动作就得反复来纯体力活二是低水平错误标题漏填、摘要超字数、封面尺寸不对、定时时间设错这些错我全犯过每次都得重新走流程。对一个人运营账号或者小团队来说这部分时间占了内容生产总耗时的相当比例却完全没有创造性价值是最值得自动化掉的环节。我测算过自己一个月的数据40 篇文章每篇从准备到发布平均 17 分钟一个月花在发布操作上的时间超过 11 个小时。自动化之后同样 40 篇每篇人工介入时间压缩到 2 分钟以内主要就是看一遍草稿、点确认。省出来的时间当然不会让我多写出几篇爆款但至少可以把原来对着编辑器发呆的精力挪到选题、标题和正文打磨上。1.2 OpenClaw 加 Skill这不是传统脚本刚开始我也想过直接用一段 Python 脚本搭配浏览器自动化库去点后台能跑通但用起来非常别扭。传统脚本是“死”的所有步骤都写死在代码里先打开哪儿、点哪个按钮、等多少秒、输入什么内容。一旦公众号后台改版、某个按钮的路径变了、弹窗出现时机不一样脚本就断给你看你只能打开日志一行一行排查维护成本居高不下。OpenClaw 不太一样的地方在于它本身是个自主代理框架核心不是替你执行固定步骤而是能理解任务、拆解步骤、动态决策。我给它下指令“把 articles/ 目录下今天那篇新文章按惯例处理成草稿”它会自己去读目录、找文件、提取正文、判断用哪个 Skill、按顺序调起来中途遇到异常还会自己决定重试还是停下等指令。这种感觉就像真正多了个会干活的同事而不是一段只会念台词的录音。Skill 则是给代理配的“技能包”每个技能包解决一类具体问题。比如我分了四个文章加载、内容格式化、公众号发布、发布后核验。每个 Skill 自带描述文件、参数定义、执行脚本和配置代理按需加载。好处是模块之间独立哪个环节出问题就只改哪个包单个 Skill 也可以复用到别的任务上比如格式化那个包我会拿来生成邮件正文。1.3 哪些场景最适合这套方案这套方案最适合三类人。第一类是日更或周更的公众号运营者更新频率越高省下的时间越可观。第二类是给公司或团队信息中心搭发布流水线的开发者把发布动作封装成 Skill 后其他同事只需要把 Markdown 文件丢进指定目录剩下的事都自动化不清楚后台操作细节的人也能上线内容。第三类是本身在用 OpenClaw 或其他自主代理框架、想把真实业务流程接进来的技术爱好者这套发布流程是个很好的落地练手项目。反过来也有明确不推荐的情况。如果你基本不发内容一个月憋一篇那没必要折腾手动发一下反而是最稳的。如果你打算用自动化做批量注册、批量养号、高频刷量这类事情我建议趁早放弃这个念头——公众号平台对异常操作看得很紧自动化高频操作极易触发风控轻则限制发布重则封号这不是技术能绕过去的问题。自动化是帮你把固定工作做规整不是帮你钻空子。2. 架构设计与核心思路拆解2.1 把发布链路拆成四段我搭建这套系统时第一步不是写代码而是把公众号文章发布的完整链路拆开分成四个边界清晰的阶段。第一段是内容准备负责从本地目录读取待发布的 Markdown 文件解析文件头里的标题、摘要、封面路径、分类这些元信息同时把正文内容提取出来。第二段是内容格式化把 Markdown 正文转成适合公众号后台粘贴的 HTML处理标题层级、代码块、引用、图片引用这些元素顺便做标题长度截断、摘要字数控制。第三段是公众号操作这是最核心的一段负责打开后台、登录、进入图文编辑页、填充内容、上传封面、保存草稿或者直接群发。第四段是发布后核验发布完自动截个图、检查页面状态、把结果写日志方便事后追溯。这四个阶段拆出来之后每个阶段对应一个独立 Skill互不依赖。内容准备阶段从什么来源拉取文章是本地目录、API 还是 RSS都不影响后面三段。格式化规则改了也只需要动格式化那个 Skill不会碰发布逻辑。发布失败也只需要看发布 Skill 的日志不用从头排查。模块化带来的维护便利在后续页面改版时体会特别深。2.2 Skill 拆分的两个原则Skill 怎么拆直接决定这套系统的可维护性。我自己定了两条原则第一条是高内聚低耦合一个 Skill 只做一件事并且把这件事做完整。比如发布 Skill 内部把“登录”“进编辑页”“填内容”“保存草稿”串在一起而不是拆成四个微 Skill因为这几个步骤共享同一个浏览器上下文拆开反而要到处传回话柄维护复杂。第二条是故障隔离。每个 Skill 都要能独立失败、独立重试、独立标记状态。比如格式化 Skill 遇到无法处理的特殊字符不能让它一路错下去把发布流程也带崩而是应该抛出明确错误主控代理记录下来跳过这篇文章继续下一轮。同样发布 Skill 遇到后台元素找不到不能静默失败要截一张图、写一段日志再决定是否换策略重试。按这两条原则拆出来的四个 Skill我再补充一个比较重要的设计发布 Skill 里保存草稿和直接群发用的是同一个流程只是最后一步动作不同。草稿模式是默认的代理跑完保存草稿就结束等人工确认后再通过后台手动群发只有人工显式指定 actionpublish 且连续多轮验证稳定后才会走上自动群发那条路。这个设计演练下来很有必要相当于给自动化流程加了道保险。2.3 为什么走浏览器自动化而不是官方接口聊到自动发布公众号很多人的第一反应是调官方接口。但现实是公众号的真正群发接口能力基本面向完成认证的服务号开放个人订阅号既没有认证资质也申请不到相关权限。即便你有接口权限设置 IP 白名单、获取 access_token、处理素材库上传这些准备工作也是一套工期对只想省掉重复点击动作的运营者来说投入产出比并不划算。浏览器自动化的思路更直接人是怎么操作的代理就怎么操作。打开公众号后台、登录、点进图文编辑页、往里填内容——人能点的自动化都能点而且不需要额外申请任何接口权限。这套方案的制约也很明显依赖后台页面结构和元素路径哪天后台改版了需要花点时间更新选择器但公众号后台属于企业级产品改版频率并不高维护成本完全可以接受。我更愿意把官方接口和浏览器自动化看成互补关系而不是二选一。如果哪天公众号能开通发布接口我大概率会把接口封装成一个新的发布 Skill替换掉浏览器操作那个包在接口资质不具备的阶段浏览器自动化是真正的万能兜底方案。理解了这一点就明白为什么整套架构要把“公众号操作”封装成 Skill 而不是写死在主流程里——替换实现时其他部分完全不用动。3. 实操准备与关键细节3.1 环境与目录结构实操层面我建议从本地环境入手先把目录结构和依赖准备好。我用 Python 3.10 加浏览器自动化库 Playwright系统上装了 Chromium 内核。不需要服务器普通的开发机或办公电脑就能跑因为发布动作本质上和人工开浏览器一样需要桌面环境或者虚拟屏幕。目录结构参考如下wechat-auto-pub/ ├── main.py # 主控入口 ├── skills/ │ ├── article_loader/ # 内容读取 Skill │ │ ├── SKILL.md │ │ └── run.py │ ├── formatter/ # 内容格式化 Skill │ │ ├── SKILL.md │ │ └── run.py │ ├── wechat_publisher/ # 公众号发布 Skill │ │ ├── SKILL.md │ │ ├── config.yaml │ │ └── run.py │ └── verifier/ # 发布核验 Skill │ ├── SKILL.md │ └── run.py ├── articles/ # 待发布文章目录 ├── assets/covers/ # 封面图目录 ├── state/ # 登录状态存储 ├── logs/ # 日志目录 └── requirements.txt我最开始没分这么细所有代码堆在一个文件里结果改一次格式化逻辑要连带测试整条链路。后来按 Skill 重构后单测和联调都清晰多了。requirements.txt 里主要就是 playwright、pyyaml、markdown 几个库很轻量。3.2 Skill 的格式规范一个规范的 Skill 必须让代理清楚知道“这个技能是干什么的、需要传什么参数、怎么调用”。我统一使用 SKILL.md 文件描述技能元信息YAML 头部定义名称、用途、参数和返回值。以公众号发布 Skill 为例--- name: wechat_publisher description: 将本地 Markdown 文章自动填充到公众号后台保存草稿或直接群发 arguments: md_path: type: string required: true description: 待发布文章的 Markdown 路径 action: type: string required: false default: draft enum: [draft, publish] description: 保存为草稿或直接群发 returns: status: type: string description: success 或 failed draft_url: type: string required: false description: 草稿需要人工确认时可返回草稿链接 ---配套的 run.py 负责实际执行用 argparse 接收参数最后把结果以 JSON 格式输出。代理读取 SKILL.md 理解用途调用 run.py 并解析 stdout 的结果来决定下一步动作。这个协议的约定越明确代理的出错概率越低。3.3 登录态与账号安全公众号后台登录绕不开扫码验证。我的做法是首次运行时以有头浏览器模式打开后台人工扫码登录一次然后通过 Playwright 的 storage_state 把登录态保存到 state/wechat_state.json 文件。之后的自动化运行直接加载这个状态文件正常三到五天内不需要重新扫码。这里必须强调几个安全细节。第一这个状态文件等价于登录凭证泄露出去等于把公众号后台交给陌生人我把它放在单独的 state 目录并加了只读权限。第二不要在代码里硬编码任何账号密码更不要明文保存 Cookie如果用服务器跑建议给文件做加密或放在受保护的密钥管理环境里。第三每次自动化发布完我把新的 storage_state 回写覆盖旧文件确保登录态始终是最新的。还有一个经验有头模式跑半小时以上偶尔会触发后台的异常登录提醒需要重新扫码这个属于正常现象。无头模式下遇到扫码弹窗我会让代理停下来、截图、发通知等人来处理而不是让代理自己去尝试破解验证码。自动化要解决的是重复劳动不是和平台安全机制对抗。4. 核心实现内容准备、自动填充与定时发布4.1 主控流程怎么串起来主控 main.py 的逻辑比较简单核心是让代理按顺序调用四个 Skill。我先把文章加载、格式化、发布、核验四个 Skill 串成一段可复用的 Python 函数import json import subprocess import sys from pathlib import Path SKILLS_BASE Path(skills) def run_skill(skill_dir: str, **kwargs): result subprocess.run( [sys.executable, str(SKILLS_BASE / skill_dir / run.py)] [f--{k}, json.dumps(v) if isinstance(v, (dict, list)) else str(v) for k, v in kwargs.items()], capture_outputTrue, textTrue, encodingutf-8, ) return json.loads(result.stdout.strip().splitlines()[-1]) def publish_article(md_file: str, action: str draft): article run_skill(article_loader, md_pathmd_file) formatted run_skill(formatter, articlearticle) result run_skill( wechat_publisher, md_pathmd_file, titleformatted[title], contentformatted[html_content], coverarticle[cover], digestformatted[digest], actionaction, ) if result[status] success and action publish: verify run_skill(verifier, resultresult) result[verify] verify return result if __name__ __main__: target sys.argv[1] action sys.argv[2] if len(sys.argv) 2 else draft report publish_article(target, action) print(json.dumps(report, ensure_asciiFalse, indent2))当然代理环境下并不是每次都要走这层 Python 封装OpenClaw 自己也能直接调度 Skill。我保留这段封装的主要原因是方便本地调试和写定时任务两套入口并存出问题时不至于连手动跑一下的机会都没有。4.2 编辑器填充里的三个坑第一个坑是正文区域在 iframe 里。公众号的图文编辑器正文区不是普通输入框而是嵌套在 iframe 里面的富文本编辑区直接 page.fill 没反应。我在代码里用 frame_locator 定位 iframe再在 frame 内部定位可编辑区这样才能稳定填入内容。不同内核版本的编辑器结构略有差异需要按下 F12 自己确认选择器。第二个坑是富文本样式剥离。直接往编辑器粘贴带大量内联 style 的内容后台会自动做一轮样式清理很多效果会丢失。我把 Markdown 转 HTML 之后只保留 h2、h3、p、pre、blockquote、img 这类基础标签样式尽量不写让公众号后台自己的排版体系接管。做这套格式化时我的原则是“结构干净优先视觉细节靠后台默认样式”。第三个坑是标题和摘要的硬性限制。标题最长 64 字超出部分在列表页会被截断所以在格式化阶段统一做截断避免代理把超长标题填进去。自定义摘要限制 120 字超过也会提示我在 formatter 里就把摘要按字符数切好宁可短一点也别超。这几个硬限制是公众号后台一直没变的规则写死在格式化 Skill 中最省心。4.3 封面图和素材库处理封面图是发布流程里最容易翻车的一环。公众号后台对封面的比例和文件大小都有要求建议长图用 900 乘 383 的尺寸小图用 400 乘 400 比例单张图片大小不要超过 10 兆。我维护了一个 assets/covers 目录每篇文章命名成日期加标题关键词的形式方便 article_loader 解析文件头时直接引用。发布 Skill 处理封面有两种路径一是本地文件直接上传这适合每篇新配一张封面的情况二是从素材库选适合团队统一视觉物料、反复用同一套图的情况。我目前用的是第一种代码里通过文件上传控件把封面传上去再在编辑器里勾选“封面和全文”展示方式。第二种路径需要额外维护素材库的命名规则不建议刚开始就做先把基础流程跑通再说。4.4 定时任务与发布节奏控制定时发布我这边分两个层级。第一层是系统层定时触发 main.pyWindows 下用计划任务Linux 下用 cron每天固定时间执行一次把当天文章处理成草稿。第二层是公众号后台自身的定时群发功能草稿准备好之后人工看好时间再设置定时发布。这么设计是因为后台的定时群发比脚本等待更稳定同时也强制保留了一个人工确认节点。实际节奏上我建议刚开始自动化时前两周只跑草稿模式每天生成草稿后人工进后台看一眼再发送。等确认格式化规则稳定、封面路径没问题、登录态不频繁失效再打开定时任务跑自动群发。我见过有人第一天就把全自动开满结果封面选错文件名、正文全是乱码连发三篇才发现账号阅读数据和口碑都受影响了。自动化发布是一场长跑先稳后快才是正路。5. 三大高频故障排查实录5.1 登录态失效与滑块验证用了一个月之后我碰到最频繁的故障就是登录态失效。后台偶尔会弹出“环境异常”或者直接跳转登录页加载 storage_state 也救不回来因为失效的不是本地 Cookie而是后台判定需要重新验证身份。遇上这种情况无头模式跑多少遍都是白搭排查方式很简单看截图页面停在登录界面那基本就是需要人工扫码了。我的处理流程分三步代理检测到登录页元素出现就停止后续动作截一张全屏图存档然后给日志写一条明确错误。随后我把对应通知发到群里人来了以后用有头模式打开后台、扫码、重新保存状态文件再重新跑一次草稿流程。整套流程从发现到恢复熟练之后五分钟内能搞定损失最多就是当天的草稿晚一点生成。有段时间登录态频繁失效几乎每天都要手扫一次后来发现是我把登录状态保存在服务器上而服务器出口 IP 一直变触发了后台的安全策略。换成固定出口后一周多都没再需要扫码。排查这类问题的思路是先看是不是你自己的环境特征不稳定再考虑账号本身有没有异常不要一上来就怪自动化。5.2 群发失败后的草稿回退自动群发出错是比登录失效更棘手的问题因为群发是有真实影响的动作。我遇到过标题超过限制导致保存失败、图片上传中途断掉导致正文里缺图、甚至后台升级页面元素路径失效。这些情况如果代理傻傻地重试三次还是失败极有可能造成半成品内容直接发出去。所以发布 Skill 内置了一个兜底逻辑所有动作默认优先保存草稿只有在确认草稿正常且 action 指定 publish 时才执行群发。群发那一步再单独包一层 try 块任何异常都先自动保存草稿再抛出错误绝不让“群发”这一步在半成功状态下继续。这套逻辑跑下来最差的结果是草稿箱里多了一篇需要人工检查的文章而不是读者收到一篇排版错乱的内容。关于重试我也做了次数限制。同一篇内容最多重试两次两次失败就直接切换人工确认流程。日志里会记录每次重试的原因、耗时和截图路径方便回看。自动流程容忍偶发故障但要坚决防止同一个已知故障反复消耗资源这是自动化工程里很重要的一条经验。5.3 内容异常排版丢失和怪字符第三类高频问题出现在内容格式化这层。Markdown 转 HTML 再填进编辑器的过程中我踩到过几个具体坑正文里出现的全角空格在公众号编辑器里会被渲染成一堆占位符某些版本的编辑器遇到连续换行会把行间距压缩掉代码块里的尖括号偶尔被解析成 HTML 标签直接吞掉。解决方案比较粗暴但有效格式化 Skill 在输出前统一做一遍字符清洗。全角空格转成普通空格或删除连续换行收敛成段落标签代码块内容统一转义后再包进 pre 标签。另外封面图 alt 文本和图片文件名里也不要放特殊符号公众号后台对中文文件名兼容性尚可但遇到“”“?”这类字符偶尔会抽风我尽量用纯字母数字加下划线命名。整理下来我把高频问题整理成了一个速查表放在项目 README 里每次出问题先查表现象常见原因处理方式打开页面停在登录页登录态失效或环境异常有头模式人工扫码更新 state 文件标题或摘要保存报错超过后台长度限制在 formatter 里提前截断正文内容为空iframe 定位失效重新获取编辑器元素路径图片上传失败文件过大或命名特殊字符压缩图片、统一规范命名定时任务没触发cron 环境变量缺失脚本内指定 Python 绝对路径发布后缺图正文中的图片是外部链接先将图片下载到本地再上传6. 自动化的底线合规、账号防封与长期维护6.1 平台规则红线一票否决自动化发布节约的是时间不是内容审核的流程。公众号平台对内容有明确底线诱导分享、标题党、虚假宣传、洗稿抄袭这些行为不会因为发布方式变自动就网开一面反而自动化高频操作更容易引起系统注意。我给自己定的规矩是每篇发布前必须有人工审核环节哪怕只是扫一眼草稿也不能让机器当唯一的内容把关人。频率也要控制。我见过有人把自动发布频率设到一天三更实际上内容储备和选题根本跟不上阅读数据一塌糊涂不说后台还会因为频繁群发触发平台提醒。公众号是内容产品读者之所以愿意看是因为内容本身有价值自动化的作用是让你把省下的精力投向内容质量而不是让低质内容刷得更快。6.2 账号安全与敏感信息管理自动化脚本里必然涉及登录态和可能的后台配置信息这些信息要按敏感资料对待。我的具体要求是登录状态文件不提交到代码仓库不通过聊天工具明文传输服务器上设置独立目录并做最小权限所有日志禁止打印完整的 Cookie 内容。如果多人协作建议每个人维护自己的本地登录态而不是共享同一个 state 文件。另外一个容易被忽略的细节是浏览器内核的缓存文件。自动化跑多了本地会积累不少临时文件里面可能包含页面渲染数据。定期清理这套临时目录尤其是在调试完有头模式之后看起来是小习惯但安全无小事。账号出现问题再想起来处理代价往往比预想的大得多。6.3 长期维护页面改版与 Skill 版本管理任何自动化方案都逃不开“依赖的页面改版”这一天。公众号后台虽然不是隔三差五大改但按钮位置、编辑器结构变化是常态。我养成了一个习惯每个月抽半天手动打开后台对照一遍自动化检查清单确认主要元素路径没变。一旦发现某个选择器失效立刻更新到对应 Skill 里并写一条变更日志。Skill 的版本管理我建议纳入代码仓库每个 Skill 单独记录改动历史。改格式化规则、调整封面路径、更新选择器这些都要有据可查否则两三个月后再看代码根本说不清当时为什么那么改。我自己吃过这个亏一度为了赶发布日期临时改过摘要截断长度事后忘记记录后来有人问我为什么有的摘要长有的短我完全答不上来。从那以后Skill 更新必须写 commit message这是底线。最后再分享一点运营层面的体会自动化发布带来最大的收益不是把发布时间从 20 分钟压到 2 分钟而是你不再被发布动作拖着走。以前每天发完稿精力已经消耗了一半根本没心思复盘阅读数据现在草稿自动生成我只需要定时看一眼后台剩余精力能放在选题和话题打磨上。按我个人经验第一次搭这套系统最关键的提醒就是别急着全自动先把草稿模式跑稳再加群发再上定时任务一步一步来后面会省掉很多不必要的事故处理时间。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑