一份 Markdown,自动发布到多个社交平台——小红书、抖音、快手、视频号、X (Twitter)、B 站。
⚠️ 早期开发中,CLI 接口可能变;浏览器自动化方案,无 API 依赖,平台 DOM 改版会导致选择器失效。🔒 向 GitHub 提交前必看:docs/git-safety.md——
cookies/、conf.py、.env*、qrcode.png、logs/、state/等含账号凭证 / 本机配置的目录已默认屏蔽,但 push 前还是要按 checklist 自查。
article.md ──→ mp publish ──┬─→ 小红书
├─→ 抖音
├─→ 快手
├─→ 视频号
├─→ X (Twitter)
└─→ B 站(计划中接入 publish)
- 它能做什么
- 适合谁用
- 安装(5 分钟)
- 快速开始
mp publish详解mp fetch wechat详解- Markdown frontmatter 字段参考
- 平台支持详情
- 常见问题
- 工作原理
- 项目结构
- 风险声明
| 任务 | 命令 | 说明 |
|---|---|---|
| 一篇 Markdown 同步发到 N 个平台 | mp publish article.md |
核心场景,按 frontmatter 中的 publish_to 自动适配每个平台 |
| 把公众号文章抓成 Markdown | mp fetch wechat <URL> |
含 frontmatter + 本地图片,可直接给 mp publish 用 |
| 没图也能发图文 | mp publish 自动渲染卡片 |
正文按段落切片渲染成 1080×1440 图文卡片 |
| 定时发布 | frontmatter schedule: 2026-05-20 14:00 |
各平台支持情况见下 |
| 多账号隔离 | --account creator1 / --account creator2 |
cookie 按账号分文件保存 |
| 每个平台还能单独发 | mp xiaohongshu upload-note ... |
需要平台特定字段时绕过 publish |
- 个人内容创作者:想把同一篇内容发到多个平台,不想手工复制粘贴 7 次。
- 写公众号文章的作者:想把已发布的公众号文章自动同步到其他平台。
- 会用命令行的人:本工具是 CLI,没有 GUI。
不适合:
- 需要批量营销、刷量、机器人矩阵——这不是这个工具的用途,封号风险自负。
- 不熟悉命令行——可以用,但门槛较高。
前置:macOS 或 Linux,已装 uv。
# 1. 克隆
git clone https://github.com/walter201230/media-publisher.git
cd media-publisher
# 2. Python 3.12(patchright 还不支持 3.13+)
uv python install 3.12
# 3. 虚拟环境(建议放 home 目录,iCloud 同步目录会卡)
uv venv ~/.venvs/mp --python 3.12
source ~/.venvs/mp/bin/activate
# 4. 装本项目
uv pip install -e .
# 5. 装浏览器(国内用 npmmirror 加速)
PLAYWRIGHT_DOWNLOAD_HOST="https://npmmirror.com/mirrors/playwright" patchright install chromium
# 6. 复制配置
cp conf.py.example conf.py验证:
mp --help
# 应输出:usage: mp [-h] {publish,fetch,douyin,kuaishou,xiaohongshu,x,bilibili} ...最常见的用法——写一份 Markdown,自动发到所有目标平台。
1. 准备 Markdown(hello.md):
---
title: 我的第一篇 mp 笔记
type: note
publish_to: [xiaohongshu, douyin, kuaishou]
account: creator
desc: 一份 Markdown 同时发到多个平台
tags: [测试, mp]
---
正文写 Markdown,标题、列表、引用都支持。
没有图片时,工具会自动把正文切成 1080×1440 的图文卡片,多个平台共用。2. dry-run 验证(不真发,只跑适配 + 生成卡片图):
mp publish hello.md --dry-run终端会打印每个平台的 ✅/❌ 和卡片图路径(在 ~/.cache/mp/dry-run/<时间戳>/_cards/),可以预览卡片渲染效果。
3. 登录各平台(第一次需要):
mp xiaohongshu login --account creator # 用小红书 App 扫码
mp douyin login --account creator # 抖音 App 扫码
mp kuaishou login --account creator # 快手 App 扫码扫码完成后 cookie 保存在 cookies/<platform>_<account>.json,后续命令会自动复用。
4. 真发布:
mp publish hello.md终端汇总每个平台的结果:
[✅] xiaohongshu — 已发布
[✅] douyin — 已发布
[❌] kuaishou — 适配/发布失败:cookie 已过期
把一篇公众号文章一键转成 Markdown,再发到其他平台。
# 1. 抓取(默认输出到 fetched/<sha8>/)
mp fetch wechat https://mp.weixin.qq.com/s/xxxxxxxxxxxxxx
# 2. 编辑产出的 article.md:填 publish_to / account
# 默认 frontmatter 已带 title / author / publish_time / source_url
# 3. 看一眼 dry-run,确认卡片渲染没问题
mp publish fetched/abc12345/article.md --dry-run
# 4. 真发
mp publish fetched/abc12345/article.md不写 frontmatter,直接发一个平台:
# 小红书图文
mp xiaohongshu upload-note --account creator \
--images 1.png 2.png --title "标题" --note "正文" --tags 标签1,标签2
# 抖音视频
mp douyin upload-video --account creator \
--file demo.mp4 --title "标题"
# B 站视频(B 站不走 publish,只能单平台命令)
mp bilibili upload-video --account creator \
--file demo.mp4 --title "标题" --desc "简介" --tid 21
# X (Twitter) 推文
mp x upload-tweet --account main \
--text "Hello from mp" --images 1.png 2.png每个平台的完整参数:mp <platform> --help。
mp publish <article.md> # 按 frontmatter.publish_to 发布
mp publish <article.md> --only xiaohongshu,douyin # 临时覆盖 publish_to
mp publish <article.md> --account other_account # 覆盖账号
mp publish <article.md> --schedule "2026-05-20 14:00" # 定时
mp publish <article.md> --dry-run # 只跑适配 + 渲染卡片图0— 所有目标平台都成功1— 至少一个平台失败(终端有逐平台 ✅/❌ 汇总)
- 图文卡片自动渲染:
type: note或article,且 frontmatter 没填media:时,编排器把正文切片渲染成竖屏卡片图,所有目标平台共用同一组卡片。 - 逐平台隔离:某个平台失败不影响其他平台,最后给汇总。
- dry-run 产物:
~/.cache/mp/dry-run/<timestamp>/,含_cards/(共用卡片)和<platform>/(平台专属,预留)。
把一个公众号文章 URL 转成 mp publish 能吃的 Markdown。
mp fetch wechat <URL> # 输出到 fetched/<sha8>/
mp fetch wechat <URL> -o ./posts/foo/ # 自定义目录产物:
fetched/abc12345/
├── article.md # 含 frontmatter
└── images/
└── <sha1>.jpg # 文章里的图片,已下载到本地
生成的 frontmatter:
---
title: 文章标题(自动抓)
type: article
author: 公众号名(自动抓)
publish_time: 2026-05-10 10:30
source_url: https://mp.weixin.qq.com/s/xxx
publish_to: [] # ← 自己填目标平台
tags: [] # ← 自己填
---抓完手动填 publish_to: [xiaohongshu, douyin, ...],再 mp publish。
---
title: 必填,文章/视频标题
type: note | video | article
# note = 短图文(适配为图文卡片)
# video = 视频(必须给 media)
# article = 长图文(行为同 note,预留为语义标签)
publish_to: # 必填(除非用 --only 覆盖)
- xiaohongshu
- douyin
- kuaishou
- tencent # 视频号
- x # X (Twitter)
account: creator # 可选,默认 creator;可用 --account 覆盖
desc: 兜底简介 # 可选,平台用作 desc/note
tags: [tag1, tag2] # 可选
schedule: 2026-05-20 14:00 # 可选,定时发布(格式 YYYY-MM-DD HH:MM)
media: # video 必填;note 可选(缺省自动渲染卡片)
- videos/demo.mp4
- videos/cover.png
cover: videos/demo.png # 可选,视频封面
---
正文写 Markdown。路径相对性:media / cover 是相对 .md 文件所在目录的路径。
publish_to 值 |
视频 | 图文(自带图) | 图文(自动渲染卡片) | 定时 | cookie 路径 | 登录入口 |
|---|---|---|---|---|---|---|
xiaohongshu |
✅ | ✅ | ✅ | ✅ | cookies/xiaohongshu_<account>.json |
mp xiaohongshu login --account <name> |
douyin |
✅ | ✅ | ✅ | ✅ | cookies/douyin_<account>.json |
mp douyin login --account <name> |
kuaishou |
✅ | ✅ | ✅ | ✅ | cookies/kuaishou_<account>.json |
mp kuaishou login --account <name> |
tencent(视频号) |
✅ | ✅ | ✅ | ✅ | cookies/tencent_uploader/<account>.json |
python examples/get_tencent_cookie.py |
x (Twitter) |
❌ | ✅(≤4 张图) | ✅ | ❌ | cookies/x_<account>.json |
mp x login --account <name>(密码登录) |
| 平台 | 命令 | 说明 |
|---|---|---|
| Bilibili | mp bilibili upload-video ... |
走 biliup,未接入 mp publish |
| 百家号 | (uploader 已就绪) | CLI 待接入 |
| TikTok | (uploader 已就绪) | 海外环境用 |
| 知乎 / 微博 | — | 计划中 |
- cookie 路径不在
cookies/根目录下,而是嵌套在cookies/tencent_uploader/<account>.json。 - 登录不走
mp tencent login(暂未接入),用python examples/get_tencent_cookie.py,用视频号助手 App 扫码(不是微信主 App)。
- X 不支持扫码登录,
mp x login会弹出浏览器让你手动输入账号密码(最多等 5 分钟)。 - 国内访问 X 需要代理,在
conf.py设:也可以用环境变量X_PROXY = "http://127.0.0.1:7890" # 或 socks5://...
MP_X_PROXY覆盖。 - 当前只支持图文(≤ 4 张图),不支持视频。
Q: 扫码看不到二维码?
确认 conf.py 里 LOCAL_CHROME_HEADLESS = False(默认就是 False),会弹出可见浏览器窗口,二维码直接显示在登录页上。也可以打开终端提示的 qrcode.png。
Q: ModuleNotFoundError: No module named 'conf'
必须在项目根目录执行命令(CLI 会从 conf.py 加载 BASE_DIR)。如果没有 conf.py,跑 cp conf.py.example conf.py。
Q: cookie 失效
各平台 cookie 有效期通常 1–3 个月,失效后重新跑 mp <platform> login --account <name> 即可。
Q: iCloud 路径下 venv 卡顿
venv 一定要放到 home 目录(如 ~/.venvs/mp),别放在 iCloud 同步目录里。项目源码在 iCloud 路径影响不大。
Q: 发布卡在「上传中」 平台后端转码慢/网络问题。等一下,或 Ctrl-C 后重试。
Q: 视频号一直 401 / 跳登录页
视频号 cookie 路径特殊(在 cookies/tencent_uploader/ 子目录下),重新跑 python examples/get_tencent_cookie.py,用视频号助手 App 扫码。
Q: 卡片图里 Markdown 标题乱码?
当前卡片渲染只做了纯文本切片,复杂格式会被 strip 掉。如果要发完整排版,自己给 media: [...] 提供成品图片。
Q: X 推文发了但终端说「未确认到发推成功」 X 的成功检测目前不稳,去 x.com 看一眼自己的主页即可。后续会改进。
读 .md (Markdown + frontmatter)
↓
解析成统一 Article 对象
↓
对每个目标平台分别适配(截断 / 卡片化 / 格式转换)
↓
调用各平台的上传器(patchright 驱动浏览器自动化,无 API 依赖)
↓
汇总每个平台的 ✅/❌ 结果
技术栈:
- patchright:playwright fork,加了 stealth 防检测
- stealth.min.js:第二层防检测(注入 init script)
- storage_state:cookie 持久化,按
<platform>_<account>.json隔离 - python-frontmatter + markdownify:Markdown / HTML 互转
media-publisher/
├── mp_cli.py # CLI 主入口
├── conf.py.example # 配置模板
├── pyproject.toml
│
├── article/ # Article 数据模型 + Markdown loader
├── adapters/ # 各平台内容适配器(Article → 平台 payload)
│ ├── _common.py # cookie 路径、note 文本拼接等共用逻辑
│ ├── base.py
│ ├── xiaohongshu/ # 含卡片渲染(templates/card.html + image_card.py)
│ ├── douyin/
│ ├── kuaishou/
│ ├── tencent/ # 视频号
│ └── x/ # X (Twitter)
├── ingest/ # 外部内容源 → Markdown
│ └── wechat/ # 公众号 URL → article.md + 图片
├── orchestrator/ # publish 编排器 + adapter registry
├── cli/ # mp publish / mp fetch 等高层命令
├── diagnose/ # 各平台连通性诊断脚本
│
├── uploaders/ # 底层平台 SDK(每个平台一个目录)
│ ├── xiaohongshu_uploader/
│ ├── douyin_uploader/
│ ├── ks_uploader/
│ ├── tencent_uploader/
│ ├── x_uploader/
│ ├── bilibili_uploader/
│ ├── baijiahao_uploader/
│ └── tk_uploader/
│
├── examples/ # 还没进 CLI 的脚本入口(如视频号登录)
│
├── utils/ # 通用工具
│ ├── base_social_media.py # stealth.min.js 注入
│ ├── browser_hook.py # patchright 启动参数
│ ├── login_qrcode.py # 二维码处理
│ └── stealth.min.js
│
├── skills/ # Claude Code skills(给 AI agent 用的调用指南)
│ ├── mp-publish/
│ ├── xiaohongshu-upload/
│ ├── douyin-upload/
│ ├── kuaishou-upload/
│ └── bilibili-upload/
│
├── docs/mp/ # 设计文档
│
└── cookies/ # 登录态文件(gitignore)
自动化操作可能违反目标平台的服务条款。本工具仅供个人内容创作者用于自己内容的多平台分发。
禁止用于:刷量、批量营销、机器人账号矩阵、爬取他人数据。
账号封禁风险自负。
平台 DOM 改版会导致选择器失效,欢迎 issue / PR。