9.0 KiB
9.0 KiB
架构说明(v1.2.0)
本文档梳理项目中的主要模块、职责划分以及核心流程,帮助维护者快速了解整体结构。当前版本包含短信验证码登录、Cookie 持久化以及 AI 驱动的滑块验证码自动破解功能。
模块概览
graph TD
root((项目根目录))
root --> readme[README.md<br/>使用说明与运行指引]
root --> arch[ARCHITECTURE.md<br/>架构概览与流程说明]
root --> impl[IMPLEMENTATION.md<br/>实现细节记录]
root --> quick[QUICKSTART.md<br/>快速开始指南]
root --> changelog[CHANGELOG.md<br/>更新日志]
root --> release[release.md<br/>发布说明]
root --> login_doc[login.md<br/>早期需求与操作步骤]
root --> pkg[package.json<br/>项目配置]
root --> src_dir[src/]
root --> noflag[noflag/<br/>原始验证码截图]
root --> output_dir[output/<br/>标注结果]
root --> ts_spec[typescript-spec.md<br/>编码规范]
src_dir --> login_ts[login.ts<br/>登录脚本入口]
src_dir --> sms_dir[sms/]
src_dir --> slider_dir[slider/]
sms_dir --> sms_code[douban-code.ts<br/>macOS 短信读取]
subgraph slider["slider/ 模块"]
direction TB
slider_index[index.ts]
slider_types[types.ts]
slider_detector[detector.ts]
slider_self[detector-self-learning.ts]
slider_controller[slider-controller.ts]
slider_cli[cli.ts]
slider_validator[validator.ts]
slider_detection_dir[detection/]
slider_utils_dir[utils/]
slider_detection_dir --> slider_candidate[candidate-search.ts]
slider_utils_dir --> slider_geometry[geometry.ts]
slider_utils_dir --> slider_image[image.ts]
end
slider_dir --> slider_index
slider_dir --> slider_types
slider_dir --> slider_detector
slider_dir --> slider_self
slider_dir --> slider_controller
slider_dir --> slider_cli
slider_dir --> slider_validator
slider_dir --> slider_detection_dir
slider_dir --> slider_utils_dir
登录流程分层(v1.2.0)
flowchart TD
main[main()<br/>• 启动 Chromium<br/>• 复用或创建上下文<br/>• 调用 loginWithSms()<br/>• 保存 Cookies] --> login[loginWithSms()<br/>• 输入手机号<br/>• 触发短信验证码<br/>• 自动处理滑块验证<br/>• 自动读取 macOS 短信验证码<br/>• 提交并校验登录结果]
login --> slider[SliderController<br/>• 等待滑块出现<br/>• 截图并调用检测器<br/>• 计算距离与拖动<br/>• 失败自动重试]
login --> logged[isLoggedIn()<br/>• 检查 Cookie(dbcl2)<br/>• 确认登录表单状态]
slider --> detector[SliderDetector<br/>• 图像缩放(800px)<br/>• 多策略检测<br/>• 候选框评分<br/>• 绘制标注]
detector --> candidate[CandidateSearch<br/>• 暗区域检测<br/>• Canny 边缘<br/>• 颜色量化<br/>• LAB 色彩<br/>• IoU 去重]
login --> sms[waitForDoubanCode()<br/>• 连接 chat.db<br/>• 跟踪最新消息<br/>• 解析验证码<br/>• 超时降级手动输入]
sms --> autofill[自动填入验证码<br/>input#code]
sms --> fallback[提示手动输入验证码]
关键模块职责:
prepareContext():负责加载已有 Cookie、创建新上下文以及兜底跳转登录页loginWithSms():串联短信登录流程,涵盖用户输入与滑块自动化waitForDoubanCode():从 macOS 信息数据库读取最新验证码,失败时回退到手动输入SliderController:Playwright 集成,控制滑块验证的完整流程SliderDetector:图像处理和滑块位置检测的核心算法CandidateSearch:多种图像识别策略的并行执行isLoggedIn():封装判定逻辑,避免各处重复编写 Cookie/页面检查
依赖与交互
- Playwright:启动浏览器、操作页面元素、持久化
storageState、控制滑块拖动 - Sharp:图像处理(缩放、边缘检测、颜色量化、模板匹配)
- Node.js:文件读写、路径与环境变量处理
- better-sqlite3:只读访问
~/Library/Messages/chat.db,解析最新短信验证码(macOS) - readline:作为短信读取的降级方案,提示用户手动输入验证码
- 环境变量:
DOUBAN_PHONE:登录手机号(必填)DOUBAN_AUTO_SLIDER:启用自动滑块验证(可选,值为 1 时启用)
~/douban-cookie.json:保存登录态的 storageState 文件,下次运行直接复用noflag/:原始验证码截图存储目录output/:标注结果(红框)存储目录
数据流(v1.2.0)
-
初始化阶段
- 读取
DOUBAN_PHONE,未配置则终止 - 检查
DOUBAN_AUTO_SLIDER环境变量 - 若存在本地 Cookie 文件,加载后访问登录页以确认是否仍然有效
- 读取
-
登录流程
- 无有效登录态时执行短信登录:
- Playwright 填写手机号并请求验证码
- [v1.1.0] 自动检测并处理滑块验证码:
- 等待验证码 iframe 加载
- 截图验证码区域到
noflag/目录 - 使用 Sharp 将图像缩放到 800px 宽度
- 并行运行四种检测策略
- 计算距离:
(缺口X - 滑块X) / scaleX - 绘制红框标注保存到
output/目录 - 拖动滑块到计算位置
- 检测成功标识(
.tc-success) - 失败则刷新重试(最多 10 次)
- [v1.2.0] 调用
waitForDoubanCode()轮询 chat.db,捕获最新验证码 - 若读取失败或超时,提示用户手动输入验证码
- 将验证码填入页面并提交
- 无有效登录态时执行短信登录:
-
状态持久化
- 登录成功后调用
context.storageState()写入~/douban-cookie.json - 浏览器关闭,后续脚本可直接复用该文件
- 登录成功后调用
-
图像数据流
flowchart TD img_raw[原始验证码<br/>(340x191)] --> img_capture[截图保存<br/>noflag/captcha-*.png] img_capture --> img_scale[缩放至 800px<br/>内存处理图像] img_scale --> img_detect[多策略检测] img_detect --> img_boxes[候选框数组<br/>{x,y,w,h,score}] img_boxes --> img_filter[评分排序 + IoU 去重] img_filter --> img_best[最佳滑块位置<br/>[b1, b2]] img_best --> img_draw[绘制标注<br/>output/captcha-*-detected.png] img_draw --> img_distance[计算距离<br/>(b2.x - b1.x) / scaleX] -
短信数据流(macOS)
flowchart TD sms_db[~/Library/Messages/chat.db] --> sms_query[better-sqlite3 查询] sms_query --> sms_record[最新短信记录<br/>(handle/text/date)] sms_record --> sms_parse[parseDoubanSms()<br/>解析验证码] sms_parse --> sms_autofill[自动填入 input#code] sms_parse --> sms_manual[失败时提示手动输入]
日志与错误处理
- 关键步骤均在控制台打印提示,便于追踪流程
- [v1.2.0] 短信读取阶段输出
[短信读取]前缀日志,包含基线 ID、轮询状态与命中消息 - [v1.1.0] 滑块检测过程的详细日志:
- 图像缩放信息(原始尺寸 → 检测尺寸)
- 检测到的滑块数量和位置
- 每个滑块的评分和尺寸
- 距离计算公式和结果
- 成功/失败状态和重试次数
- 默认优先使用自动短信读取,
prompt只在超时或读取失败时触发 - 登录失败或异常会设置
process.exitCode并输出详细错误信息 - 视觉调试:
output/目录中的红框标注图便于人工验证检测准确性
v1.2.0 新增能力
- macOS 短信自动读取:通过
better-sqlite3直接查询chat.db,仅处理新消息并解析验证码。 - 自动回填验证码:等待
input#code可见后自动填充,减少人为介入。 - 降级与日志机制:超时或权限不足时回退到控制台输入,并输出明确的失败原因与排查建议。
v1.1.0 核心创新
简化的距离计算算法
核心原理:"两只小鸟嘴尖距离"
// 双滑块模式(推荐)
const distance = (box2.x - box1.x) / scaleX;
// 单滑块模式(兜底)
const distance = box.x / scaleX;
为什么这样简单?
- 检测在 800px 宽度图像上进行(scaleX ≈ 2.35)
- 两个滑块的左边界水平距离就是移动距离(缩放坐标系)
- 除以 scaleX 转换回实际显示坐标系(340px)
- 避免复杂的 iframe 偏移、页面坐标转换等计算
v1.0.0 vs v1.1.0:
- v1.0.0:需要人工完成滑块验证
- v1.1.0:自动检测、计算、拖动,成功率约 50%
多策略并行检测
并行运行四种算法,提高鲁棒性:
- 暗区域检测:基于亮度阈值查找暗色滑块
- Canny 边缘检测:查找边缘密集区域
- 颜色量化:K-means 聚类找独特色块
- LAB 色彩空间:在感知均匀的色彩空间中检测
候选框通过 IoU 去重,避免重复检测同一个滑块。
自学习模板匹配
使用第一个检测到的滑块作为模板,在图像中查找第二个滑块:
- 提取第一个滑块的边缘特征
- 在剩余区域进行模板匹配
- 验证 y 坐标一致性(偏差 < 25px)
- 确保两个滑块在合理的水平距离范围内