feat(monitor): 抖音 Web 接口客户端 —— 绕开爬虫子进程,直接发 HTTP
Deploy VitePress site to Pages / build (push) Canceled after 0s
Deploy VitePress site to Pages / Deploy (push) Canceled after 0s

移植自 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:
2026-10-10 17:12:25 +08:00
parent 21ff01b894
commit 2112c1a870
1601 changed files with 367425 additions and 0 deletions
@@ -0,0 +1,372 @@
# 可行性规则库 — 技术优选层的规则源(v1.0 / 2026-10-02)
# =====================================================================
# 用途:
# 导演产出分镜后,capability_matcher 用本规则库做「技术需求 → 能力匹配 → 缺口报告」。
# 规则分三级:blocking(必须解决)/ warning(风险提示)/ info(建议)。
#
# 维护:
# 能力建设完成后改对应 capability_needs[].status(missing → ready),
# 技术方案检测到版本变化会自动标记「可升级」,无需改分镜。
# =====================================================================
version: '1.1'
updated: '2026-10-02'
# ── 引擎时长档位对照(规则 duration_over_single_limit 的判定依据)──────
# 本项目默认引擎=可灵;接入其他引擎时按此表调整上限
engine_duration_limits:
kling: {single_max: 10, slots: [5, 10], note: 可灵 kling-v3 档位 5s/10s}
wan: {single_max: 10, slots: [5, 10], note: 通义万相}
seedance_2_5: {single_max: 30, slots: [4, 30], note: '官方:单条 4–30s,无 1080p;超长模式 30–180s;延长累计 ≤60s'}
seedance_2_0: {single_max: 15, slots: [4, 15], note: '官方:单条 4–15s,可 1080p/4K(15s 时)'}
# ── 能力需求映射(缺口清单的来源)──────────────────────────────
# status: missing(能力目录中无对应实现)/ planned(已登记未实现)/ ready(可用)
capability_needs:
frame_chain:
name: 首尾帧衔接
capability_id: frame_chain
status: partial
note: 长镜头接续 / 无缝延续 / 跨生成单元拼接。
可行路径:可灵/万相首尾帧(kf2v) 或 分段生成+取尾帧作下一段参考。当前能力目录无此项。
expression_consistency:
name: 表情微管理
capability_id: null
status: missing
note: 跨镜表情延续(眼神/嘴部/眉宇一致)。当前仅有 expression_detail 字段靠提示词描述,
无独立能力;精细控制需接 ComfyUI 或专用表情迁移模型。
vfx_apply:
name: 视频特效
capability_id: vfx_apply
status: planned
note: 可灵 camera_control 已部分可用(环绕/子弹时间/慢动作/焦点锁定);更多特效待接入。
character_3d:
name: 3D 角色
capability_id: character_3d
status: planned
note: 混元3D,未接入。
comfyui_workflow:
name: ComfyUI 工作流
capability_id: comfyui_workflow
status: planned
note: RunningHub / ComfyDeploy,未接入。
lipsync:
name: 对口型
capability_id: lipsync
status: partial
note: 代码就绪(fal.ai Kling Lipsync),缺 fal.api_key;火山 OmniHuman 可用。
person_swap:
name: 人物置换
capability_id: person_swap
status: partial
note: 百炼 wan2.2-animate-mix 已校准(std/pro),待真实样片验证。
character_card_seven_dim:
name: 七维角色卡 + 三格出图
capability_id: character_lock
status: partial
note: '现有角色锁定(固定描述块+seed+参考图)已具备雏形;Seedance 方法论要求更严:
七维公式[年龄/种族+肤色质感+面部细节(≥3-4点)+眼神+发型+服装+体型/气质]、
三格出图(一张图三格=同一次噪声=同一个人;格2去头让全图唯一脸源=格1大特写)、
皮肤强制后缀"保留真实的微细毛孔与肌肤纹理"。待纳入角色生成器。'
voice_lock:
name: 声线锁
capability_id: voice_lock
status: ready
note: 'TTS 已可按角色固定音色;方法论要求更严:声线锁逐字复用、连近义词都不换、
外观变体(湿身/带伤/换装)不换锁;群演不逐人建档(人群是一个资产,超15人塌缩)。'
long_video_extend:
name: 超长/视频延长
capability_id: frame_chain
status: missing
note: 底片 ≤30s,单次延长 4–30s,累计 ≤60s(Seedance 2.5 特例通道)。依赖首尾帧衔接能力。
# ── 规则清单 ────────────────────────────────────────────────────
rules:
# ═══ 时长 / 接续 ═══
- id: duration_over_single_limit
name: 单镜时长超生成上限
level: blocking
nature: yellow
trigger: {type: shot_duration_over, value: 10}
problem: 单次视频生成上限 10 秒(可灵/万相档位 5s/10s)
action: 切成两条并在接缝声明接续(chain_from_prev),或压缩到 10 秒内
need: frame_chain
- id: duration_over_5s_complex
name: 超 5 秒且动作幅度大
level: warning
nature: yellow
trigger: {type: duration_and_motion, duration_over: 5, motion_in: [medium, large]}
problem: 长时长 + 大幅动作,角色变形/闪烁风险高
action: 优先 5 秒档;必要时拆分动作节拍,或改用 10 秒档并接受重试损耗
need: null
- id: text_exceeds_duration
name: 台词超出时长容量
level: warning
nature: yellow
trigger: {type: text_fit, chars_per_sec: 4.5}
problem: 台词字数按语速估算需要更长时间,会被截断或语速过快
action: 加长该镜时长(≤10s)或切分台词到下一镜
need: null
# ═══ 一致性需求(缺口驱动)═══
- id: need_frame_chain
name: 要求承接上一镜尾帧(长镜接续)
level: blocking
nature: yellow
trigger: {type: tech_flag, field: chain_from_prev, value: true}
problem: 当前无「首尾帧衔接」能力,无法保证无缝接续
action: 建设该能力(首尾帧 kf2v / 分段+尾帧参考),或改成硬切分镜
need: frame_chain
- id: need_expression_consistency
name: 要求跨镜表情一致
level: blocking
nature: yellow
trigger: {type: tech_continuity, field: expression, values: [must, prefer]}
problem: 无「表情微管理」能力,跨镜表情延续不可控
action: 建设表情一致性能力(ComfyUI/表情迁移),或降级为"不要求"
need: expression_consistency
- id: need_character_consistency
name: 要求跨镜角色一致
level: info
nature: yellow
trigger: {type: tech_continuity, field: character, values: [must, prefer]}
problem: ""
action: 使用「角色锁定」能力(固定描述块 + seed + 参考图绑定)
need: null # 已有能力,满足
- id: need_location_consistency
name: 要求跨镜场景一致
level: info
nature: yellow
trigger: {type: tech_continuity, field: location, values: [must, prefer]}
problem: ""
action: 使用场地资产 + 首帧参考(部分依赖 frame_chain 才能完全无缝)
need: null
# ═══ 特效 / 运镜 / 特殊需求 ═══
- id: need_vfx
name: 需要视频特效
level: warning
nature: yellow
trigger: {type: shot_or_need, shot_type: vfx, need_keywords: [特效, 子弹时间, 环绕, 慢动作, 焦点锁定, 变速]}
problem: vfx_apply 能力为 planned,仅可灵 camera_control 部分可用
action: 用可灵运镜参数承载(环绕/子弹时间/慢动作/焦点锁定),其余待能力建设
need: vfx_apply
- id: camera_complex
name: 复杂运镜调度
level: warning
nature: yellow
trigger: {type: tech_flag, field: camera_difficulty, value: complex}
problem: 复杂调度(环绕/跟拍/多段运镜合一)单次生成成功率低
action: 拆成多个简单运镜的条,或接受重试损耗
need: null
- id: need_hand_closeup
name: 手部特写/精细手部动作
level: warning
nature: yellow
trigger: {type: need_keywords, keywords: [手部特写, 手部动作, 拿取细节, 手指]}
problem: 手部是最易变形区域,特写下更明显
action: 降低手部占比或改为中近景;必要时接受局部重绘
need: null
- id: need_on_screen_text
name: 画面内文字/LOGO
level: warning
nature: yellow
trigger: {type: need_keywords, keywords: [画面文字, 字幕特效, LOGO, 招牌, 书籍文字]}
problem: 视频模型对画面内文字渲染不稳定(易乱码)
action: 文字改为后期叠加(字幕能力),画面内避免依赖文字
need: null
- id: need_multi_person
name: 多人同框互动
level: warning
nature: yellow
trigger: {type: need_keywords, keywords: [多人, 双人互动, 对话双方, 群像]}
problem: 多人一致性/交互稳定性差
action: 减少同框人数或用正反打(单人对镜)替代同框
need: null
# ═══ 合规红线 ═══
- id: real_person_authorization
name: 真人肖像未授权
level: blocking
nature: red
trigger: {type: manual_check}
problem: 使用真人肖像(含真人参考图/人物置换)必须有书面授权
action: 在授权登记中登记后放行;未授权不得生成
need: null
- id: platform_restricted
name: 平台禁限内容
level: blocking
nature: red
trigger: {type: manual_check}
problem: 暴力/色情/政治敏感等平台禁限内容会被拒绝或封号
action: 停下报告用户,不自行改写规避
need: null
# ══════════════════════════════════════════════════════════════
# v1.1 追加 — 来自 Seedance 方法论卡片(hongxian / moxinglei / leiqu)
#
# nature 三色分性质(对应 Seedance 审核体系):
# red = 绝对红线(法律/平台硬禁)→ 命中即 blocking,不许生成
# yellow = 平台误杀规避(工程约束,不是法律红线)→ 只标「建议改 + 通过率风险」,不判 FAIL
# blue = 投放侧合规(内容能生成,卡的是上线手续)→ 只标「前置事项 + 责任方=user」
# ══════════════════════════════════════════════════════════════
# ── 模型雷 · B 动态预演 ──
- id: mine_identity_drift_seam
name: 条缝/镜缝身份漂移(变脸)
level: warning
nature: yellow
trigger: {type: need_keywords, keywords: [换装, 湿身, 淋雨, 受伤, 带伤, 血迹, 变装]}
problem: 外观状态变化处若未声明接缝状态,跨条/跨镜会变脸漂移
action: 在接缝声明**结束状态五字段**(位置 / 朝向 / 持物 / 动作动势 / 情绪),下一条按此承接
need: null
- id: mine_conflicting_actions
name: 一镜叠加互斥动作
level: warning
nature: yellow
trigger: {type: need_keywords, keywords: [一边, 同时又, 同时进行, 并同时]}
problem: 一条内并行多个互斥动作 → 模型取平均,动作糊成一片
action: 拆成两条(条一个目的),或只保留承重动作
need: null
- id: mine_abstract_emotion
name: 情绪单词化(漫画化/死面)
level: warning
nature: yellow
trigger: {type: need_keywords, keywords: [悲伤, 愤怒, 开心, 绝望, 恐惧, 震惊, 兴奋]}
problem: 只写情绪形容词 → 模型输出夸张漫画化表情或死面
action: 改写成**可见行为 + 微表情**(眼神/嘴部/眉宇 + 具体动作)
need: null
- id: mine_crowd_collapse
name: 群像人数超稳定区(塌缩)
level: warning
nature: yellow
trigger: {type: need_keywords, keywords: [人群, 群像, 人群涌动, 众多, 上百, 几十人, 十多人]}
problem: 主体稳定区 1–5 人;群像写实数或超 15 人会塌缩/相似脸
action: 人群作**一个资产**不逐人建档;只写身体质量与局部,不写人数
need: null
- id: mine_precise_lipsync
name: 精确口型与长台词
level: warning
nature: yellow
trigger: {type: need_keywords, keywords: [口型, 对口型, 说话特写, 长篇独白]}
problem: 口型三前提:短句 / 正脸 / 中景;单句超 20 词未拆则口型必崩
action: 拆短句,改正脸中景,或后期对口型(lipsync 能力)
need: lipsync
- id: mine_open_motion
name: 开放运动无终点
level: warning
nature: yellow
trigger: {type: need_keywords, keywords: [走去, 跑向远方, 走出画面, 渐行渐远, 无限延伸]}
problem: 开放式运动缺终点锚 → 模型卡死或抽搐
action: 给运动一个**可见终点/落点**,或明确写出结束状态
need: null
# ── 可行性雷 · 11 卡要点 ──
- id: feas_precise_quantity
name: 精确数量承重
level: warning
nature: yellow
trigger: {type: need_keywords, keywords: [三只手, 五个人, 恰好, 正好, 数量精确, 一共, 整齐排列]}
problem: 精确数量是模型弱项,数量承重易错
action: 降低数量承重(改"几个"),或降档/标注放行
need: null
- id: feas_sustained_contact
name: 持续精确接触点
level: warning
nature: yellow
trigger: {type: need_keywords, keywords: [抵住, 贴着, 接触点, 手指按, 刀抵, 针尖, 精确触碰]}
problem: 持续精确接触(刀抵喉/针尖等)易穿模错位
action: 用**解剖位正向描述 + 对比双写**("刀锋贴在颈侧皮肤上"),或降档为不接触
need: null
- id: feas_special_physics
name: 特殊物理(硬机械/液体火烟粒子)
level: warning
nature: yellow
trigger: {type: need_keywords, keywords: [爆炸, 火焰, 烟雾, 水流, 液体, 机械结构, 齿轮, 碎片]}
problem: 特殊物理模拟不稳定(硬机械穿模、流体/粒子失控)
action: 缩短其出现时长、减少精细交互,或改用后期特效叠加(vfx)
need: vfx_apply
- id: feas_large_group_scale
name: 大规模群体场面(卡01)
level: warning
nature: yellow
trigger: {type: need_keywords, keywords: [大军, 战场, 广场人群, 集会, 阅兵, 无数人]}
problem: 稳定区 1–5 主体;大规模群体必然塌缩
action: 用**局部特写 + 数量暗示**(旗帜/脚步/背影)替代全景实数
need: null
# ── 红线 · 三色体系 ──
- id: red_copyright_ip
name: 版权 IP(🔴 绝对红线)
level: blocking
nature: red
trigger: {type: need_keywords, keywords: [动漫角色, 影视角色, 游戏角色, 明星, IP形象, 知名卡通, 品牌logo, 商标]}
problem: 使用受版权保护的 IP/角色/品牌形象 → 侵权(判例:投喂《斗破苍穹》角色形象被判赔 5 万)
action: 停止;改为原创形象或取得授权
need: null
- id: red_false_info
name: 虚假信息 / 伪证类(🔴 绝对红线)
level: blocking
nature: red
trigger: {type: need_keywords, keywords: [去水印, 去角标, 去AI标识, 消除标识, 伪街拍, 伪监控, 伪新闻, 伪造现场]}
problem: 伪造真实性/去除 AI 标识属虚假信息红线
action: 停止;不得用于伪造真实场景或消除 AI 标识
need: null
- id: red_real_person
name: 真人肖像(🔴 绝对红线)
level: blocking
nature: red
trigger: {type: manual_check}
problem: 使用真人肖像(含真人参考图 / 人物置换 / 明星脸)须书面授权
action: 在授权登记中登记后放行;未授权不得生成(责任方=user)
need: null
- id: yellow_platform_false_kill
name: 平台误杀规避(🟡 工程约束)
level: warning
nature: yellow
trigger: {type: manual_check}
problem: 密集血腥特写 / 敏感历史题材 / 动漫风低拦截阈值 等易被平台误杀
action: 标注「建议改 + 通过率风险」;**不判 FAIL、不置 blocking**(除非同时踩某条 🔴)
need: null
- id: blue_delivery_compliance
name: 投放侧合规(🔵 前置手续)
level: info
nature: blue
trigger: {type: manual_check}
problem: 内容可生成,卡的是上线手续(网络剧片发行许可/备案/分级)
action: 标注「投放前置事项 + 责任方=user」;**不判 FAIL、不置 blocking**
need: null
- id: green_protect
name: 绿档保护(不许以「可实现性」砍)
level: info
nature: yellow
trigger: {type: need_keywords, keywords: [长场, 长镜头调度, 夜戏, 逆光, 剪影, 情绪重头戏, 正反打]}
problem: 这些是本方法论的**绿档**内容,不得以技术可实现性为由删除
action: 优先保内容;技术手段不足时按「改写 → 降档 → 标注放行 → 待决」处理,而不是砍内容
need: null
# ── 处置四类说明(供前端提示) ──
# 处置顺序:改写(首选)→ 降档(保画面类型压复杂度)→ 标注放行 → 待决(用户拍板)
# 原则:能改写就不降档,能降档就不删。