Files
MediaCrawler/mac-agent-os-main/archive_docs/matrix_docs/REFACTOR-PLAN.md
T
butubb 2112c1a870
Deploy VitePress site to Pages / build (push) Canceled after 0s
Deploy VitePress site to Pages / Deploy (push) Canceled after 0s
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 带网关原话 / 正常返回)。
2026-10-10 17:12:25 +08:00

191 lines
6.2 KiB
Markdown

# Matrix 养号系统 — 重构设计方案 v2.2
> 最后更新:2026-05-01
> 版本:2.2.0 (草案)
> 本文件为设计方案,待确认后再实施。
## 一、当前问题诊断
| # | 问题 | 根因 | 影响 |
|---|------|------|------|
| 1 | 退出时 Chrome 崩溃/恢复弹窗 | `os.kill(pid, 9)` 强行杀进程,未走正常关闭 | 下次启动弹恢复确认框 |
| 2 | 点赞/收藏永远失败 | 操作前未验证当前页面状态,直接在首页点按钮 | 操作无效果 |
| 3 | "11/11 完成"但什么都没做 | 没有操作后的锚点验证,异常也被吞了 | 误报成功 |
| 4 | 不知道当前在什么页面 | 没有页面状态跟踪器 | 操作错位 |
| 5 | 登录验证不可靠 | 只查了一个 `data-e2e` 选择器,页面不同状态结果不同 | 误判未登录 |
| 6 | 脚本散乱不可组合 | 每个测试脚本都重复写类似逻辑 | 维护成本高 |
## 二、架构设计
### 2.1 三层架构
```
┌─────────────────────────────┐
│ WorkBuddy 技能层 │ ← 对话触发
│ (SKILL.md + 养号指令) │
├─────────────────────────────┤
│ orchestrator 调度层 │ ← 智能选账号/蓝图/状态机
│ (yanghao_orchestrator.py) │
├─────────────────────────────┤
│ 原子操作层 (21个原子操作) │ ← 可组合、可验证
│ (AtomOps + 校验器) │
├─────────────────────────────┤
│ CDP连接器 + 浏览器管理 │ ← 优雅启停
│ (cdp_connector + browser) │
└─────────────────────────────┘
```
### 2.2 原子操作定义 (每个操作带前置校验 + 后置锚点)
```
每个原子操作 = (名称, 执行函数, 前置校验, 后置锚点, 超时, 重试次数)
例子:
"like" =
pre_check: 当前在视频播放器页, 点赞按钮存在
execute: 点击 [data-e2e="video-player-digg"]
post_check: 点赞数+1 或 按钮状态变化
timeout: 10s
retry: 2次
```
### 2.3 页面状态机
```
[首页 grid] ──点击视频──→ [视频播放器]
↑ │
│ ↓
│ [下滑/下一条]
│ │
│ ↓
│ [新视频播放器]
│ │
└─────── 返回首页 ──────┘
页面锚点:
grid 模式: 有 [data-e2e="alink-item"],无 video-player-digg
播放器模式: 有 [data-e2e="video-player-digg"]
搜索页: 有 [data-e2e="searchbar-input"]
登录态: 有 sessionid cookie + 特定 DOM 元素
```
### 2.4 浏览器优雅管理
```python
# 不要 kill -9,用正常关闭
browser_manager = BrowserManager()
await browser_manager.launch(account='douyin_01') # 启动
await browser_manager.close() # 正常关闭,不走 kill
await browser_manager.graceful_shutdown() # 先 SIGTERM,等待,再 SIGKILL
```
### 2.5 蓝图新格式 (带验证锚点)
```json
{
"id": "douyin_browse_v2",
"version": "3.0.0",
"steps": [
{
"step_id": 1,
"op": "goto_and_verify",
"args": {"url": "https://www.douyin.com/"},
"verify": {"mode": "page", "anchor": "alink-item"},
"on_fail": "retry(2)"
},
{
"step_id": 2,
"op": "open_video",
"args": {},
"verify": {"mode": "element", "selector": "[data-e2e='video-player-digg']"},
"on_fail": "try_search"
},
{
"step_id": 3,
"op": "wait_watch",
"args": {"seconds": 8},
"verify": {"mode": "state", "field": "video_playing", "expect": true},
"on_fail": "skip"
},
{
"step_id": 4,
"op": "like",
"args": {},
"verify": {"mode": "change", "selector": "[data-e2e='video-player-digg']", "attr": "class"},
"on_fail": "log_warn"
}
]
}
```
### 2.6 调度器设计
```python
class YanghaoOrchestrator:
"""养号调度器"""
async def run(self, account_id, blueprint_id):
"""执行一次养号"""
# 1. 校验账号配置
# 2. 校验蓝图
# 3. 启动浏览器 (优雅)
# 4. 登录校验
# 5. 逐步骤执行 (带验证锚点)
# 6. 生成报告
# 7. 关闭浏览器 (优雅)
async def verify_login(self):
"""多维度验证登录态"""
# cookie: sessionid 存在
# DOM: user-avatar 或 user-detail 可见
# 请求: 能获取推荐内容
```
### 2.7 接入 WorkBuddy 技能
在 `matrix/SKILL.md` 中新增触发词:
```yaml
triggers:
- 养号
- 运行养号
- 南方小马铃薯
- 次元时空的桃子
- 橙子哥
```
WorkBuddy 通过 Skill 工具加载后,**由我在对话中根据你的指令自动编排执行**,而不是写死脚本。
### 2.8 接入 agentos CLI
```bash
agentos yanghao # 交互选账号+蓝图
agentos yanghao --account douyin_01 # 指定账号
agentos yanghao --account douyin_01 --blueprint douyin_browse_v2 # 全指定
agentos yanghao --list # 列出账号和蓝图
agentos yanghao --status # 查看当前运行状态
```
### 2.9 跨机恢复
```
agent-sync/02_skills/matrix/ → 包含所有脚本和蓝图
agent-local/tools/matrix/ → 账号登录态、Cookies、Profiles
换机流程:
agentos init → 安装技能+目录
agentos restore backup.tar.gz → 还原登录态
agentos yanghao --status → 验证可用
```
## 三、实施计划(建议)
1. **阶段1**: 设计并实现 `AtomOps` 原子操作层(含前置校验+后置锚点)
2. **阶段2**: 实现 `BrowserManager` 优雅启停
3. **阶段3**: 实现 `PageState` 页面状态机
4. **阶段4**: 重写蓝图格式(v3.0.0),加入验证锚点
5. **阶段5**: 实现 `YanghaoOrchestrator` 调度器
6. **阶段6**: 接入 agentos CLI 和 WorkBuddy 技能
7. **阶段7**: 全面测试三账号 + 跨机恢复