Files
MediaCrawler/mac-agent-os-main/03_knowledge/99_system/AgentOS-原子操作体系-v2_副本2/日志-2026-06-20.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

10 KiB
Raw Blame History

2026-06-20 工作日誌

00:00-00:30 — 执行状态显示细腻度升级

背景

用户反馈 Dashboard 侧边栏的执行历史区块只显示"进程运行中"/"进程已结束"两种状态,但后端状态机有10种状态。

修改内容

  • 后端 (services/command_bus.py): CommandStatus 枚举定义 10 种状态:queued / preflighting / preflight_failed / dispatching / running / completed / failed / timed_out / crashed / cancelled ✅ 已有
  • 前端 (frontend/src/modules/matrix_views.js): 重写 loadExecutionHistory() 函数:
    • 新增 STATUS_MAP 常量,每种状态映射到独立图标+颜色+中文标签+分组
    • 顶部显示各状态的实际数量标签(不合并分组)
    • 每台机器显示 ok/active/fail 细分(不再只看完成率)
    • 每条执行记录显示:状态标签 | 机器 | 账号 | 消息 | 耗时 | 时间
    • 格式化的耗时显示(s/m 自适应)
    • Vite build 完成,hash 更新为 index-BhCDf8FF.js
  • 无需重启服务(静态文件在磁盘上实时读取)

00:30-01:00 — 信息采集全链路断点分析(L1→L5)

背景

用户反馈信息采集页面点击「采集选中」后没有获取到内容。

分析结论

断点在 L1(登录检测),不是数据回传问题:

  • 所有 recent collect log 都显示 ensure_login 返回 "unknown" → 账号被跳过
  • 实际 douyin_134 有 3 个 session cookie(有效登录态)但 DOM 锚点检测不到
  • 旧版 collect_batch_runner.py 用不同检测逻辑能正确识别,新版 LoginStateMachine._detect() 只查 DOM 锚点失败

L1 修复

  1. 抖音 logged_in 锚点从 2 个扩展到 9 个
  2. 新增 Cookie 兜底检测 — DOM 检测失败后用 page.context.cookies() 检查 sessionid/token
  3. 新增页面标题检测 — "xxx的抖音" = 已登录,"记录美好生活" = 未登录
  4. _recover_cookie() 改为导航到 user/self — 不再只刷新首页,强制触发登录态

L1→L5 测试验证

  • L1: ✅ 登录检测通过(dl/fix-recover-cookie -> 进入蓝图执行)
  • L2: ✅ 蓝图引擎启动,到达 check_verify_dialog 钩子
  • L3: ✅ CommandBus dispatch → status:"accepted", PID=32964
  • L4: ✅ API /api/ops/status 正常返回
  • L5: ✅ 前端可通过 API 获取(等待下次 build)
  • 次要问题:douyin_test 触发 SMS 验证弹窗导致执行卡住(已有钩子但 _recover_sms 阻塞)

文档更新

  • FEDERATION_GUIDE.md 新增「十一、五层执行架构 (L1–L5)」完整文档
  • 更新 4.4 登录状态机说明,记录 2026-06-20 修复细节
  • 合并 4.4/4.5 多机账号管理部分(之前有格式错误)

09:00-16:30 — 登录状态机重构 + 全场景验证通过

背景

  • 14:00 用户提供阿里百炼 API key,配置 vision_bridge.py 远程视觉支持(DashScope qwen-vl-plus)
  • 15:00-16:20 反复调试抖音登录,逐个修复问题

修复清单

  1. 检测器误判 logged_in — 移除 [data-e2e="user-avatar"] 锚点(视频创作者头像也匹配)
  2. 增加文本检测 — body.innerText 检查"未登录"和"粉丝/关注"关键词
  3. 登录按钮被浮层拦截 — JS fallback el.click() 绕过 Playwright 可见性检查
  4. 手机号为空 — 添加 _ensure_phone() 检查当前值,空则重填
  5. 短信验证码取旧码 — 改为直接调用 ApiSMSHandler._fetch_messages() + 过滤 id > min_id
  6. 登录按钮是"确认登录"不是"登录" — 多文本匹配

