微信公众号文章排版美化
把公众号后台(mp.weixin.qq.com)的文章正文提取出来,用微信编辑器兼容的内联样式重新排版,再整体替换回编辑器并保存为草稿。全程通过 agent-browser 浏览器自动化完成。
前置条件
- agent-browser 已安装(
which agent-browser检查;没有则npm install -g agent-browser && agent-browser install) - Python + bs4:
python3 -c "import bs4";没有则python3 -m pip install --user bs4 - 用户在场(需要扫码登录,且必须用绑定公众号管理员权限的微信)
完整流程
第 1 步:登录(每次会话 token 都会失效,几乎每次都要重新扫码)
agent-browser open "https://mp.weixin.qq.com/"
agent-browser snapshot -i | grep -E "扫码|登录" # 找扫码登录入口的元素 ref
agent-browser click e17 # ref 会变,以 snapshot 实际结果为准
提取二维码给用户扫(页面是 canvas/图片,直接截图不够清晰时用 toDataURL):
agent-browser eval "(() => { const qr = document.querySelector('img[src*=\"qrcode\"], img[src*=\"qr\"]'); const c = document.createElement('canvas'); c.width = qr.naturalWidth; c.height = qr.naturalHeight; c.getContext('2d').drawImage(qr, 0, 0); return c.toDataURL('image/png'); })()" > /tmp/qr_b64.txt
# 然后用 python 解码 base64 存为 /tmp/qr.png,用 present_files 展示给用户
⚠️ 最大的坑:账号选错。 用户的微信可能绑定了公众号 + 小程序等多个平台账号,扫码后可能默认登录成「小程序」。登录后必须检查:
agent-browser eval "document.body.innerText.substring(0, 100)"
确认显示的是目标公众号名称(如「你的公众号名称」)。如果登错:访问 https://mp.weixin.qq.com/cgi-bin/logout?token=<旧token> 退出,重新出二维码,并提醒用户扫码后手机上选择公众号账号。
第 2 步:打开文章编辑页并提取正文
登录后从 URL 中取新 token(token=xxxx),拼编辑页 URL:
https://mp.weixin.qq.com/cgi-bin/appmsg?t=media/appmsg_edit&action=edit&reprint_confirm=0&type=77&appmsgid=<文章ID>&token=<新token>&lang=zh_CN
用户给的旧链接里的 token 已失效,必须用当前会话的新 token 替换,appmsgid 沿用旧链接里的。
编辑器定位(关键:正文编辑器是第 2 个 .ProseMirror,索引 1):
agent-browser eval "document.querySelectorAll('.ProseMirror')[1].innerHTML" > /tmp/wx_article_html.txt
# 返回的是 JSON 编码字符串,需 python json.loads 解码后存为 /tmp/wx_article.html
解码后统计结构(h2/h3/img/pre/table 数量),既了解文章规模,也作为后续替换的验证基准。
第 3 步:重排版(调用本技能脚本)
python3 <技能目录>/scripts/restyle.py /tmp/wx_article.html /tmp/wx_styled.html <配色名>
可选配色:cream(米杏暖棕,默认)、ink(极简黑白)、slate(雾蓝/钢蓝,#3F7191)、haze(雾霾蓝)、sage(鼠尾草绿)、taro(香芋紫)、rose(藕粉)、mint(薄荷绿)、klein(克莱因蓝)、oat(燕麦奶茶)。
脚本做的事:清除全部旧 style → 按标签注入新内联样式(H2 卡片、H3 左边线、引用块卡片、斑马纹表格、行内代码胶囊、加粗染色、分割线虚线、图片圆角)→ 保留 class(code-snippet 微信需要)。
第 4 步:本地预览验证
生成 414px 手机宽度预览页,agent-browser 打开并分多处截图(顶部 / H2 / 表格 / 引用块 / 代码块),确认效果后再注入。预览页模板:
<style> body { background: #EDEDED; } .phone { width: 414px; margin: 0 auto; background: #fff; padding: 24px 20px; } </style>
第 5 步:注入回编辑器(两阶段,缺一不可)
坑 1:agent-browser eval 的命令行参数有长度限制——把 styled HTML 切成 3 块,分次累加:
# python 把 html 切块,每块生成一段 JS: window.__hx = (window.__hx || "") + "<chunk>";
agent-browser eval "$(cat /tmp/chunk_0.js)"
agent-browser eval "$(cat /tmp/chunk_1.js)"
agent-browser eval "$(cat /tmp/chunk_2.js)"
坑 2:不能用 DOM Range 全选 + pasteHTML——选区不被 ProseMirror 承认,内容会被追加而不是替换。正确做法是用 agent-browser press "Meta+a" 真实键盘全选:
# 聚焦编辑器并把光标放到开头
agent-browser eval "(() => { const ed = document.querySelectorAll('.ProseMirror')[1]; ed.focus(); const r = document.createRange(); r.setStart(ed, 0); r.collapse(true); const s = window.getSelection(); s.removeAllRanges(); s.addRange(r); return 'ok'; })()"
agent-browser press "Meta+a"
# 验证选区覆盖全文(from=0, to=doc.content.size, empty=false)
agent-browser eval "(() => { const v = window.__mpBodyChecktextView; const sel = v.state.selection; return JSON.stringify({from: sel.from, to: sel.to, size: v.state.doc.content.size, empty: sel.empty}); })()"
坑 3:window.__mpBodyChecktextView 是页面暴露的 ProseMirror EditorView,pasteHTML() 是同步方法(不返回 Promise),调用后直接验证即可:
agent-browser eval "window.__mpBodyChecktextView.pasteHTML(window.__hx)"
# 验证:h2/h3/img/pre/table 数量与提取时统计一致,head/tail 文本正确
如果内容被追加(数量翻倍):直接 agent-browser reload,自动保存会恢复到单份原文,重做第 5 步。
坑 4:代码块(pre.code-snippet)是微信的节点视图,内联样式会被它反复还原,别浪费时间对抗——保留微信原生浅底 + 行号 + 语法高亮即可(发布后正常显示)。想要深色代码块需把代码转成图片(carbon.now.sh)替换。
第 6 步:截图验收 + 保存草稿
多处截图(H2 卡片、表格、引用块、代码块)给用户看效果,确认后保存:
agent-browser eval "(() => { const btn = [...document.querySelectorAll('button')].find(b => b.innerText.trim() === '保存为草稿'); if (btn) { btn.click(); return 'clicked'; } return 'NO'; })()"
保存后确认历史版本列表出现新时间戳。历史版本可回滚,操作相对安全,但替换前仍建议先让用户看过预览。
配色定制
用户给了封面图或指定色值(如 RGB(236,231,221))时:把该色作为 BG_SOFT(大面积底色),主强调色选同色系深色、文字色选更深一档,参照 scripts/restyle.py 里的 PALETTES 字典新增一套即可。
默认配色与提示
- 默认推荐
cream米杏配色(暖色封面、杂志感);若用户提供了封面图或指定色值,以该色为BG_SOFT推导同色系配色即可。 - 注意:若微信绑定了多个平台账号,扫码后请在手机上选择「公众号」而非「小程序」,否则会登错后台。