Files
StudioLift/assets/skill-问题复盘与优化建议.md
Sidney Zhang 9020752eed feat(scripts): 添加 PEP 723 脚本元数据并修复 HTTP/2 伪头过滤问题
- 为 build_studio_urls.py 和 lookup_groups.py 添加 PEP 723 依赖声明
- 修复 HTTP/2 伪头导致 requests 抛 InvalidHeader 的问题
- 添加 CDP 端口连通性预检查及启动指引
2026-08-27 13:33:34 +08:00

152 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# StudioSkillsSet 四技能使用问题复盘与优化建议
> 记录日期2026-08-26
> 涉及技能:`uv-env-setup`、`yt-studio-groupid-lookup`、`yt-studio-url-builder`、`youtube-studio-csv-download`
> 数据链路:群组名 →(groupid-lookup)→ groupId →(url-builder)→ explore URL →(csv-download)→ CSV zip
---
## 一、结论速览
| 技能 | 是否遇到问题 | 问题是否已解决 | 是否需要优化 | 优化紧急度 |
|---|---|---|---|---|
| uv-env-setup | 是(命令不可用) | 是 | 是(轻) | 低 |
| yt-studio-groupid-lookup | 是(端口/登录/401/伪头) | 是 | 是 | 中 |
| yt-studio-url-builder | 否(但存在隐性前置依赖) | 是 | 是(轻) | 低 |
| youtube-studio-csv-download | 是(登录/按钮定位/base64 解码) | 是 | **是** | **高** |
整体结论4 个技能功能均跑通最终产物6 份 CSV zip全部有效。其中 `youtube-studio-csv-download` 暴露了 **2 处真实脚本缺陷**(导出按钮定位、`zippedData` 解码),是本次最需要回填到技能脚本的修复点。
---
## 二、uv-env-setup环境准备
### 问题 1`uv` 命令不被识别
- **现象**:执行 `uv --version``uv sync``The term 'uv' is not recognized`
- **为什么会出现**`uv` 刚安装,当前 PowerShell 会话的 PATH 未刷新;或者安装方式(如 `pip install uv`)没有把可执行文件加入 PATH。
- **解决方法**:改用 `python -m uv` 调用;或在后续会话中直接调用项目已有的 `.venv\Scripts\python.exe` 绕过 uv 代理。
- **如何避免**:安装后重开终端;或脚本执行统一改为"优先 `.venv\Scripts\python.exe` 直调,回退 `uv run`"。
### 问题 2已有 `.venv` 但缺 `pyproject.toml`
- **现象**:项目已存在 Python 3.12.6 的 `.venv`(内含 pandas/openpyxl/playwright但没有 `pyproject.toml`
- **为什么会出现**:原环境是手动 `pip install` 搭出来的,不是 uv 管理。
- **解决方法**:新建 `pyproject.toml` 声明依赖作为唯一事实来源,`uv sync` 复用现有 Python 生成 `uv.lock`
- **如何避免**:首次迁移到 uv 时先补 `pyproject.toml`,再 `uv sync`
**是否已解决**:是。环境最终就绪,三条自检(`import pandas/openpyxl/playwright``--selftest``--help`)通过。
---
## 三、yt-studio-groupid-lookup群组名 → groupId
### 问题 1Chrome 调试端口 9222 连不上
- **现象**`--connect http://localhost:9222` 连不上,报"无法连接到远程服务器"。
- **为什么会出现**Chrome 未以 `--remote-debugging-port=9222` 启动。
- **解决方法**:用带调试端口的命令重启 Chrome。
- **如何避免**:运行前先 `Invoke-WebRequest http://localhost:9222/json/version` 探测端口是否在线。
### 问题 2Chrome 进程未完全退出,调试端口参数被忽略
- **现象**:已带参数重启 Chrome但 9222 仍不通。
- **为什么会出现**:后台仍有 Chrome 残留进程,新启动实例的 `--remote-debugging-port` 被已运行实例"吞掉"Chrome 单实例复用机制)。
- **解决方法**:完全退出所有 Chrome 进程后再启动调试实例,或者改用独立 `--user-data-dir` 隔离启动。
- **如何避免**:启动前检测残留进程;或固定使用独立 profile 目录 + 调试端口。
### 问题 3回放请求全量 401
- **现象**`search_groups` 回放返回 `HTTP401`
- **为什么会出现**:套件过期(鉴权头是逐请求计算的),或捕获时鉴权头不全。
- **解决方法**:重新在线捕获套件,更新 `bundles.json`
- **如何避免**:套件一次性用完即弃;长期复用前先重新捕获校验。
### 问题 4HTTP/2 伪头导致 `InvalidHeader` 报错
- **现象**`requests``InvalidHeader: Invalid leading whitespace...`
- **为什么会出现**:捕获到的请求头里残留了 HTTP/2 伪头 `:authority``:method``:path``:scheme`,这些带冒号前缀的伪头不能被 `requests` 直接作为普通请求头发送。
- **解决方法**:从 `bundles.json` 中手动删除这 4 个伪头字段。
- **如何避免**:脚本捕获时自动过滤伪头,而不是留到下游报错后人工处理。
**是否已解决**是。3 个群组名全部解析出 groupId 并标注归属所有者(产物 `群组ID结果-需求输入-测试.xlsx`)。
---
## 四、yt-studio-url-builder生成 explore URL
- **现象**:本身运行无报错,从需求清单成功生成 6 条 URL。
- **隐性前置依赖(潜在问题)**URL 中 `entity_id` 必须是群组的 groupId清单里只有群组名、没有 ID 时会缺 `entity_id` 而失败。本次实际流程正是"先 groupid-lookup 填 ID再 url-builder 生成 URL"。
- **如何避免**:在 SKILL.md 中显式注明"清单若只有群组名,需先经 groupid-lookup 补 entity_id"。
**是否已解决**:是。产物 `studio_urls_需求输入-测试.csv` 含 6 条有效 URL。
---
## 五、youtube-studio-csv-download下载 CSV
这是问题最集中的技能,存在 2 处需要回填的脚本缺陷。
### 问题 1登录态失效跳转 Google 登录页
- **现象**:用已保存的 `cdp-profile`Chrome`edge-yts-debug-profile`Edge启动页面都停在 `accounts.google.com` 登录页。
- **为什么会出现**:两个 profile 里保存的 YouTube Studio 登录会话已过期。注意Edge 配置目录的 Cookies 文件里仍能看到 SAPISID/SID/__Secure-3PSID 等 cookie但**cookie 存在不等于会话仍有效**Google 仍要求重新登录。
- **解决方法**:由用户在浏览器中手动完成一次登录,之后复用该已登录会话。
- **如何避免**:下载前先探测页面是否跳登录页(脚本已有该判断,但只在跳转后提示);长期任务建议在开始前确认一遍登录态。
### 问题 2导出按钮定位失败脚本缺陷 1
- **现象**`page.get_by_text("导出当前视图")` 点击超时 30s日志 `waiting for get_by_text("导出当前视图")`
- **为什么会出现**:当前 YouTube Studio「高级模式」页的导出入口是右上角的**下载图标按钮**,它只有 `aria-label="导出当前视图"`**没有可见文本**。脚本用 `get_by_text`(文本匹配)自然匹配不到。
- **解决方法**:改用 `page.get_by_label("导出当前视图")`(或 `get_by_role("button", name=...)``[aria-label=...]`),已验证三种方式都能命中 `count=1`
- **如何避免**:对"图标类按钮"优先用 `aria-label` 定位,而非可见文本。
### 问题 3`zippedData` 解码失败 / 生成的 zip 损坏(脚本缺陷 2核心
- **现象**:拦截到 `csv_export` 响应后,`base64.b64decode(zippedData)``Incorrect padding`;即使解码未抛错,写出的 zip 文件用 `zipfile` 打开报 `BadZipFile: Bad magic number for central directory`(文件尾部无 `PK\x05\x06` 结束记录)。
- **为什么会出现**:响应中 `zippedData` 字段是 **URL-safe base64**(用 `-``_` 替代 `+``/`)且**去掉了 `=` 填充**。脚本用标准 `base64.b64decode` 解码:遇到 `-`/`_` 或非 4 对齐长度时,要么抛 padding 错,要么静默解出损坏字节流,导致 zip 不完整。
- **排查过程**:诊断脚本发现响应 `status=200``content-encoding: br`Brotli但 Playwright 已自动解压、`resp.json()` 能正常解析,因此排除了"响应被压缩截断"的猜想,最终锁定是 base64 变体问题。
- **解决方法**:解码前补 `=` 填充(`z += "=" * (-len(z) % 4)`),并用 `base64.b64decode(z, altchars=b"-_")` 指定 URL-safe 字符表。
- **如何避免**:对来自前端接口的 base64 字段,先确认是否为 URL-safe + 无填充变体再解码;解码后增加 `zipfile.testzip()` 完整性校验。
**是否已解决**:是。修正后 6/6 条全部下载成功,每个 zip 含 `表格数据.csv` / `图表数据.csv` / `总计.csv`,抽查验证美国筛选、按频道明细、按日收益均正确。
---
## 六、执行过程与原 skill 的差异对比
| 环节 | 原 skill 脚本行为 | 本次实际执行行为 | 差异原因 | 如何回归/解决 |
|---|---|---|---|---|
| csv-download导出按钮 | `get_by_text("导出当前视图")` | `get_by_label("导出当前视图")` | 前端已改为图标按钮,无可见文本,原定位失效 | 回填脚本:优先 `get_by_label`,可保留 `get_by_text` 兜底 |
| csv-downloadzip 解码 | `base64.b64decode(zipped)` | 补 `=` 填充 + `altchars=b"-_"` | 接口返回 URL-safe、无填充 base64 | 回填脚本:改用 URL-safe 解码 + 完整性校验 |
| csv-download下载目录 | 写死 `D:\Downloads` | 传 `--download-dir` 指向工作区 `YT导出` | 沙箱外 `D:\Downloads` 用户不可见 | 脚本已支持 `--download-dir`,无需改;仅执行时传参 |
| csv-download批量下载 | `run()` 单 URL、每次新建会话 | 外层驱动循环复用一次浏览器连接逐条下载 + zip 校验 + 失败重试 | 清单有 6 条 URL单次调用不够 | 可选:给脚本增加批量能力;或保持单次语义、由调用方写循环 |
| groupid-lookup伪头 | 捕获后原样落 `bundles.json` | 人工删除 4 个 HTTP/2 伪头 | 脚本未在捕获阶段过滤伪头 | 建议:捕获时自动过滤伪头 |
| url-builder | 直接读清单生成 URL | 先经 groupid-lookup 补 entity_id 再生成 | 清单只有群组名,缺 groupId | 无需改脚本;在 SKILL.md 注明前置依赖即可 |
> 差异分为两类:**脚本缺陷**按钮定位、base64 解码、伪头过滤)应回填到技能脚本;**环境/规模差异**(下载目录、批量循环、前置补 ID属于执行时的合理适配脚本本身逻辑无需破坏性改动。
---
## 七、四技能优化清单(建议)
### youtube-studio-csv-download高优先
1. 导出按钮定位由 `get_by_text` 改为 `get_by_label("导出当前视图")`(保留文本定位兜底)。
2. `decode_zipped_data` 改为 URL-safe base64 解码(补 `=` + `altchars=b"-_"`)。
3. (可选增强)保存后加 `zipfile.testzip()` 校验,失败自动重试一次。
### yt-studio-groupid-lookup中优先
4. 捕获套件时自动过滤 HTTP/2 伪头(`:authority` / `:method` / `:path` / `:scheme`)。
5. (可选)运行前探测 Chrome 残留进程,给出更明确的"完全退出后重启"提示。
### uv-env-setup低优先
6. 补充"`uv` 命令不可用时改用 `python -m uv` 或直调 `.venv\Scripts\python.exe`"的排查提示。
### yt-studio-url-builder低优先
7. SKILL.md 显式说明"清单只有群组名时,需先经 groupid-lookup 补 entity_id"。
---
## 八、待确认事项
以上优化点(尤其第三节、第五节的 3 处脚本缺陷修复)尚未改动任何技能脚本,仅记录在本文档。是否执行优化、执行到哪些范围(仅修复缺陷 / 同时做增强),请确认后再实施。