docs: 更新 README 和安装文档,新增 yt-studio-groupid-lookup 技能说明

This commit is contained in:
2026-08-24 14:25:59 +08:00
parent bcfe0f4a29
commit 5bc318e0cb
9 changed files with 750 additions and 21 deletions

View File

@@ -0,0 +1,124 @@
---
name: "yt-studio-groupid-lookup"
description: "把一批群组名批量解析为 entity_id即 groupId并标注其归属的内容所有者。围绕 scripts/lookup_groups.py用「套件回放」search_groups 接口:在线捕获鉴权套件后并发查询,或离线用已存套件回放。当用户给出群组名清单、要查找/映射/匹配群组的 groupId 或 entity_id、确认某群组属于哪个所有者/内容管理器、排查群组 ID 查不到或回放 401 时使用。"
---
# 群组名解析为 entity_id脚本版
把群组名 --> `groupId`(即 explore URL 里的 `entity_id`),并标注归属的内容所有者。底层执行 `scripts/lookup_groups.py`。核心是「套件回放」:**套件**(捕获页面的完整鉴权头 + 请求体模板),**回放**(重发 `search_groups`,只改 `query`),因手写请求必 401。
## 何时使用
- **批量解析**:用户有一批群组名,要拿到每个名字对应的 groupId / entity_id。
- **归属确认**同名群组可能多个所有者都有需要确认某群组属于哪个内容管理器ownerId + 显示名)。
- **建 URL 前置**:要生成 explore 报告 URL但清单里只有群组名、没有 entity_id。
- **排查失败**:回放遇到 401 / 查不到 / 大小写差异,需要定位修复。
## 领域词汇
- **套件Bundle**:从页面捕获的一次 `search_groups` 请求 = 完整请求头(`Authorization: SAPISIDHASH...``Cookie``X-YouTube-Delegation-Context` 等)+ 请求体模板(含 `context.user.delegationContext`)。一个内容所有者一份。手写必 401唯一可靠来源。
- **回放Replay**:用套件重发 `search_groups`**只改 body 的 `query` 字段**,其余(尤其 delegation 语境)一律不动。
- **实体ID / groupId**:响应 `groupDatas[].groupId`,即 explore URL 的 `entity_id`(如 `NCy9C2QPQ1E`)。
- **精确命中**:响应当中存在 `displayName === 查询名` 的项,直接取它的 groupId命中即停不再往下查。
- **变体候选**:无精确命中时,接口仍可能返回前 5 个相近名,写入结果「备注」列供人工复核。
## 脚本与依赖
- 脚本:`scripts/lookup_groups.py`(本技能目录下;若缺失,用 SearchCodebase 按 `lookup_groups.py` 定位)。
- 依赖playwright、requests、openpyxl 已统一在根 `pyproject.toml` 声明(`uv sync` 自动装),环境准备见 `uv-env-setup` 技能。
- 登录态必须已存在:脚本不登录,只复用已登录 YouTube Studio 会话,否则跳 Google 登录页。
## 选择运行分支
| 你的情况 | 分支 | 关键参数 |
|---|---|---|
| 要在线拿新套件并立即查询 | 分支 A捕获+回放 | `--url` + `--names` |
| 套件已存盘(`--save-bundles` 产物) | 分支 B离线回放 | `--bundles` + `--names` |
| 只想捕获/校验套件,先不查 | 分支 C仅捕获 | `--url`(不带 `--names` |
| 无浏览器/网络,验脚本逻辑 | 分支 D自测 | `--selftest` |
多所有者的分三种做法(三者都对应分支 A`--url` 重复传多次、或 `--url ... --save-bundles bundles.json` 先存盘、或下次直接用 `--bundles bundles.json`(分支 B
## 工作流
### 步骤 0环境与自测分支 D
```bash
uv run python scripts\lookup_groups.py --selftest
```
**完成判据**:打印 `selftest OK`,退出码 0无需浏览器/网络)。
### 步骤 1确认登录态来源
复用已登录 YouTube Studio 的浏览器会话,否则跳 Google 登录页。与 `youtube-studio-csv-download` 同一套约定:
- 方式 A能关浏览器`--user-data-dir <目录> --channel chrome|msedge`,二者必须同品牌。
- 方式 B浏览器不能关`chrome.exe --remote-debugging-port=9222``msedge.exe --remote-debugging-port=9222`,再加 `--connect http://localhost:9222`
**完成判据**:得到任意一种可复用的登录态(用户数据目录路径,或调试端口号)。
### 步骤 2拿到所有者 URL 与群组名单
- 所有者 URL`studio.youtube.com/owner/<ownerId>/analytics?...`;脚本自动从 URL 路径 `owner/<id>``?o=<id>` 提取 ownerId不需手工填。
- 群组名单json / txt / csv / xlsx 均可,支持 `群组名称``group_name``实体名称``名称` 等列名,自动去重。(格式细节见 [references/input-guide.md](references/input-guide.md)
**完成判据**`--names` 指向的文件能被脚本解析出非空名单(列名可识别)。
### 步骤 3运行脚本
分支 A在线捕获 + 回放):
```powershell
# 单所有者
uv run python scripts\lookup_groups.py --url "<owner URL>" --names 名单.xlsx --channel chrome --user-data-dir "$env:LOCALAPPDATA\Google\Chrome\User Data"
# 多所有者:--url 重复;浏览器不能关就改用 --connect
uv run python scripts\lookup_groups.py --url "<owner1 URL>" --url "<owner2 URL>" --names 名单.csv --connect http://localhost:9222 --save-bundles bundles.json
```
分支 B离线回放套件已存盘无需浏览器
```powershell
uv run python scripts\lookup_groups.py --bundles bundles.json --names 名单.json --out result.xlsx
```
分支 C仅捕获/校验套件,暂不查询):
```powershell
uv run python scripts\lookup_groups.py --url "<owner URL>" --save-bundles bundles.json
```
**关键行为**
- 打开页面后先**自动触发一次群组搜索**(猜搜索框);猜不中会提示「在浏览器顶部搜索框输入任意词并回车」,只需触发一次 `search_groups` 请求即可。
- 捕到请求后,脚本校验 `delegationContext.externalOwnerId` 与 URL ownerId 是否一致、鉴权头是否齐全(缺 Authorization/Cookie/delegation 是 401 根因,会在捕获时直接打警告)。
- 回放用线程本地 Session并发默认 8 线程)逐个名字 × 逐个所有者,**首个精确命中即停**。
**完成判据**:终端打印 `[输出] 精确命中 N/M -> <路径>`,退出码 0且生成结果文件。
### 步骤 4校验产物与处理未命中
- 结果列:`group_name / ownerid / owner_display / groupid / 备注``ownerid + owner_display` 标注群组归属的所有者。
- 未命中的名字会列在末尾 `[复核] 未命中 N 个`,其候选/线索在「备注」列。
- 处理变体:若备注里只有大小写/空格差异的候选,直接改用候选 groupId若跨所有者都命中以**精确 displayName** 为准核对归属;若名字疑似错字,用更短关键词(如品牌名)重跑一次。
**完成判据**:无 `HTTPxxx` / `ERR` 残留;每个群组要么有确定 groupId要么在备注列明确记录了候选或原因。
## 常用参数速查
| 参数 | 说明 |
|---|---|
| `--url` | 所有者分析页 URL可重复多所有者 |
| `--names` | 群组名单json / txt / csv / xlsx |
| `--bundles` | 已有套件 json离线回放或与 `--url` 捕获结果合并) |
| `--save-bundles` | 把套件写盘,供下次离线回放 |
| `--out` | 结果文件,默认 `group_entity_id_result.xlsx`,缺 openpyxl 自动回退 csv |
| `--max-workers` | 并发线程数,默认 8 |
| `--connect` | CDP 附加到已打开浏览器 |
| `--user-data-dir` / `--channel` | 用已登录用户数据目录启动 |
| `--owner-display` | 所有者显示名(可选,单 `--url` 时用于结果标注) |
| `--wait-seconds` | 等待手动触发搜索的最长秒数,默认 180 |
## 参考
- [名单与套件制作指南](references/input-guide.md):名单文件格式/列别名、套件 bundles.json 结构、多所有者、产物核对。
- [常见问题排查](references/troubleshooting.md):按 现象 → 原因 → 解决 逐条排查401、未登录跳转、捕获不到请求、查不到、CDP 连不上、channel 不匹配等)。