douyin-crawler-poc/docs/superpowers/specs/2026-04-17-douyin-login-entry-design.md

192 lines
5.9 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.

# Douyin Login Entry Design
## Goal
将当前“手动先开浏览器登录,再让 `Douyin.py` 附着到调试端口抓取”的隐式流程,固化为稳定、明确、可复用的两步式命令行入口。
## Current Context
- 现有抓取实现位于 `Douyin.py`
- `Douyin.py` 已支持通过 `--browser-port` 附着到已启动的 Chrome 调试端口。
- 本次实测已经证明:用户先在可见 Chrome 中登录抖音并通过验证码后,`Douyin.py --browser-port 9223` 可以成功抓到 `web/aweme/post/` 接口并下载视频。
- 当前缺少一个明确的“登录准备入口”,导致可操作性依赖人工记忆和临时命令。
## Requirements
### Functional
1. 提供一个独立脚本,用于启动可见 Chrome并固定
- 调试端口,默认 `9223`
- 用户数据目录,默认使用一个项目约定路径
- 打开的初始 URL默认指向现有抖音博主页
2. 登录脚本只负责“打开浏览器并提示用户手动登录”,不负责抓取。
3. `Douyin.py` 继续负责抓取,并保持“附着已有浏览器”的职责边界。
4.`Douyin.py` 指定了 `--browser-port` 但端口不可连通时,应给出清晰错误,提示先运行登录脚本。
5. 文档应给出最短可执行流程:
- 第一步:启动浏览器并登录
- 第二步:运行抓取命令
### Non-Functional
1. 不改变现有抓包、解析、下载的主逻辑。
2. 保持现有命令参数兼容。
3. 入口职责清晰,便于排查“登录问题”和“抓取问题”。
4. 新增行为应具备可自动化测试的核心单元。
## Chosen Approach
采用双脚本方案:
- 新增 `login_douyin.py`
- 负责启动可见 Chrome
- 固定 remote debugging port
- 固定 profile 目录
- 打开目标用户主页
- 输出明确提示,引导用户完成手动登录和验证码
- 保留 `Douyin.py`
- 继续承担附着浏览器、监听接口、下载视频的职责
- 增强附着前检查与报错信息
## Rejected Alternatives
### Alternative 1: 将“启动浏览器”直接并入 `Douyin.py`
不采用。原因:
- 会让 `Douyin.py` 同时承担登录准备和抓取职责。
- 错误定位会变差,用户更难区分是登录失败还是抓取失败。
- 未来若需要“先登录、稍后再抓”,这种合并入口不灵活。
### Alternative 2: 只写 shell 脚本串联所有步骤
不采用。原因:
- 逻辑容易散落在 shell 中,测试性差。
- 浏览器启动参数、等待逻辑和抓取命令耦合度高。
- 后续若要扩展默认参数或跨平台兼容shell 方案维护成本更高。
## Proposed CLI UX
### Step 1: 启动登录浏览器
```bash
./.venv/bin/python login_douyin.py
```
默认行为:
- 启动可见 Chrome
- 调试端口为 `9223`
- profile 目录为项目约定的本地路径
- 打开默认的抖音主页 URL
- 输出“请在浏览器中完成登录/验证码,然后再运行抓取命令”
可选扩展参数:
- `--browser-port`
- `--profile-dir`
- `--user-url`
- `--chrome-path`
### Step 2: 运行抓取
```bash
./.venv/bin/python Douyin.py --pages 1 --browser-port 9223
```
## Design Details
### `login_douyin.py`
建议拆分为可测试的小函数:
- `build_login_command(...)`
- 输入 Chrome 路径、profile 目录、端口、URL
- 输出适合 `subprocess.Popen(...)` 的参数列表
- `launch_browser(...)`
- 调用 `subprocess.Popen(...)`
- `build_parser()`
- 定义 CLI 参数
- `main()`
- 解析参数
- 启动浏览器
- 打印下一步指引
### `Douyin.py`
新增一个显式的端口检查函数,例如:
- `ensure_browser_debug_port_ready(browser_port: int) -> None`
行为:
- 仅当用户传入 `--browser-port` 时执行
- 尝试连接 `127.0.0.1:<port>`
- 若失败,抛出清晰错误,提示:
- 先启动 `login_douyin.py`
- 确认 Chrome 仍在运行
- 确认端口与抓取命令一致
## Error Handling
### 登录脚本
- Chrome 可执行文件不存在:直接报错并退出。
- 浏览器启动失败:输出异常原因并返回非零退出码。
- profile 目录不存在:自动创建。
### 抓取脚本
- 指定 `--browser-port` 但端口不可达:立即失败,不进入抓取流程。
- 登录未完成导致页面异常:保留现有抓包等待与警告逻辑。
## Testing Strategy
### Unit Tests
新增或扩展 `test_douyin.py`,覆盖:
1. `build_login_command()` 生成的命令参数正确。
2. 默认调试地址仍为 `127.0.0.1:<port>`
3. `ensure_browser_debug_port_ready()` 在端口不可达时抛出可读错误。
4. `ensure_browser_debug_port_ready()` 在端口可达时正常返回。
如测试边界过大,可新增 `test_login_douyin.py`
### Manual Verification
1. 运行 `./.venv/bin/python login_douyin.py`
2. 在打开的 Chrome 中登录抖音并通过验证码
3. 运行 `./.venv/bin/python Douyin.py --pages 1 --browser-port 9223`
4. 确认 `video/` 下生成新的 mp4 文件
## Implementation Boundaries
本次只做以下改动:
- 新增登录入口脚本
- 为抓取入口补充附着前端口检查
- 更新测试
- 更新使用文档
本次不做以下改动:
- 不重写抓取主流程
- 不改成单命令自动等待登录
- 不引入 Playwright 作为正式运行时依赖
- 不增加下载调度、断点续传或批量任务管理
## Risks
1. 本机 Chrome 路径可能与预设不同,因此需要保留 `--chrome-path` 覆盖能力。
2. profile 目录固定后,用户可能重复复用登录态,这是预期行为,但文档需说明。
3. 若目标端口被其他进程占用,登录脚本需要给出可诊断的失败信息或允许端口覆盖。
## Success Criteria
满足以下条件即视为完成:
1. 用户可以通过固定命令启动登录浏览器。
2. 用户登录完成后,可通过固定命令让 `Douyin.py` 成功附着并抓取。
3. 当浏览器未启动或端口错误时,抓取脚本会给出明确提示,而不是模糊失败。