抖音自动化发布
基于 OpenCLI 浏览器自动化,在抖音创作中心发布内容。
环境搭建(首次使用)
1. 安装 Node.js
要求 Node.js >= 21。检查版本:
node --version
2. 安装 OpenCLI
npm install -g @jackwener/opencli
验证安装:
opencli doctor
3. 安装 Claude Code 所需 Skill
本 Skill 依赖 OpenCLI 的配套 Skill,Claude Code 需要它们来理解 opencli browser 命令体系。
必装(核心):
# OpenCLI 主 Skill — 提供 opencli 全部命令知识
npx skills add jackwener/opencli
# OpenCLI 浏览器 Skill — 提供 browser 子命令参考(state/click/fill/upload/eval/wait 等)
npx skills add opencli-browser
推荐安装:
# OpenCLI 适配器开发 Skill — 需要调试/修改适配器时使用
npx skills add opencli-adapter-author
# OpenCLI 自动修复 Skill — 适配器命令失败时自动修复
npx skills add opencli-autofix
# OpenCLI 快速参考 Skill — 所有命令和站点的速查表
npx skills add opencli-usage
验证已安装的 Skill:
npx skills list
4. 安装 Browser Bridge 扩展
在 Chrome/Chromium 中安装 OpenCLI 扩展(Chrome Web Store 搜索 OpenCLI)。
或者手动安装:
1. 从 https://github.com/jackwener/opencli/releases 下载 opencli-extension-v{version}.zip
2. 解压,打开 chrome://extensions,启用开发者模式
3. 点击"加载已解压的扩展程序",选择解压目录
5. 登录抖音创作中心
在已安装扩展的浏览器中打开 https://creator.douyin.com 并登录。
6. 安装 douyin 适配器(可选,提供 opencli douyin 命令)
将适配器文件放入 ~/.opencli/clis/douyin/ 目录:
~/.opencli/clis/douyin/
├── article.js # 文章发布适配器
├── image-post.js # 图文发布适配器
├── _shared/
│ ├── creation-id.js
│ └── timing.js
draft.js(视频草稿)已内置在 OpenCLI 中。
7. 关键修复:evaluateWithArgs 问题
OpenCLI 1.7.18 存在一个 bug:多次调用 browser upload / browser fill 时 const 变量重复声明导致 SyntaxError。
找到 OpenCLI 安装目录下的 dist/src/browser/base-page.js(全局安装通常在 {npm 全局目录}/node_modules/@jackwener/opencli/dist/src/browser/base-page.js)。
查看 npm 全局目录:
npm root -g
找到 evaluateWithArgs 方法(约第 76 行),将:
return this.evaluate(`${declarations}\n${js}`);
改为:
return this.evaluate(`(() => {\n${declarations}\nreturn (${js});\n})()`);
支持的内容类型
| 类型 | 方式 | 复杂度 |
|---|---|---|
| 文章 | 浏览器手动操作 / opencli douyin article |
高 — Semi Design 封面上传 |
| 图文 | 浏览器手动操作 / opencli douyin image-post |
低 — 标准文件上传 |
| 视频 | 浏览器手动操作 | 中 — 需等待上传/转码 |
通用技巧
启动浏览器会话
opencli browser --session dy open "<url>"
如果 URL 含 &,Windows 命令行会将其截断,使用不含查询参数的基础 URL。
关闭弹窗
(function(){
var t=['我知道了','知道了','关闭','确定'];
for(var i=0;i<t.length;i++){
var b=Array.from(document.querySelectorAll('button,[role=button]')).find(function(e){
return (e.textContent||'').trim()===t[i];
});
if(b) b.click();
}
})()
点击发布按钮
(function(){
var b=Array.from(document.querySelectorAll('button')).find(function(x){
var t=(x.textContent||'').trim();
return t==='发布';
});
if(b) b.click();
})()
React 表单填写
抖音创作中心使用 React 17+(fiber 模式),DOM 元素没有 __reactProps$。
文本输入(标题、摘要)
browser fill 可正确处理 React 输入:
opencli browser --session dy fill "input[placeholder*=\"<部分占位符>\"]" "<文本>"
Contenteditable 编辑器(正文)
不要用 \n — 会被当作字面量。用 eval 注入 HTML 段落:
(() => {
var editor = document.querySelector('[contenteditable="true"][role="textbox"]');
// 图文用: document.querySelector('[contenteditable="true"]')
var html = '<p>段落一</p>' + '<p>段落二</p>';
var desc = Object.getOwnPropertyDescriptor(Element.prototype, 'innerHTML');
if (desc && desc.set) {
desc.set.call(editor, html);
} else {
editor.innerHTML = html;
}
editor.dispatchEvent(new Event('input', { bubbles: true }));
editor.dispatchEvent(new Event('change', { bubbles: true }));
})()
验证码输入框(type=number)
browser fill 对此类输入无效,用原生 setter:
var input = document.querySelector('input[type="number"][placeholder="请输入验证码"]');
var setter = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, 'value').set;
setter.call(input, '<验证码>');
input.dispatchEvent(new Event('input', { bubbles: true }));
input.dispatchEvent(new Event('change', { bubbles: true }));
图文发布
# 1. 导航
opencli browser --session dy open "https://creator.douyin.com/creator-micro/content/upload"
# 2. 等待并关闭弹窗
opencli browser --session dy wait time 3
opencli browser --session dy eval "弹窗关闭代码"
# 3. 切换到图文 Tab(先用 state 查看索引)
opencli browser --session dy state
opencli browser --session dy click <N> # "发布图文"
# 4. 上传图片
opencli browser --session dy upload "input[type=file][accept*=image]" "<图片路径>"
# 5. 等待编辑器加载
opencli browser --session dy wait time 4
# 6. 填写标题
opencli browser --session dy fill "input[placeholder*=填写作品标题]" "<标题>"
# 7. 填写正文(用 eval 注入 <p> 标签,见上方)
# 8. 发布
opencli browser --session dy eval "点击发布代码"
# 9. 等待结果
opencli browser --session dy wait time 5
文章发布
# 1. 导航
opencli browser --session dy open "https://creator.douyin.com/creator-micro/content/post/article"
# 2. 等待并关闭弹窗
opencli browser --session dy wait time 3
opencli browser --session dy eval "弹窗关闭代码"
# 3. 填写标题
opencli browser --session dy fill "input[placeholder*=文章标题]" "<标题>"
# 4. 填写正文(用 eval 注入 <p> 标签,见上方)
# 5. 上传封面(见下方封面上传章节)
封面上传
文章页使用 Semi Design 组件,其文件输入通过 document.createElement 创建但不挂载到 DOM。必须用 monkey-patch 拦截。
第 1 步:设置拦截并点击触发按钮
(function(){
var oc=document.createElement.bind(document);
var ocl=HTMLInputElement.prototype.click;
document.createElement=function(t,o){
var e=oc(t,o);
if(t.toLowerCase()==='input') window.__ci=e;
return e;
};
HTMLInputElement.prototype.click=function(){
if(this.type==='file'){
window.__ft=this;
this.setAttribute('data-oc-cov','1');
if(!this.isConnected) (document.querySelector('#root')||document.body).appendChild(this);
return;
}
return ocl.call(this);
};
var t=Array.from(document.querySelectorAll('span')).find(function(s){
return (s.textContent||'').trim()==='点击上传封面图';
});
if(t) t.click();
})()
第 2 步:上传文件
opencli browser --session dy upload "input[data-oc-cov=\"1\"]" <封面路径>
第 3 步:触发 change 事件
(()=>{
var i=document.querySelector('input[data-oc-cov="1"]');
i.dispatchEvent(new Event('change',{bubbles:true,composed:true}));
i.dispatchEvent(new Event('input',{bubbles:true,composed:true}));
})()
第 4 步:点击"完成"(必须执行,否则封面不生效)
opencli browser --session dy wait time 3
opencli browser --session dy eval "(function(){var b=Array.from(document.querySelectorAll('button')).find(function(x){return (x.textContent||'').trim()==='完成';});if(b)b.click();})()"
短信验证
发布可能触发短信验证弹窗(显示脱敏手机号 + 验证码输入框 + "获取验证码" + "验证"按钮)。
- 点击"获取验证码"发送验证码
- 向用户索要验证码
- 用原生 setter 填写(
browser fill对 type=number 无效) - 点击"验证"按钮
视频发布
# 1. 导航(默认即视频 Tab)
opencli browser --session dy open "https://creator.douyin.com/creator-micro/content/upload"
# 2. 上传视频
opencli browser --session dy upload "input[type=file][accept*=video]" "<视频路径>"
# 3. 等待处理(视频需要时间)
opencli browser --session dy wait time 15
# 4. 填写标题
opencli browser --session dy fill "input[placeholder*=填写作品标题]" "<标题>"
# 5. 发布(可在上传进行中发布)
opencli browser --session dy eval "点击发布代码"
使用适配器(推荐方式)
如果已安装 douyin 适配器,可以一行命令完成发布:
# 图文发布
opencli douyin image-post "<图片路径>" --title "标题" --caption "正文"
# 文章发布
opencli douyin article --title "标题" --content "正文" --cover "<封面路径>"
# 视频保存草稿
opencli douyin draft "<视频路径>" --title "标题"
适配器文件见环境搭建第 6 步。
故障排查
| 现象 | 原因 | 解决方法 |
|---|---|---|
Extension not connected |
浏览器扩展未运行 | 确保 Chrome 已打开且扩展已启用,运行 opencli doctor 检查 |
正文 \n 显示为字面量 |
通过 eval 传文本时未用 HTML | 用 innerHTML 注入 <p> 标签 |
browser upload 报 SyntaxError |
evaluateWithArgs 重复声明 const | 应用上述 base-page.js 修复 |
| 上传后封面未生效 | 没有点"完成"按钮 | 上传后必须点击"完成" |
| 验证码输入 fill 失败 | type=number 不支持 fill | 用原生 value setter 填写 |
selector_not_found |
placeholder 不匹配 | 用 opencli browser --session dy state 查看当前页面 |
URL 含 & 被截断 |
Windows cmd 解析问题 | 使用不含查询参数的基础 URL |
| Node API 报错 / 缺少 fetch | Node.js 版本过低 | Node.js >= 21 是强制要求 |
Unauthorized |
登录态过期 | 在浏览器中重新登录 creator.douyin.com |