微信公众号发表数据导出
用 BrowserSkill(bsk)登录 mp.weixin.qq.com,从「内容管理 → 发表记录」抓取全部已发表文章的实时数据,生成 xlsx。
前置
- bsk CLI:
~/.local/bin/bsk.exe(v0.2.1);BrowserSkill 扩展已装在用户 Chrome。 - 平台沙箱会在命令结束后杀掉子进程,daemon 必须用 run_in_background 保活:
bash export BSK_HOME="$HOME/.bsk"; export BSK_AUTO_START=0 bsk daemon start --foreground # run_in_background=true
之后每个命令都带BSK_HOME="$HOME/.bsk"和BSK_AUTO_START=0,先bsk status --json确认 browsers 非空(空则让用户点扩展图标唤醒,重试至多 5 次)。 - daemon 可能因自动更新自愈重启(0.2.1→0.3.0),重启后 session 会丢,需重新
session start并改用新 session id。 - 截图/写文件到含中文的路径可行,但输出文件名建议用英文排查问题更快。
流程
- 登录:
session start --json→navigate https://mp.weixin.qq.com→ observe。若为扫码登录页:screenshot --out login.png截图 → present_files 给用户扫码 → 等用户回复"已登录"。 - 导航:登录后进「内容管理 → 发表记录」(URL 形如
/cgi-bin/appmsgpublish?sub=list&begin=0&count=10&token=<token>&lang=zh_CN,token 可从页面任一菜单链接里取)。页面顶部有「全部 N」记录数和分页(每页 10 条)。 - 确认指标含义(首次务必截图核对):每条记录 6 个数字对应 tooltip 标签:阅读人数、点赞人数、分享人数(=用户说的"转发数")、推荐人数、留言条数、划线人数。
- 逐页抓取:翻页是整页 URL 跳转(begin=0,10,20,…),不是 AJAX。在
evaluate里点"下一页"会触发 CDP "Inspected target navigated" 错误——必须逐页 navigate + evaluate,一条 bash 循环搞定,每页结果追加写入 jsonl:
bash for begin in 0 10 20 ... (到 ceil(N/10)*10-1); do bsk navigate "https://mp.weixin.qq.com/cgi-bin/appmsgpublish?sub=list&begin=$begin&count=10&token=<token>&lang=zh_CN" --session <id> --json >/dev/null \ && bsk evaluate --quiet --session <id> "<extract_script>" >> mp_pages.jsonl done
extract_script(单引号 bash 字符串内只用双引号):
js (function(){function txt(e){return e?e.textContent.trim():''} var items=document.querySelectorAll('.weui-desktop-mass-appmsg');var out=[]; for(var i=0;i<items.length;i++){var it=items[i]; var card=it.closest('.publish_hover_content')||it.parentElement.parentElement; var timeEl=card.querySelector('.weui-desktop-mass__time'); var links=it.querySelectorAll('a.weui-desktop-mass-appmsg__title'); var stats=[];var ds=it.querySelectorAll('.weui-desktop-tooltip__wrp'); for(var j=0;j<ds.length;j++){var lab=ds[j].querySelector('.weui-desktop-tooltip');var val=ds[j].querySelector('.weui-desktop-mass-media__data__inner'); if(lab&&val){stats.push([txt(lab),txt(val)])}} for(var k=0;k<links.length;k++){out.push({time:txt(timeEl),title:txt(links[k]),url:links[k].href,stats:stats})}} return JSON.stringify({begin:<begin>,rows:out})})()
注意:一次群发多篇文章时 mass-appmsg 内有多个标题链接,脚本已按链接数展开成多行。 - 校验:用 Python 统计 jsonl 总行数 ≈ 页面"全部 N",检查 unique url 数、无 stats 的行(视频/图片消息可能无数据)。
- 生成 xlsx(按 excel-generation skill 范式,记录型清单):
- 列:序号、发表日期、文章标题、阅读数、点赞数、转发数、推荐数、留言数、划线数、文章链接、互动率。
- 日期解析:YYYY年MM月DD日直取;MM月DD日= 当年;今天/昨天 HH:mm按当天推算。
- 末行合计(SUM)+ 互动率(分母空/0 保护)。
- 坑:本平台无 LibreOffice 且 formulas 引擎未装,recalc 拿不到缓存值。 这是静态快照交付,把合计/互动率直接在 Python 里算好写入(不写公式字符串),保证微信/邮件预览器正常显示。
- 样式:商务蓝表头(#4472C4 白字)、筛选 A1 起、冻结 A2、标题列宽 42+wrapText。 - 收尾:
bsk session stop <id>(必须),删除登录二维码等临时截图,原始 jsonl 留档供增量更新。
产出约定
- 文件名:
公众号已发表文章数据统计.xlsx(已存在则加时间戳,不覆盖)。 - 完成后用 present_files 交付,并汇报:总篇数、时间跨度、累计阅读/点赞/转发、最高阅读文章。
示例与模板参考
1. 原始 jsonl 单行示例(第 4 步产物,每页一行)
{"begin":0,"rows":[
{"time":"2026年09月21日 08:27","title":"中美CPI对比:谁在通胀谁在通缩","url":"https://mp.weixin.qq.com/s/xxxx1",
"stats":[["阅读人数","12534"],["点赞人数","86"],["分享人数","142"],["推荐人数","57"],["留言条数","23"],["划线人数","9"]]},
{"time":"2026年09月20日 08:27","title":"茅台股东大会三个信号","url":"https://mp.weixin.qq.com/s/xxxx2","stats":[]}
]}
stats为空数组 = 视频/图片消息无数据,xlsx 中该行数值列留空并在备注标注"无数据(非图文消息)"。
2. xlsx 表格结构示例
| 序号 | 发表日期 | 文章标题 | 阅读数 | 点赞数 | 转发数 | 推荐数 | 留言数 | 划线数 | 文章链接 | 互动率 |
|---|---|---|---|---|---|---|---|---|---|---|
| 1 | 2026-09-21 | 中美CPI对比:谁在通胀谁在通缩 | 12534 | 86 | 142 | 57 | 23 | 9 | 链接 | 2.50% |
| 2 | 2026-09-20 | 茅台股东大会三个信号 | 9876 | 64 | 110 | 40 | 18 | 6 | 链接 | 2.41% |
| … | ||||||||||
| 合计 | 共 12 篇 | 89420 | 621 | 1053 | 410 | 187 | 72 | 2.47% |
- 日期统一为
YYYY-MM-DD;互动率 = (点赞+转发+留言) / 阅读,百分比保留 2 位,阅读为 0/空时写"—"。 - 合计行的数字直接由 Python 算好写入(静态值),不写 SUM 公式(本平台 recalc 不可用的坑,见第 6 步)。
3. 完成汇报文案模板
> 公众号文章数据已导出完成 ✅
> - 总篇数:12 篇(2026-07-01 至 2026-09-21)
> - 累计阅读 89,420|点赞 621|转发 1,053
> - 最高阅读:《中美CPI对比:谁在通胀谁在通缩》(12,534)
> - 平均互动率:2.47%
> 表格已生成:公众号已发表文章数据统计.xlsx
4. extract_script 关键选择器速查(调试用)
| 元素 | 选择器 |
|---|---|
| 单次群发卡片 | .weui-desktop-mass-appmsg |
| 文章标题链接 | a.weui-desktop-mass-appmsg__title |
| 数据对(label+value) | .weui-desktop-tooltip__wrp 内的 .weui-desktop-tooltip + .weui-desktop-mass-media__data__inner |
| 发表时间 | .weui-desktop-mass__time(在 card.closest('.publish_hover_content') 内) |
| 分页 URL 参数 | begin=0,10,20…&count=10&token=<token> |