视频创作声明合规自动化:用 Puppeteer 把每个平台的弹窗都驯服了

1 阅读7分钟

分类:前端 标签:Electron、开源


一、政策来了,手动操作有多烦

2025 年 3 月,国家网信办联合工信部、公安部、广电总局发布《人工智能生成合成内容标识办法》(国信办通字〔2025〕2号),要求视频创作者在发布 AI 生成或辅助生成的内容时,必须主动进行内容标识声明。随后各大平台陆续跟进落地——抖音、快手、B 站、小红书相继在发布流程里加入了「创作声明」弹窗或选项,要求创作者勾选内容类型:是否使用 AI 辅助、是否为二次创作、是否涉及虚构剧情等。原文地址:www.gov.cn/zhengce/zhe…

政策本身没什么问题,合规是应该的。问题在于执行层面。

如果你只运营一个账号,偶尔发几条视频,手动勾选不是难事。但如果你跑的是矩阵账号——同一套内容分发到 5 个平台、每个平台 3 个账号,一周发 4 次,那每次发布都要在不同平台的不同弹窗里重复做同样的操作。每次发布大约要多花 2-3 分钟,算下来一周多出将近一小时的纯机械劳动。

更烦的是各平台的实现方式完全不统一:

  • 抖音是发布流程末尾的一个独立弹窗,需要点「填写声明」再进入子页面选择
  • 快手是发布表单里的一个折叠区域,默认收起,需要手动展开
  • B 站把它放在「更多选项」里,不展开根本看不到
  • 小红书是正文编辑页侧边栏的一个 toggle,位置还会随版本更新而漂移

每个平台的交互路径不同,每次发布都得重新想一遍「这个平台的声明在哪」。人工操作既耗时又容易忘,一旦漏填可能被平台限流甚至警告。

这就是我在 MatrixMedia 里把创作声明自动化纳入核心功能的原因。


二、技术方案:用 Puppeteer 驯服每一个弹窗

MatrixMedia 的底层是 Electron + Puppeteer。Electron 负责管理多账号的 session(每个账号一个独立的 BrowserContext,互不干扰),Puppeteer 负责驱动浏览器做实际操作。

发布视频的整体流程可以分为几个阶段:填写标题/描述、上传文件、处理附加信息(标签、封面、定时等)、最后提交。创作声明的处理被抽象为「附加信息处理」阶段的一个子步骤。

核心挑战有两个:

1. 如何可靠地检测弹窗或选项是否出现

平台页面是动态渲染的,元素出现时机不固定。直接用 page.$() 查找往往会因为时机问题拿到 null。我们封装了一个带超时和重试机制的等待函数,大致思路是:

waitForSelectorWithRetry(page, selector, options)
  - 最大等待时长:可配置,默认 8 秒
  - 轮询间隔:300ms
  - 如果超时且 required=false,视为「本次发布该平台无此弹窗」,跳过
  - 如果超时且 required=true,抛出异常,发布流程终止

创作声明属于「存在则填,不存在则跳过」的场景,所以用 required=false 处理,不会因为某次平台 UI 改版导致整个发布失败。

2. 如何处理跨平台的 selector 差异

各平台的 DOM 结构完全不同,不可能写一个通用 selector。我们的做法是为每个平台单独维护一个「发布步骤配置文件」,里面描述了该平台创作声明相关元素的选择器、操作顺序和等待条件:

platform: douyin
creativeStatement:
  trigger: '[data-testid="creative-declaration-btn"]'
  container: '.creative-declaration-modal'
  options:
    - selector: '[value="ai_generated"]'
      label: AI 生成
    - selector: '[value="secondary_creation"]'  
      label: 二次创作
  confirmBtn: '.modal-confirm-btn'

实际执行时,Puppeteer 按照这份配置依次查找元素、点击、等待状态变化,最后确认。逻辑层与平台特定的选择器完全解耦,新增平台只需要增加一份配置,不需要改执行逻辑。


三、全平台覆盖的实际情况

目前 MatrixMedia 支持的平台是:抖音、快手、B 站、百家号、头条、视频号、小红书,共 7 个平台。创作声明自动化的支持情况如下:

抖音:完整支持。弹窗交互路径固定,选择器稳定,是 7 个平台里最好处理的。

快手:完整支持。折叠区域需要先触发展开动画,等动画结束后再操作内部元素,否则点击会落空。用 waitForSelector + 短暂 delay 解决。

B 站:完整支持。「更多选项」需要先展开,逻辑和快手类似,但选择器完全不同。

小红书:支持,但需要额外处理 toggle 的状态判断。小红书的声明 toggle 有时候默认已开启(平台自动推断),这种情况下不应该再去点击,否则反而会关掉。所以操作前要先读取当前状态,再决定是否点击。

百家号、头条、视频号:这三个平台目前的创作声明入口形式更接近「发布表单里的一个普通字段」,不是弹窗,处理起来相对简单,直接按配置填写即可。

目前唯一没有完整自动化的是某些平台在特定账号状态下会弹出「首次声明须知」的全屏引导页,这类一次性弹窗逻辑上只需要处理一次,我们的做法是检测到它之后点击「我知道了」,同时在本地记录该账号已完成首次引导,后续发布跳过检测。


四、代码设计思路

整个创作声明模块的设计遵循几个原则:

配置驱动,不写死逻辑。选择器、操作顺序、等待时长全部在配置文件里定义,执行引擎只管按配置跑。平台 UI 改版时只需要更新配置,不需要改代码。

幂等性。同一个发布任务如果因为网络或其他原因重试,创作声明的操作不能重复执行(比如重复点击导致反选)。每次操作前先检查当前状态。

失败隔离。创作声明处理失败不应该导致整个发布任务失败——合规是重要的,但发布本身也是重要的。我们把它设计为「尽力执行,失败记录警告,不中断主流程」。当然如果业务上要求严格合规,可以通过配置把它改为「失败则中断」。

可观测。每次创作声明的处理结果(是否触发、选择了哪些选项、是否成功)都会写入发布日志,方便后续审计。

这套设计放到更大的视角里看,其实是一个通用的「表单自动化框架」的具体应用。MatrixMedia 里的标签填写、封面上传、定时发布设置,用的是同一套机制,创作声明只是其中一个模块。


五、对运营者的实际价值

技术细节说完,回到实际使用层面。

对于矩阵运营来说,创作声明自动化意味着:发布任务提交之后,这件事你不需要再管。无论是立即发布还是定时发布,工具会在合适的时机处理好每个平台的声明。你不会因为忘记填而被平台扣分,也不需要在 5 个平台之间来回切换做重复操作。

MatrixMedia 支持 CLI 调用,这意味着它可以被 AI Agent 集成进工作流。比如 Claude 或其他 Agent 生成完视频脚本、完成剪辑之后,直接调用 MatrixMedia 的 CLI 接口发布,创作声明、标签、定时等参数全部通过命令行传入,整个流程无人值守。这也是我们和蚁小二这类工具的核心差异——我们不是做一个更好用的 GUI,而是做一个 Agent 可以直接驱动的底层工具。


开源地址:github.com/hanliang97/… 代码对你有用的话,点个 Star,这是对开源项目最直接的支持。


帮个忙,填 5 题,2 分钟 — 我在验证 MatrixMedia 的下一步方向,你的反馈直接影响功能优先级。 👉 点这里填写