Files
douban-login/ARCHITECTURE.md
2025-10-25 23:39:25 +08:00

214 lines
9.0 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.

# 架构说明v1.1.0
本文档梳理项目中的主要模块、职责划分以及核心流程帮助维护者快速了解整体结构。当前版本包含短信验证码登录、Cookie 持久化以及 AI 驱动的滑块验证码自动破解功能。
## 模块概览
```
├── README.md // 使用说明与运行指引
├── ARCHITECTURE.md // 架构概览与流程说明(本文档)
├── IMPLEMENTATION.md // 关键实现细节记录
├── QUICKSTART.md // 快速开始指南
├── CHANGELOG.md // 版本更新日志
├── release.md // 发布说明
├── login.md // 早期需求与操作步骤
├── package.json // 项目配置v1.1.0
├── src/
│ ├── login.ts // 豆瓣登录脚本入口(集成滑块验证)
│ └── slider/ // 滑块验证模块v1.1.0 新增)
│ ├── index.ts // 模块导出
│ ├── types.ts // 类型定义
│ ├── detector.ts // 主滑块检测器
│ ├── detector-self-learning.ts // 第二滑块检测
│ ├── slider-controller.ts // 滑块控制器
│ ├── cli.ts // CLI 批量工具
│ ├── validator.ts // 结果验证工具
│ ├── detection/
│ │ └── candidate-search.ts // 多策略检测
│ └── utils/
│ ├── geometry.ts // 几何计算
│ └── image.ts // 图像处理
├── noflag/ // 原始验证码截图输出目录
├── output/ // 标注结果输出目录
└── typescript-spec.md // 团队 TypeScript 编码规范
```
## 登录流程分层v1.1.0
```
┌─────────────────────────────────────────┐
│ main() │
│ - 启动 Chromium │
│ - 复用或创建上下文 │
│ - 调用 loginWithSms() │
│ - 保存 Cookies │
└─────────────────────────────────────────┘
┌──────────────────▼────────────────────┐
│ loginWithSms() │
│ - 输入手机号 │
│ - 触发短信验证码 │
│ - [v1.1.0] 自动处理滑块验证 │
│ - 等待并提交短信验证码 │
│ - 校验是否登录成功 │
└───────────────────────────────────────┘
┌────────────┴──────────────┐
│ │
┌─────▼──────────────┐ ┌─────────▼──────────────┐
│ SliderController │ │ isLoggedIn() │
│ - 等待滑块出现 │ │ - 检查 Cookiedbcl2
│ - 截图到 noflag/ │ │ - 确认登录表单状态 │
│ - 调用 detector │ └────────────────────────┘
│ - 计算距离 │
│ - 拖动滑块 │
│ - 验证成功标识 │
│ - 失败重试(10次) │
└────────────────────┘
┌────────▼───────────────┐
│ SliderDetector │
│ - 图像缩放(800px) │
│ - 多策略检测 │
│ - 候选框评分 │
│ - 绘制标注到 output/ │
└────────────────────────┘
┌────────▼───────────────┐
│ CandidateSearch │
│ - 暗区域检测 │
│ - Canny 边缘检测 │
│ - 颜色量化 │
│ - LAB 色彩空间 │
│ - IoU 去重 │
└────────────────────────┘
```
**关键模块职责**
- `prepareContext()`:负责加载已有 Cookie、创建新上下文以及兜底跳转登录页
- `loginWithSms()`:串联短信登录流程,涵盖用户输入与滑块自动化
- `SliderController`Playwright 集成,控制滑块验证的完整流程
- `SliderDetector`:图像处理和滑块位置检测的核心算法
- `CandidateSearch`:多种图像识别策略的并行执行
- `isLoggedIn()`:封装判定逻辑,避免各处重复编写 Cookie/页面检查
## 依赖与交互
- **Playwright**:启动浏览器、操作页面元素、持久化 `storageState`、控制滑块拖动
- **Sharp**:图像处理(缩放、边缘检测、颜色量化、模板匹配)
- **Node.js**:文件读写、路径与环境变量处理
- **readline**:在控制台等待用户输入短信验证码
- **环境变量**
- `DOUBAN_PHONE`:登录手机号(必填)
- `DOUBAN_AUTO_SLIDER`:启用自动滑块验证(可选,值为 1 时启用)
- **`~/douban-cookie.json`**:保存登录态的 storageState 文件,下次运行直接复用
- **`noflag/`**:原始验证码截图存储目录
- **`output/`**:标注结果(红框)存储目录
## 数据流v1.1.0
1. **初始化阶段**
- 读取 `DOUBAN_PHONE`,未配置则终止
- 检查 `DOUBAN_AUTO_SLIDER` 环境变量
- 若存在本地 Cookie 文件,加载后访问登录页以确认是否仍然有效
2. **登录流程**
- 无有效登录态时执行短信登录:
- Playwright 填写手机号并请求验证码
- **[v1.1.0]** 自动检测并处理滑块验证码:
1. 等待验证码 iframe 加载
2. 截图验证码区域到 `noflag/` 目录
3. 使用 Sharp 将图像缩放到 800px 宽度
4. 并行运行四种检测策略
5. 计算距离:`(缺口X - 滑块X) / scaleX`
6. 绘制红框标注保存到 `output/` 目录
7. 拖动滑块到计算位置
8. 检测成功标识(`.tc-success`
9. 失败则刷新重试(最多 10 次)
- 控制台输入短信验证码并提交
3. **状态持久化**
- 登录成功后调用 `context.storageState()` 写入 `~/douban-cookie.json`
- 浏览器关闭,后续脚本可直接复用该文件
4. **图像数据流**
```
原始验证码(340x191)
▼ 截图
noflag/captcha-timestamp.png
▼ 缩放到 800px
内存中的处理图像(800x449)
▼ 多策略检测
候选框数组 [{x,y,w,h,score}]
▼ 评分排序 + IoU去重
最佳滑块位置 [b1, b2]
▼ 绘制红框
output/captcha-timestamp-detected.png
▼ 计算距离
移动距离 = (b2.x - b1.x) / scaleX
```
## 日志与错误处理
- 关键步骤均在控制台打印提示,便于追踪流程
- **[v1.1.0]** 滑块检测过程的详细日志:
- 图像缩放信息(原始尺寸 → 检测尺寸)
- 检测到的滑块数量和位置
- 每个滑块的评分和尺寸
- 距离计算公式和结果
- 成功/失败状态和重试次数
- 验证码相关操作采用提示 + `prompt` 方式等待人工输入
- 登录失败或异常会设置 `process.exitCode` 并输出详细错误信息
- 视觉调试:`output/` 目录中的红框标注图便于人工验证检测准确性
## v1.1.0 核心创新
### 简化的距离计算算法
**核心原理**"两只小鸟嘴尖距离"
```typescript
// 双滑块模式(推荐)
const distance = (box2.x - box1.x) / scaleX;
// 单滑块模式(兜底)
const distance = box.x / scaleX;
```
**为什么这样简单?**
1. 检测在 800px 宽度图像上进行scaleX ≈ 2.35
2. 两个滑块的左边界水平距离就是移动距离(缩放坐标系)
3. 除以 scaleX 转换回实际显示坐标系340px
4. 避免复杂的 iframe 偏移、页面坐标转换等计算
**v1.0.0 vs v1.1.0**
- v1.0.0:需要人工完成滑块验证
- v1.1.0:自动检测、计算、拖动,成功率约 50%
### 多策略并行检测
并行运行四种算法,提高鲁棒性:
1. **暗区域检测**:基于亮度阈值查找暗色滑块
2. **Canny 边缘检测**:查找边缘密集区域
3. **颜色量化**K-means 聚类找独特色块
4. **LAB 色彩空间**:在感知均匀的色彩空间中检测
候选框通过 IoU 去重,避免重复检测同一个滑块。
### 自学习模板匹配
使用第一个检测到的滑块作为模板,在图像中查找第二个滑块:
1. 提取第一个滑块的边缘特征
2. 在剩余区域进行模板匹配
3. 验证 y 坐标一致性(偏差 < 25px
4. 确保两个滑块在合理的水平距离范围内