验证结果(三种场景全通过)

  • 全新登录: detect→点登录→填手机→获取验证码→登录→douyin_read_profile 9步 ✅
  • 短期过期: detect→JS点登录→JS点一键登录→验证码→确认登录→douyin_read_profile 9步 ✅
  • 已登录: detect→logged_in→直接执行蓝图 ✅

代码清理

  • login_state_machine.py 重构为三组件架构(PlatformDetector / RecoveryChain / LoginManager)
  • SmsRecovery 限制仅小红书使用(抖音由 DouyinLoginRecovery 处理)
  • cdp_connector.py close() 三层兜底修复 Camoufox stop() 缺失
  • mc/cli.py setup_log() 加 logging.basicConfig 修复日志不输出
  • 归档 2 个 export_* 蓝图到 _archive/
  • FEDERATION_GUIDE.md 更新登录状态机章节 + 蓝图清单

16:30-18:10 — 小红书登录修复 + 全场景验证通过

修复清单

  1. SmsRecovery 调用错版本 — 之前调 sms_login(抖音版),改为直接调 xhs_login(小红书6位框版)
  2. XhsDetector cookie 误判 — 移除 cookie 直接返回 logged_in
  3. xhs_login.is_logged_in() 太松 — 改为严格匹配 + 登录面板检测
  4. 步骤顺序错误 — 「协议同意处理」移到点登录后
  5. "同意并继续"按钮文字 — 改为「同意并继续」,class 为 div.foot-btn
  6. 缺少 oauth-tip 切换 — 填手机号后需点 div.oauth-tip
  7. SmsRecovery 二次验证过严 — 移除重复验证,信任 xhs_login

验证结果(18:08 全新登录 8/8 成功)

✅ 昵称=橙子哥 | ID=254437248 | 关注=1 | 粉丝=6

两种平台验证状态

场景 抖音 小红书
全新登录 ✅ ✅
短期过期 ✅ 🔵
已登录 ✅ ✅

18:10-18:45 — 养号蓝图 v2.0 更新

基础修

  1. 冷却前缀匹配 — _get_cooldown() 去掉 xhs_/dy_/dy_ 前缀
  2. wait_watch 补到 xhs_ops — 使小红书养号蓝图可用
  3. 搜索 @random 支持 — douyin_ops + xhs_ops 均支持随机关键词

4个养号蓝图更新

蓝图 版本 步数 变化
douyin_daily v2.0 40 10个视频,1-2条评论,概率点赞/收藏
douyin_active_v1 v2.0 80 2次@random搜索+各6结果,50%评论率
xhs_daily v2.0 49 10篇笔记,1-2条评论,参照抖音
xhs_active_v1 v2.0 89 2次搜索+各6结果+关注,参照抖音

19:10-20:40 — 养号蓝图 v2.x 修复

抖音日常 v2.1 (最终通)

  • 根因: open_video 只单点不验证 + 蓝图未进详情页
  • 修复: open_video 双击+验证+焦点+回首页兜底
  • like/collect 改为键盘 z(非 DOM 点击)
  • 结果: 45步 39成功 6失败 ✅

修复清单

  1. douyin_ops._click_selector — 加 JS fallback(备用)
  2. douyin_ops.like — 键盘 z 为主线
  3. douyin_ops.open_video — 双击+验证+焦点+回首页
  4. douyin_daily蓝图 — 每视频前加 open_video
  5. xhs_ops — 补 wait_watch、go_back
  6. xhs_ops.xhs_click_note — 回首页兜底、返回 False
  7. engine._get_cooldown — 去前缀匹配

待测试

  • xhs_daily 小红书日常(需用户配合验证码)

20:40-21:40 — 抖音版面整理 + 录制验证

