Skip to main content

mpdt — 公众号运营数据,抓回本机,一键周报

WeChat Official Account analytics, fully local — fetch, store, and report your own data via one CLI.

Python 3.10+ License: MIT CI Tests Dependencies

公众号后台(mp.weixin.qq.com)的运营数据散落在三个页面,官方不提供导出,mpdt 把它们自动抓回本机 SQLite,并生成 Markdown 周报:

  • 发表列表:阅读 / 分享 / 点赞 / 评论(实时累计口径)
  • datacube 文章级:完读率 / 阅读率 / 送达 pv(发表后 7 天窗口,T+1)
  • 单篇渠道页:逐篇阅读人数、完读率、平均时长、渠道构成(推荐 / 搜一搜 / 公众号消息…,30 天窗口)

为什么做这个

  • 官方不提供导出:后台数据只能一屏一屏翻页看,换设备、离职交接、跨年对比都无从下手
  • 商业工具 ¥99/月起:第三方 SaaS 要么按月收费,要么要求交出账号托管,个人号主用不起也不敢用
  • 个人号主被忽视:官方与商业工具都面向机构运营团队,一个人打理的号缺少趁手的本地工具

mpdt 的答案:数据 100% 留在本机(SQLite + 本地文件),复用你已登录的 Chrome,不托管、不上传、不收费。

⚠️ 口径警告:三源同名指标口径不同(统计窗口 / 分母各异)——发表列表是实时累计,datacube 是发表后 7 天窗口 T+1,单篇渠道页是 30 天窗口。跨源比较前先对齐口径,周报文首附完整口径说明。

特性

  • 零扫码:复用本机已登录 Chrome 的登录态(CDP 远程调试),token 从页面 URL 自动刷新
  • 全本地:数据只存本机 SQLite(~/.mpdt/mpdt.sqlite3),凭据文件 600 权限、打印永不回显
  • 幂等:同一天重复抓取 upsert 不重复;log_run 记录每次运行
  • 礼貌限速:请求间隔 ≥ 1s
  • 错误语义明确:退出码 0 成功(含空数据)|2 配置问题|3 凭据/登录态问题|4 上游接口异常(附原始返回片段)|130 用户中断(幂等设计,重跑安全)
  • 机器可读输出:全局 --json 参数——stdout 恰好一行 JSON({ok, cmd, data, meta}),适合脚本/管道串联
  • 非交互友好:stdout 非 TTY(管道 / 重定向 / cron)时自动静默过程输出
  • 零框架测试:98 个 unittest,零第三方测试依赖,python3 tests/test_fetchers.py 直跑

安装

# 推荐:pip 安装
pip install mpdt

# 或本地安装
git clone https://github.com/ttxs69/mpdt.git
cd mpdt && pip install .

未安装到环境时,python3 -m mpdt 与 mpdt 命令完全等价——从仓库根目录直接运行即可。

依赖:Python 3.10+、requests、websocket-client(其余全标准库)。

Quick Start(30 秒)

# ① 以调试端口启动 Chrome 并登录公众号后台
google-chrome --remote-debugging-port=9222
#    打开 https://mp.weixin.qq.com 扫码登录,保持该标签页存在

# ② 初始化配置(生成 ~/.mpdt/config.json,600 权限)
mpdt init

# ③ 抓数据 → 出周报
mpdt fetch --backfill 7   # 抓最近 7 天(默认仅昨天,T+1 口径)
mpdt detail --recent 7    # 单篇渠道构成(最近 7 天发表的)
mpdt report               # → mpdt-reports/weekly-YYYY-Www.md

已在跑的 Chrome 需先完全退出再用该参数重启;介意隔离可用独立 profile: --user-data-dir=/tmp/mpdt-chrome --remote-debugging-port=9222

命令一览

命令 作用 常用参数
mpdt init 生成配置 --db PATH 自定义数据库位置
mpdt fetch 发表列表 + datacube 文章级快照 --backfill N / --from/--to YYYY-MM-DD / --count N
mpdt detail 单篇渠道页(完读率 + 渠道构成) --recent N,或 --msgid ID --publish-date D [--item-idx 1]
mpdt report 生成周报 Markdown + HTML --week 2026-W42
mpdt export 导出快照 CSV(附口径元数据 *.metrics.csv) --source SOURCE --out OUT(--no-meta 关闭伴随文件)
mpdt metrics 列出全部指标及口径(按概念分组) 可选位置参数按 概念名/显示名/源/字段 子串过滤

所有命令支持全局 --json(stdout 恰好一行 JSON)。

