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,199 @@
# 创意矩阵配置(GapEngine)— 负面/正向/道具场景 + 生成参数
# =====================================================================
# 来源:GapEngine 设计(2026-10-02 讨论)原文内容,整理为可编辑配置。
#
# 用法:创意工坊的 ②负面矩阵 / ③正向矩阵 / ④道具场景 三个标签页读写本文件;
# ⑤生成&筛选 依据 negative 硬过滤、positive 加权、generation 控制条数。
# 维护:可直接编辑;也可以把不同模式另存为 presets 下的一套(如"肛肠科反差模式")。
# =====================================================================
version: '1.0'
updated: '2026-10-02'
# ── 生成参数 ──────────────────────────────────────────────
generation:
candidates_per_round: 30 # 每轮候选条数(默认 30,AI 按规则推荐一轮)
max_params_per_layer: 2 # 每层最多选中的参数数(原文约束;0 = 不限制)
min_params_total: 2 # 少于该数量无法计算缺口(原文 app.py 校验)
# ── 负面矩阵(勾选排除)────────────────────────────────────
# hard = 🔴 平台硬违禁:默认锁死,不参与创意(locked: true 表示不可放开)
# soft = 🟡 观众反感:默认全部排除,允许放开某一项来制造反差(relaxed: true 表示已放开)
negative:
hard:
- id: politics
name: 政治敏感
detail: 国家象征标志不规范使用、歪曲解读政策、不当关联政治事件营销
locked: true
- id: porn
name: 色情低俗
detail: 淫秽色情内容、性暗示、擦边球文案
locked: true
- id: violence
name: 暴力恐怖
detail: 血腥暴力、恐怖主义、教唆犯罪
locked: true
- id: gambling_drug
name: 赌博毒品
detail: 赌博、毒品、违禁药物
locked: true
- id: superstition
name: 迷信荒诞
detail: 封建迷信、荒诞不经的内容
locked: true
- id: false_claim
name: 虚假宣传
detail: 弄虚作假、夸大功效、绝对化用语("最""第一""国家级"等)
locked: true
- id: medical_violation
name: 医疗违规
detail: 医疗功效词、未标注"演绎"的诊疗场景、以医生身份带货
locked: true
soft:
- id: anxiety
name: 贩卖焦虑
detail: 容貌焦虑、年龄焦虑、职场内卷焦虑
relaxed: false
hint: 泰国广告的反差恰恰建立在"先制造焦虑,再反转消解"上——放开此项可做此类反差
- id: division
name: 制造对立
detail: 地域对立、性别对立、身份对立
relaxed: false
hint: 放开此项可做"对立→和解"的反转
- id: emotional_coercion
name: 情绪勒索
detail: '"不转不是中国人" "你忍心看着…" 等强制情感绑架'
relaxed: false
hint: 放开可做"反套路"嘲讽
- id: misery
name: 过度卖惨
detail: 医疗卖惨、贫穷卖惨、残障卖惨
relaxed: false
hint: 医疗题材放开此项,可做"惨到好笑"的反差
- id: petty_bourgeois
name: 小资情结
detail: 刻意精致、脱离现实的生活展示
relaxed: false
hint: 放开可做"精致破产"的反差
- id: caustic
name: 尖酸刻薄
detail: 以嘲讽弱者为乐、居高临下的幽默
relaxed: false
hint: 放开可做"刻薄者反被刻薄"的反转
- id: cunning_honest
name: 老实人精明
detail: 表面老实实则算计的叙事模式
relaxed: false
hint: 放开可做"精明者失算"的反转
- id: preachy
name: 油腻说教
detail: 居高临下的人生道理、爹味说教
relaxed: false
hint: 放开可做"说教者出丑"的反转
- id: exaggeration
name: 极端夸张
detail: 脱离物理常识的夸张表现
relaxed: false
hint: 泰国广告核心手法之一——放开此项才能做极限夸张,但需控制尺度
# ── 正向矩阵(勾选引入,命中时给缺口分加成)─────────────────
positive:
- id: warm_twist
name: 温情反转
detail: 先制造误解或冲突,结尾转向温暖
bonus: 10
- id: self_mockery
name: 幽默自嘲
detail: 角色嘲笑自己的处境,而非嘲笑他人
bonus: 8
- id: ordinary_hero
name: 平凡英雄
detail: 普通人做出不平凡的小事
bonus: 8
- id: anti_cliche
name: 反套路认知
detail: 颠覆观众对某类人的刻板印象
bonus: 12
- id: warm_stranger
name: 温暖陌生人
detail: 陌生人之间的善意互动
bonus: 8
- id: reconciliation
name: 和解与释然
detail: 冲突最终走向理解而非对抗
bonus: 10
# ── 道具变量库(勾选可用;AI 推荐 + 手动增选)────────────────
props:
- id: childlike
name: 童趣道具
examples: [卡通玩偶, 棒棒糖, 气球]
contrast: 严肃场景 × 童趣道具 = 荒诞温情
- id: tech
name: 科技道具
examples: [手机, 智能手表, 耳机]
contrast: 日常场景 × 科技介入 = 现代荒诞
- id: wealth
name: 财富符号
examples: [股票软件, 豪车钥匙, 名表]
contrast: 平凡角色 × 财富符号 = 身份反差
- id: medical
name: 医疗道具
examples: [病历本, 输液架, 病号服]
contrast: 常规道具 × 非常规使用 = 叙事转折
- id: daily
name: 日常小物
examples: [咖啡杯, 雨伞, 钥匙]
contrast: 日常物件 × 特殊时刻 = 情感锚点
- id: symbol
name: 象征物(隐喻用)
examples: [地震, 潮水, 风暴, 种子, 齿轮, 流水线, 监控, 牢笼, 笼中鸟, 茧, 飞蛾, 镜子, 雨伞, 闹钟, 门]
contrast: 抽象主题 × 具体物象 = 观众自己完成的那次替代
# ── 场景变量库 ─────────────────────────────────────────────
scenes:
- id: space
name: 空间反差
examples: [病房vs豪宅, 诊室vs演唱会]
contrast: 空间错位制造荒诞
- id: time
name: 时间反差
examples: [白天vs深夜, 术前vs术后]
contrast: 时间跳跃制造悬念
- id: weather
name: 天气反差
examples: [晴天vs暴雨, 室内vs室外]
contrast: 环境变化推动情绪转折
- id: social
name: 社交反差
examples: [独处vs人群, 熟人vs陌生人]
contrast: 社交密度变化制造戏剧张力
# ── 预设矩阵配置(多套可切换)──────────────────────────────
# 使用某套 preset 时,soft 项的 relaxed / positive 勾选 / props / scenes 按此覆盖。
presets:
- id: conservative
name: 保守模式(默认)
soft_relaxed: []
positive: [warm_twist, self_mockery]
props: []
scenes: []
- id: contrast
name: 反差模式
soft_relaxed: [exaggeration, anxiety]
positive: [warm_twist, anti_cliche]
props: [childlike, medical]
scenes: [space, time]
# ── 与六层参数的联动规则(供生成器参考)────────────────────
linkage:
- when: {layer: narrative, param: conflict_type, value: 认知反转}
recommend: {props: [childlike], note: 用童趣道具作为反转触发器}
- when: {layer: visual, param: shot_size, value: 特写}
recommend: {props: [daily], note: 用道具特写作为转场锚点}
- when: {layer: rhetoric, param: expression_mode, value: 暗喻}
recommend: {props: [symbol], note: 从象征物里挑一个作喻体,被比喻的事始终不出现}
- when: {layer: rhetoric, param: vehicle_source, value: 自然现象}
recommend: {props: [symbol], note: 自然类喻体:地震 / 潮水 / 风暴 / 干旱}
- when: {layer: rhetoric, param: mapping, value: 整体寓言}
recommend: {props: [symbol], note: 全片围绕一个喻体展开,不得中途切回写实}