录制成果(2轮,共48步操作)

  • 第1轮: 弹窗模式完整操作(点赞z→评论x→收藏→关注g→下一页→首页→主页)
  • 第2轮: 搜索"美食"→结果操作 + 全屏详情页/video/xxx操作
  • 发现: 键盘快捷键(z/x/g/ArrowDown) 两种模式通用
  • 收藏按钮是SVG图标,非 data-e2e 选择器

蓝图整理(9→6个活跃)

状态 蓝图
✅ 保留 douyin_daily / active / comment / reply / search / read_profile
📦 归档 comment_test / search_browse / collect(_archive/ 保留旧版做参考)
↩️ 不删 _archive/12个旧蓝图保留不动

23:50 — 今日复盘与明日任务清单

今日底线(已通过验证)

  • douyin_read_profile: ✅
  • xiaohongshu_read_profile: ✅
  • 抖音登录(3场景): ✅
  • 小红书登录(全新登录): ✅
  • 抖音原子操作全测: 15/16 ✅(仅follow失败)

今日未解决的问题

1. post_comment(抖音)— 代码返回成功但实际没发

  • 根因: _do_execute 中 ok = await self.post_comment() 返回 'ok' 字符串,Python 视为 truthy,直接显示 sent
  • 实际: 注释输入框 .public-DraftEditor-content 点击→打字→Enter,但评论未出现在列表
  • 修复方向(已改未测): 加 send 按钮查找(发送/发布类名)+comment-list 文本验证,验证不通过返回 failed
  • 旧代码参考: archive/interactive_test.py 的 step_send_comment 和 matrix_modules/nurture/runner.py 的 _send_comment

2. follow(抖音)— 失败

  • 当前实现: page.keyboard.press("g") + _click_selector 查找关注按钮
  • 录制发现: 用户按 g 键关注/取消关注,键盘方法本身正确
  • 可能原因: 视频详情页中已关注作者,g 键变成取消关注

3. xhs_post_comment(小红书)— 完全没发出去

  • 根因: p.content-input 选择器找不到(CSS modules 添加 hash)
  • 录制数据: 正确路径是 → 笔记详情页滑到底部 → 找到 DIV[class*="inner"] 点击激活 → P.content-input 出现 → 填字 → BUTTON.btn.submit 发送
  • 但 p.content-input 始终匹配不到,尝试了 x 键/JS激活/scrollTo 等5种方式均失败
  • 明天方向: 用截图+视觉识别找输入框位置,或改用 Playwright getByPlaceholder

4. xhs_click_note 在 go_back 后失败

  • 笔记返回首页后 feed 未渲染完就找笔记,找不到
  • 方向: go_back 后加 2-3秒延迟

明日任务清单(优先级排序)

P0: 修抖音 post_comment 验证(已改代码,明天测试验证)
P0: 修抖音 follow(查 g 键是否被已关注状态干扰)
P0: 修小红书 post_comment(截图视觉分析找输入框)
P1: 修 xhs_click_note 后 feed 刷新延迟
P1: 修 xhs_like 选择器稳定性
P1: 抖音高活跃蓝图 douyin_active 测试
P1: 新建小红书 xhs_comment_on_post / xhs_search 蓝图
P2: 小红书高活跃蓝图 xhs_active 测试
P2: 双平台日常养号自动化定时任务

关键教训(以后不要犯)

  1. 录制数据要直接用(坐标/元素类名),不要加 is_visible() 等额外检查
  2. 抖音和小红书的操作不能通用(x 键开评论在抖音通,小红书不通)
  3. 代码返回 ✅ 不等于页面真的有反应,每种操作必须加验证
  4. post_comment 必须检查 comment-list 中是否出现刚发的文字
  5. 跑测试用"原子操作全测"蓝图(每个操作一次),不用养号蓝图(49步浪费时间)
  6. CSS modules 类名不可靠,优先用 text/placeholder/坐标
  7. 每次测试前先给路径让用户审查,确认再跑

补注: 2026-06-21 08:20 确认小红书 xhs_post_comment 测试通过 ✅