指标口径(CONCEPTS · 按概念分组)

完读率(read_completion,单位:比例(0-1))

完读率是同一概念下的两个口径,窗口与分母均不同

series_key 源字段 所属源 窗口 窗口天数 分母 备注
dc7 finish_read_rate datacube_article 发表后 7 天窗口,T+1 出数 7 7 天窗口内阅读人数 datacube 7 天窗口·阅读人数分母
ad30 finished_read_pv_ratio article_detail 发表后 30 天窗口 30 阅读次数(pv) 单篇页 30 天窗口·pv 分母

阅读量(read_volume,单位:人次/次/人(按 series 而定))

三个 series 口径不同:实时累计 vs 7 天 pv vs 30 天 uv

series_key 源字段 所属源 窗口 窗口天数 分母 备注
pl read_num publish_list 实时累计(拉取时点全量) 0 - publish_list 实时累计,无窗口无去重
dc7 total_pv datacube_article 发表后 7 天窗口,T+1 出数 7 - datacube 7 天窗口·全渠道阅读次数(≈量级)
ad30 read_uv article_detail 发表后 30 天窗口 30 「全部」渠道去重 单篇页 30 天窗口·全渠道去重阅读人数

分享(share,单位:次/人(按 series 而定))

series_key 源字段 所属源 窗口 窗口天数 分母 备注
pl share_num publish_list 实时累计(拉取时点全量) 0 - 实时累计分享次数
dc7 total_share datacube_article 发表后 7 天窗口,T+1 出数 7 - datacube 7 天窗口·分享次数
ad30 share_uv article_detail 发表后 30 天窗口 30 - 单篇页 30 天窗口·分享人数

点赞(like,单位:次)

series_key 源字段 所属源 窗口 窗口天数 分母 备注
pl like_num publish_list 实时累计(拉取时点全量) 0 - 实时累计点赞数
ad30 like_cnt article_detail 发表后 30 天窗口 30 - 单篇页 30 天窗口·点赞数

在看(wow,单位:次)

series_key 源字段 所属源 窗口 窗口天数 分母 备注
ad30 zaikan_cnt article_detail 发表后 30 天窗口 30 - 单篇页 30 天窗口·「在看」数(与点赞不同概念)

评论(comment,单位:条)

series_key 源字段 所属源 窗口 窗口天数 分母 备注
pl comment_num publish_list 实时累计(拉取时点全量) 0 - 实时累计评论数
ad30 comment_cnt article_detail 发表后 30 天窗口 30 - 单篇页 30 天窗口·评论数

送达人数(delivery,单位:人)

series_key 源字段 所属源 窗口 窗口天数 分母 备注
dc7 send_succ datacube_article 发表后 7 天窗口,T+1 出数 7 - datacube 7 天窗口·送达人数(分母=送达)

完读次数(finish_count,单位:次)

series_key 源字段 所属源 窗口 窗口天数 分母 备注
dc7 total_read_finish datacube_article 发表后 7 天窗口,T+1 出数 7 - datacube 7 天窗口·完读次数

阅读率(read_rate,单位:比例(0-1))

series_key 源字段 所属源 窗口 窗口天数 分母 备注
dc7 read_rate datacube_article 发表后 7 天窗口,T+1 出数 7 送达人数(send_succ) datacube 阅读 pv / 送达

阅读后关注人数(follow_after_read,单位:人)

series_key 源字段 所属源 窗口 窗口天数 分母 备注
ad30 follow_after_read_uv article_detail 发表后 30 天窗口 30 - 单篇页 30 天窗口·阅读后关注人数

收藏人数(collection,单位:人)

series_key 源字段 所属源 窗口 窗口天数 分母 备注
ad30 collection_uv article_detail 发表后 30 天窗口 30 - 单篇页 30 天窗口·收藏人数

听读人数(listen_people,单位:人)

series_key 源字段 所属源 窗口 窗口天数 分母 备注
ad30 listen_uv article_detail 发表后 30 天窗口 30 - 单篇页 30 天窗口·听读人数(与听读次数不同概念)

听读次数(listen_plays,单位:次)

series_key 源字段 所属源 窗口 窗口天数 分母 备注
ad30 listen_pv article_detail 发表后 30 天窗口 30 - 单篇页 30 天窗口·听读次数(与听读人数不同概念)

平均阅读时长(avg_read_time,单位:秒)

series_key 源字段 所属源 窗口 窗口天数 分母 备注
ad30 avg_article_read_time article_detail 发表后 30 天窗口 30 - 单篇页 30 天窗口·平均阅读时长(秒)

赞赏金额(praise_money,单位:上游金额单位)

