feat(monitor): 抖音 Web 接口客户端 —— 绕开爬虫子进程,直接发 HTTP
移植自 mac-agent-os 的 mediacrawler_adapter:不起子进程、不开页面,用浏览器里那份
登录态直接调抖音 Web 接口。产物键名照抄 store/douyin,所以 ingest 那条链路一个字不用改。
**目前能用的(真环境实测,非推断)**:
profile/other : 200, 7075 字节 —— 博主主页指标(粉丝/获赞/作品数/昵称)
aweme/detail : 200, 45425 字节 —— 单条作品详情(含点赞/评论/收藏/分享)
**目前不能用的:作品列表 `aweme/post`。** 两个互相独立的原因:
1. 这个接口被抖音单独升级成了真校验:不带 x-tt-argus 回 403「Uifid Not Found」,
带上 dummy 值回 200 + **空 body**。也就是说「头在不在」骗得过,「真校验」过不了。
同一套头打 profile/other 和 aweme/detail 都是通的 —— 抖音是挑着接口加保护的,
挑中的恰好是「批量拉作品列表」这个最敏感的动作。
2. 改走页面截获也不行:CDP 浏览器打开博主主页会落到「验证码中间页」(当天大量探测的
代价,过几小时要重测)。
所以现在的边界是:**已知作品的指标刷新能做,自动发现新作品做不了**。
**排查中控住变量后得到的两条事实**(都写进注释了):
· `Accept` / `Accept-Language` / `Referer` 才是主页接口能返回真数据的原因 —— 只有
UA+client hints+Cookie 时是 200 但仅 121 字节的空壳,补上这三个头变 7074 字节。
(我先前猜的 sec-ch-ua 不是关键。)
· 因此 UA 与 client hints 必须**成套地取自同一个浏览器**,所以 BrowserIdentity 一次
从 CDP 取齐 cookie + UA + hints,而不是各自写死。
「200 + 空 body 必须当场报错」也是刻意写死的:放过去它会在下游变成「这个博主没作品」,
把一次失败伪装成一条正常结果 —— 爬虫那条路正是这么栽的,还被翻译成「账号被封」。
测试 +11:cookie 解析、请求头成套性(含 uifid 缺失/回退)、产物键名与 store 对齐、
以及 _get 的三条失败路径(空 body / 403 带网关原话 / 正常返回)。
This commit is contained in:
@@ -0,0 +1,295 @@
|
||||
# AgentOS 前端看板调整方案
|
||||
|
||||
> 版本: 1.0 | 日期: 2026-07-04
|
||||
> 后端改动: Phase 1 三队列 + Phase 2 语料重组 + Phase 3 智能评论
|
||||
|
||||
---
|
||||
|
||||
## 一、调整总览
|
||||
|
||||
| 视图 | 文件 | 行数 | 当前状态 | 需要调整 |
|
||||
|:-----|:------|:-----|:---------|:---------|
|
||||
| **指挥台** | `ops-command.js` | 413 | ✅ P0/P1/P2 过滤 + 初始化按钮 | 小修 |
|
||||
| **定向评论** | `matrix-comment.js` | 99 | ❌ 只支持旧 comment 类型 | **大改** |
|
||||
| **语料库** | `matrix-corpus.js` | 573 | ❌ 无行业/accessible 显示 | **大改** |
|
||||
| **账号中心** | `accounts-center.js` | 797 | ❌ 无 smart_comment + industry 显示 | **中改** |
|
||||
| **互动操作** | `matrix-interact.js` | 500 | ⚠️ 有 corpus 浏览但无行业池 | 小修 |
|
||||
| **执行管道** | `execution-pipeline.js` | 300 | ❌ 未被任何视图引用 | 可废弃 |
|
||||
| **命令历史** | `matrix-commands.js` | 221 | ⚠️ 需确认状态展示一致 | 小修 |
|
||||
|
||||
---
|
||||
|
||||
## 二、每项调整详述
|
||||
|
||||
### 2.1 指挥台(ops-command.js)— 小修
|
||||
|
||||
**当前已有功能** ✅
|
||||
- P0/P1/P2 过滤器 ✅
|
||||
- 机器下拉选择 ✅
|
||||
- 初始化/重置全部按钮 ✅
|
||||
- 活动任务网格 + 队列详情 ✅
|
||||
|
||||
**需要补充**:
|
||||
| 补充项 | 原因 | 工作量 |
|
||||
|:-------|:------|:-------|
|
||||
| 在队列详情中区分 smart_comment 任务来源 | 当前 P0 任务只显示优先级,不区分是评论还是智能评论 | ~10行 |
|
||||
| 添加视频分析状态显示(如果是 smart_comment) | VideoAnalyzer 的 `asyncio.run()` 可能执行较久,用户需要知道分析进度 | ~30行 |
|
||||
| 队列详情增加 industry 过滤 | 让用户只看 health 或 general 账号的任务 | ~15行 |
|
||||
|
||||
---
|
||||
|
||||
### 2.2 定向评论(matrix-comment.js)— ❌ 需要大改
|
||||
|
||||
**当前问题**:
|
||||
1. 只支持 `type:'comment'`,不支持 `smart_comment`
|
||||
2. 没有视频分析预览 — 填了链接直接执行,用户不知道会发什么评论
|
||||
3. 语料选择只有硬编码的下拉("通用/科技/生活/美食/娱乐"),不反映后端实际的行业池
|
||||
4. 每个视频×每个账号发一次 `/ops/run`,效率低(N 个账号×M 个链接 = N×M 次 API 调用)
|
||||
|
||||
**需要改为**:
|
||||
|
||||
```
|
||||
┌───────────────────────────────────────────────────┐
|
||||
│ 💬 智能评论(新版) │
|
||||
│ │
|
||||
│ [账号选择器] │
|
||||
│ │
|
||||
│ 视频链接: [textarea 每行一个] │
|
||||
│ │
|
||||
│ 方向: [称赞/提问/共鸣/感慨] 语料: [自动/行业/万能] │
|
||||
│ │
|
||||
│ [▶️ 分析视频] [▶️ 直接执行] │
|
||||
│ │
|
||||
│ ── 分析结果预览 ── │
|
||||
│ url1 → [health] "医生讲得很清楚..." [✏️ 修改] │
|
||||
│ url2 → [general] "博主说得很对..." [✏️ 修改] │
|
||||
│ url3 → [health] "这个方子很实用..." [✏️ 修改] │
|
||||
│ │
|
||||
│ 全部 3 个视频分析完成,预计分发 20 个账号 │
|
||||
│ [✅ 确认并分发] │
|
||||
└───────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**具体改动**:
|
||||
| 改动 | 说明 | 工作量 |
|
||||
|:-----|:------|:-------|
|
||||
| 新增分析按钮 + 预览区 | 先调 `smart_comment` 只分析不分发,返回预览 | ~80行 |
|
||||
| 预评论可编辑 | 用户可在预览区修改每条评论后确认 | ~30行 |
|
||||
| 行业标签显示 | 每个视频分析后显示 `[health]` 或 `[general]` 标签 | ~10行 |
|
||||
| 语料下拉从后端动态加载 | 从 `/matrix/corpus` 接口读取实际分类列表 | ~15行 |
|
||||
| 批量提交 | 分析完的一次性 `POST /ops/run` 全部账号×全部URL | ~20行 |
|
||||
| **合计** | | **~155行** |
|
||||
|
||||
---
|
||||
|
||||
### 2.3 语料库(matrix-corpus.js)— ❌ 需要大改
|
||||
|
||||
**当前现状**:
|
||||
- 573 行,三标签(1D 分类 / 2D 场景 / 3D 多轮)
|
||||
- 分类显示:分类名 + 权重 + 启用状态 + 评论列表
|
||||
- 添加/批量导入/删除
|
||||
- **缺少**:`accessible` 行业标签显示和管理
|
||||
|
||||
**需要改为**:
|
||||
|
||||
```
|
||||
┌───────────────────────────────────────────────────┐
|
||||
│ 📚 语料库 │
|
||||
│ 8 个分类 · 2 个行业池 · 156 条评论 │
|
||||
│ │
|
||||
│ ┌─ 行业过滤 ──────────────────────────────────────────┐
|
||||
│ │ [全部] [万能池] [大健康池] [科技池] [美食池] │
|
||||
│ └────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌─ 大健康称赞 ──── accessible: [health] ───────────┐ │
|
||||
│ │ weight: 30 | enabled: true │ │
|
||||
│ │ "医生讲得很清楚,通俗易懂" [编辑] [删除] │ │
|
||||
│ │ "这个方子很实用,收藏了" [编辑] [删除] │ │
|
||||
│ │ [+ 添加评论] │ │
|
||||
│ └────────────────────────────────────────────────────┘ │
|
||||
```
|
||||
|
||||
**具体改动**:
|
||||
| 改动 | 说明 | 工作量 |
|
||||
|:-----|:------|:-------|
|
||||
| 行业池过滤标签 | 在分类列表上方加 accessible 过滤按钮 | ~20行 |
|
||||
| accessible 标记显示 | 每个分类显示 `accessible: ["health"]` 或 `accessible: ["*"]` | ~15行 |
|
||||
| 行业池管理入口 | 添加/编辑分类时可选"允许哪些行业访问" | ~30行 |
|
||||
| 行业池 vs 万能池分离显示 | 万能池标签(称赞/提问/共鸣)显示在独立区域 | ~20行 |
|
||||
| 删除功能修复 | 当前删除按钮可能不工作(查下 delete 端点) | ~10行 |
|
||||
| **合计** | | **~95行** |
|
||||
|
||||
---
|
||||
|
||||
### 2.4 账号中心(accounts-center.js)— 中改
|
||||
|
||||
**当前现状**:
|
||||
- 797 行,账号列表 + 批量操作 + 状态汇总
|
||||
- 批量操作:采集/登录/评论/养号
|
||||
- 评论按钮跳转到 `matrix-comment.js`
|
||||
- **缺少**:industry 字段显示、smart_comment 批量操作
|
||||
|
||||
**需要改为**:
|
||||
|
||||
| 改动 | 说明 | 工作量 |
|
||||
|:-----|:------|:-------|
|
||||
| 账号列表增加 industry 列 | 显示 health/general 标签 | ~15行 |
|
||||
| 按 industry 过滤 | 下拉选择 health/general/全部 | ~15行 |
|
||||
| 批量操作新增"智能评论" | 弹出链接输入+方向+分析预览对话框 | ~60行 |
|
||||
| **合计** | | **~90行** |
|
||||
|
||||
---
|
||||
|
||||
### 2.5 互动操作(matrix-interact.js)— 小修
|
||||
|
||||
**当前现状**:
|
||||
- 500 行,有三个 tab(评论/点赞/关注)
|
||||
- 评论 tab 有 corpus 浏览器 + 关键词匹配
|
||||
- 评论模式下拉:`comment` / `search_browse` / `reply`
|
||||
- **缺少**:smart_comment 模式
|
||||
|
||||
| 改动 | 说明 | 工作量 |
|
||||
|:-----|:------|:-------|
|
||||
| smart_comment 模式选择 | 在模式下拉加"智能评论"选项 | ~10行 |
|
||||
| 方向选择与行业匹配 | 如果选了行业池,自动过滤可选方向 | ~15行 |
|
||||
| **合计** | | **~25行** |
|
||||
|
||||
---
|
||||
|
||||
### 2.6 执行管道组件(execution-pipeline.js)— ❌ 废弃
|
||||
|
||||
**当前现状**:
|
||||
- 300 行,但 **不被任何视图引用**
|
||||
- 搜索 `execution-pipeline.js` 的引用:0 个视图 import
|
||||
- 有 double `/api` 前缀 bug(line 20 `const API = '/api'`,line 146 `api('/api/ops/...')` → `/api/api/ops/...`)
|
||||
|
||||
| 处理 | 说明 |
|
||||
|:-----|:------|
|
||||
| 标记为废弃 | 不移除文件,但在顶部加注释说明 |
|
||||
| 保留未来用 | 如有重构计划可复用,但当前不需要修 |
|
||||
|
||||
---
|
||||
|
||||
### 2.7 命令历史(matrix-commands.js)— 小修
|
||||
|
||||
**当前现状**:
|
||||
- 221 行,显示历史命令列表
|
||||
- 调 `/ops/status` 获取
|
||||
|
||||
| 改动 | 说明 | 工作量 |
|
||||
|:-----|:------|:-------|
|
||||
| 显示 priority 列 | 区分 P0/P1/P2 任务 | ~10行 |
|
||||
| 显示 industry 列 | 如果任务包含 industry 信息 | ~5行 |
|
||||
| **合计** | | **~15行** |
|
||||
|
||||
---
|
||||
|
||||
## 三、修改优先级
|
||||
|
||||
| 优先级 | 视图 | 工作量 | 原因 |
|
||||
|:-------|:------|:-------|:-----|
|
||||
| **P0** | `matrix-comment.js` | ~155行 | **核心功能**: 智能评论的前端入口,用户直接交互 |
|
||||
| **P1** | `matrix-corpus.js` | ~95行 | **体验提升**: 行业池管理,让用户能自定义语料 |
|
||||
| **P1** | `accounts-center.js` | ~90行 | **效率提升**: 批量智能评论入口 |
|
||||
| **P2** | `matrix-interact.js` | ~25行 | 补充优化 |
|
||||
| **P2** | `ops-command.js` | ~55行 | 已有基础功能,补细节 |
|
||||
| **P2** | `matrix-commands.js` | ~15行 | 显示优化 |
|
||||
| - | `execution-pipeline.js` | 0 | 废弃不修 |
|
||||
|
||||
**总计工作量**: ~435 行改动。
|
||||
|
||||
---
|
||||
|
||||
## 四、smart_comment 前端交互流程
|
||||
|
||||
```
|
||||
用户进入「定向评论」页面
|
||||
│
|
||||
├─ 选择账号(账户选择器)
|
||||
├─ 填写视频链接(textarea,每行一个)
|
||||
├─ 选择方向(称赞/提问/共鸣)
|
||||
└─ 选择语料(自动/行业匹配/指定分类)
|
||||
│
|
||||
▼
|
||||
点击「分析视频」
|
||||
│
|
||||
▼
|
||||
前端调 POST /api/ops/run {type:"smart_comment", accounts: [只取1个], params:{urls, direction, preview:true}}
|
||||
↓ 后端 VideoAnalyzer 分析
|
||||
↓ 返回 {url: {title, industry, comment}}
|
||||
│
|
||||
▼
|
||||
前端显示分析结果预览
|
||||
┌─────────────────────────────────────────┐
|
||||
│ url1 → [health] "医生讲得很清楚..." [✏️]│
|
||||
│ url2 → [general] "博主说得很对..." [✏️]│
|
||||
└─────────────────────────────────────────┘
|
||||
用户可逐条修改预评论
|
||||
│
|
||||
▼
|
||||
点击「确认并分发」
|
||||
│
|
||||
▼
|
||||
调 POST /api/ops/run {type:"smart_comment", accounts:[全部], params:{urls, direction, comments:{url:预评论}}}
|
||||
↓
|
||||
后端直接拆解 → 打包 → API 分发到各机 guardd
|
||||
│
|
||||
▼
|
||||
前端切换到指挥台,显示各机队列状态
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 五、预审/修改流程的关键设计
|
||||
|
||||
**关键设计点:用户在分发前可以看到并修改每条预评论**
|
||||
|
||||
```javascript
|
||||
// 分析结果数据结构(前端存储)
|
||||
let previewData = {
|
||||
urls: {
|
||||
"https://v.douyin.com/xxx": {
|
||||
title: "胃镜到底疼不疼",
|
||||
industry: "health",
|
||||
comment: "医生讲得很清楚,通俗易懂" // 用户可编辑
|
||||
},
|
||||
"https://v.douyin.com/yyy": {
|
||||
title: "苏州美食探店",
|
||||
industry: "general",
|
||||
comment: "博主说得很对" // 用户可编辑
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// 用户编辑预评论后,确认分发
|
||||
async function confirmDistribute() {
|
||||
// 收集所有预评论(含用户修改后的)
|
||||
const comments = {};
|
||||
for (const [url, data] of Object.entries(previewData.urls)) {
|
||||
comments[url] = data.comment;
|
||||
}
|
||||
// 一次性分发
|
||||
await apiRequest('/ops/run', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
type: 'smart_comment',
|
||||
accounts: selectedAccounts,
|
||||
params: { urls: Object.keys(comments), comments, direction }
|
||||
})
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 六、调整汇总工作量
|
||||
|
||||
| 视图 | 当前行数 | 新增行数 | 总行数 |
|
||||
|:-----|:---------|:---------|:-------|
|
||||
| `matrix-comment.js` | 99 | +155 | 254 |
|
||||
| `matrix-corpus.js` | 573 | +95 | 668 |
|
||||
| `accounts-center.js` | 797 | +90 | 887 |
|
||||
| `ops-command.js` | 413 | +55 | 468 |
|
||||
| `matrix-interact.js` | 500 | +25 | 525 |
|
||||
| `matrix-commands.js` | 221 | +15 | 236 |
|
||||
| **Total** | **2603** | **+435** | **~3038** |
|
||||
Reference in New Issue
Block a user