series_key 源字段 所属源 窗口 窗口天数 分母 备注
ad30 praise_money article_detail 发表后 30 天窗口 30 - 单篇页 30 天窗口·赞赏金额

元数据字段(非指标:快照日 / 派生列 / 结构列)

规范名 字段 源 窗口 类型 备注
refdate refdate datacube_article 发表后 7 天窗口,T+1 出数 snapshot 文章口径日(快照行 stat_date 是拉取日,两者不同)
publish_date publish_date article_detail 发表后 30 天窗口 snapshot 单篇页 30 天窗口·文章发表日
window_days window_days article_detail 发表后 30 天窗口 derived mpdt 写入的派生列(页面固定 30 天)
total_read_user total_read_user article_detail 发表后 30 天窗口 derived mpdt 派生列:「全部」渠道逐日 read_user 求和
channel_breakdown channel_breakdown article_detail 发表后 30 天窗口 structured mpdt 派生列;同一用户多渠道重复计数 → 占比之和可 >100%(仅「全部」去重)

旧版字段(保留登记;不参与对照 / 不出现在 metrics 视图)

旧版字段保留在注册表里是为了让 mpdt/metrics.py 仍能识别上游接口历史返回的字段(CSV 导出元数据 *.metrics.csv 会标出口径),但不参与周报对照、metrics 视图与自动配对。

  • old_like_num → like_num:旧版字段(保留登记),口径与 like_num 相当

自动推导的易混淆配对(同一概念多 series)

概念 不可直接比的 series 配对 主要差异
完读率(read_completion,1 对) dc7 vs ad30 分母、窗口
阅读量(read_volume,3 对) pl vs dc7;pl vs ad30;dc7 vs ad30 分母、窗口
分享(share,3 对) pl vs dc7;pl vs ad30;dc7 vs ad30 窗口
点赞(like,1 对) pl vs ad30 窗口
评论(comment,1 对) pl vs ad30 窗口

本节由 mpdt/metrics.py CONCEPTS 自动生成(python3 -c "from mpdt.metrics import readme_section; print(readme_section())")。改口径请改 CONCEPTS,再运行 mpdt metrics 校对。

FAQ

  • fetch 提示「该日期范围无数据」:不是错误(退出码 0)。datacube 为 T+1 口径,当天数据明天可得。
  • 退出码 3(AuthError):CDP 9222 上没有已登录的 mp.weixin 标签页——回 Quick Start ① 检查 Chrome 参数与登录态。
  • 退出码 4(UpstreamError):微信接口返回了未识别结构——错误信息附原始返回片段,提 issue 时请一并贴出。
  • 换机器 / 重置:删除 ~/.mpdt/ 后重跑 mpdt init。数据库与配置都在该目录(除非 --db 另指定)。
  • 会碰我的 Chrome 吗:只通过 CDP 读取已登录标签页的 URL 与发起后台 API 请求,不注入脚本、不改动页面。

文档

边界与合规

  • 只读取你自己公众号后台的数据;不提供任何刷量 / 代抓他人数据能力
  • 自动化访问后台属微信 ToS 灰色地带,本项目仅限个人备份分析用途,风险自担

License

MIT © ttxs69

Metadata

Release files for mpdt 0.2.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for mpdt 0.2.3
File Size Uploaded Provenance
mpdt-0.2.3.tar.gz 69.1 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for mpdt 0.2.3
File Interpreter ABI Platform
mpdt-0.2.3-py3-none-any.whl Python 3 none any Details

Total release size: 115.8 kB

Release files / mpdt-0.2.3.tar.gz

Download URL mpdt-0.2.3.tar.gz
Size 69.1 kB
Tags Source
SHA-256 checksum
How to use checksums
e440bb89b44caabaf24556380034c1c0bd7b1e6b72be2bc77ffbf4450db9cd4c
BLAKE2b-256 checksum
How to use checksums
0646c5fd38da3e1093db2b9e2cb24e8139303477e936e11f7e1ca7d7bbb41227
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 17, 2026.

Transparency log

Release files / mpdt-0.2.3-py3-none-any.whl

Download URL mpdt-0.2.3-py3-none-any.whl
Size 46.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
5bd7a6f264df1e5eef623c7ffa792e6f3940a199f5041254a920f37e43d1e238
BLAKE2b-256 checksum
How to use checksums
b026339c5485c897136118283fd7bcf20c4b8867d2450e5cb7e30e31776b32c8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 17, 2026.

Transparency log

Security for mpdt 0.2.3

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for mpdt-0.2.3.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 17, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page