Skip to content

2.3.1

Choose a tag to compare

@lumingya lumingya released this 21 Feb 03:55
· 165 commits to main since this release
cb5b3d8

更新日志

v2.3.1 — 隐身模式反检测增强 + 预设系统

发布日期:2026-02-20

感谢测试者@喵团子爱摸鱼

🎯 核心新特性

预设系统

为每个站点配置引入多预设支持,允许在同一站点的不同标签页使用不同的工作流、选择器和参数配置。

典型应用场景:

  • 标签页 A:使用预设 "Pro模型对话" → 启用 new_chat_btn、复杂工作流、较长超时
  • 标签页 B:使用预设 "快速识图" → 禁用 new_chat_btn、简化工作流、图片提取优先

功能特性:

  • 每个站点可创建多个预设(克隆自现有预设)
  • 标签页池支持为单个标签页指定预设(通过 /api/tab-pool/tabs/{index}/preset
  • Dashboard UI 支持可视化管理预设(新建、删除、切换)
  • 配置文件格式自动迁移(旧版扁平结构 → 新版预设结构)

配置结构示例:

{
  "gemini.google.com": {
    "presets": {
      "主预设": {
        "selectors": { "input_box": "...", "send_btn": "..." },
        "workflow": [...],
        "image_extraction": { "enabled": false },
        "file_paste": { "threshold": 50000 }
      },
      "快速识图": {
        "selectors": { "input_box": "...", "send_btn": "..." },
        "workflow": [...],
        "image_extraction": { "enabled": true, "mode": "first" },
        "file_paste": { "threshold": 10000 }
      }
    }
  }
}

🔴 关键修复

Cloudflare 高强度盾检测绕过

通过系统性隔离测试,定位并修复了两个独立的 CF 检测向量:

检测向量 发现方式 CF 检测原理 修复方案
PointerEvent.pressure=0 对比有/无 force 参数的 CDP 点击 真实鼠标按下时 pressure≈0.5,CDP 默认 pressure=0 mousePressed 事件传递 force=0.5
额外 CDP Session 对比 network/dom 监听模式 DrissionPage tab.listen 创建独立 WebSocket + Target.attachToTarget,异常 Session 计数 补丁 DrissionPage Listener 复用主连接

1. 修复 CDP 点击 pressure=0 检测

  • 问题根因:CDP Input.dispatchMouseEventmousePressed 事件默认 force=0,导致页面 PointerEvent.pressure=0(真实鼠标按下时 pressure≈0.5)。Cloudflare 高强度盾通过此差异识别自动化点击。

  • 修复方案:隐身模式下所有点击操作的 mousePressed 事件传递 force=0.5,匹配真实设备行为。

2. 修复网络监听暴露额外 CDP Session

  • 问题根因:DrissionPage 的 tab.listen 功能在启动时会创建独立的 WebSocket 连接并调用 Target.attachToTarget 建立新的 CDP Session。Cloudflare 可检测到异常的 Session 数量和 Network.enable 活动。

  • 修复方案:新增 DrissionPage 自动补丁(patch_drissionpage.py),让 Listener 复用 tab 主连接,消除额外连接和 Session。

    • 补丁支持幂等执行(重复运行不会重复打补丁)
    • 自动备份原文件,支持 --restore 一键恢复
    • start.bat 启动脚本在依赖安装后自动执行补丁

3. 消除 ele.click() 降级路径

  • 问题:隐身模式下部分异常场景会降级回退到 ele.click()tab.actions.click(),这两者均会触发 CF 检测。

  • 修复:所有点击路径统一使用 cdp_precise_click(),彻底移除降级回退。

关键测试结论

  • tab.ele()ele.rectele.states.is_displayed 均使用纯 CDP 命令,不注入 JSRuntime.evaluate 调用次数 = 0)
  • ✅ 纯 CDP 操作(鼠标移动、元素查找、rect 读取)即使重复多轮也不触发 CF
  • ❌ DrissionPage 的 tab.listen 创建独立 WebSocket 连接 + Target.attachToTarget,这是 CF 检测的主要来源(已修复

🟡 隐身模式增强

人类化鼠标行为改进

  1. 按压期间微移

    • CDP 点击在 mousePressedmouseReleased 之间插入 1-2 个 mouseMoved(buttons=1) 微移事件
    • 模拟真实手指按压时鼠标的微小位移(±1px 范围内随机),消除"事件沙漠"
  2. 释放坐标偏移

    • mouseReleased 的坐标允许与 mousePressed 有 ±1px 偏差,匹配真实人类行为
  3. 移除危险的降级路径

    • _dispatch_mouse_move() 不再降级到 tab.actions.move_to()(测试证明 tab.actions 系列操作会触发 CF)
  4. 空闲微漂移不规则化

    • idle_drift() 的移动频率改为:
      • 30% 概率:连续快速微动(模拟手部抖动)
      • 70% 概率:长静止期(3-8秒无移动)
    • 更接近真实人类的无意识手部抖动模式

滚轮滚动改用纯 CDP

  • human_scroll() 改用 Input.dispatchMouseEvent(type='mouseWheel') 替代 tab.actions.scroll()
  • 避免 actions 系列的参数差异导致的检测

🛠️ 配置引擎重构

预设架构迁移

  • 自动迁移:启动时自动将旧版扁平配置迁移为预设结构(_migrate_to_presets()
  • 残留清理:清理预设外的冗余字段(_cleanup_preset_residuals()),修复旧 bug 导致的配置重复
  • 向后兼容:旧版单预设配置在迁移后自动包装为 "主预设"

文件粘贴配置层级修复

  • 修复 BUGFilePastePanel.js 错误地读写站点顶层的 file_paste 配置,而非预设内配置
  • 修复方案:改为通过 _getActivePresetData() 获取活跃预设的可变引用,正确读写预设内配置
  • 影响范围:所有通过 Dashboard 修改的文件粘贴配置现在会正确保存到预设内

保存机制优化

  • 修复 BUGPOST /api/config 端点直接覆写文件导致 _global 数据丢失
  • 修复方案:改用 config_engine.save_config() 保存,自动包含 _global(元素定义、回退选择器)
  • 前端清理normalizeConfig() 现在会过滤预设外的残留字段,确保保存数据干净

🏊 标签页池增强

标签页扫描优化

  • 修复 BUG_known_tab_ids 永久记录 chrome://newtab/ 等页面的 raw_tab_id,导致用户在同一标签页导航到新网站后仍被跳过
  • 修复方案
    • 不再永久标记可导航的空白页(chrome://newtab/about:blank
    • 扫描时使用 tabs_in_pool(实时计算的池内标签页集合)而非 _known_tab_ids 判断是否跳过
    • 每次扫描时清理已关闭的标签页映射

实时响应性增强

  • 修复延迟感get_tabs_with_index 每次查询都强制扫描新标签页(不受 10 秒间隔限制)
  • 首次获取立即扫描acquire() 首次进入循环时立即扫描(不等待 _should_scan()
  • 关闭检测实时化:扫描时检测已关闭的标签页并立即清理映射,避免访问旧标签页导致超时

预设切换 API

  • 新增端点PUT /api/tab-pool/tabs/{tab_index}/preset — 为指定标签页设置预设
  • Dashboard UI:标签页池页面显示预设选择器,支持可视化切换

新增 patch_drissionpage.py

DrissionPage Listener 连接复用补丁脚本。

功能:

  • 自动检测 DrissionPage 安装路径
  • 备份原文件(.bak 后缀)
  • 修改 _listener.py 让 Listener 复用 tab 主连接
  • 支持 --restore 恢复原文件

使用方式:

# 自动应用补丁(start.bat 已内置)
python patch_drissionpage.py

# 恢复原文件
python patch_drissionpage.py --restore

⚠️ 破坏性变更

  1. 配置文件格式变更

    • 旧版:{ "domain": { "selectors": {...}, "workflow": [...] } }
    • 新版:{ "domain": { "presets": { "主预设": { "selectors": {...}, ... } } } }
    • 兼容性:启动时自动迁移,无需手动操作
  2. API 响应格式变更

    • GET /api/config/{domain} 默认返回整个站点结构(含所有预设)
    • 传递 ?preset_name=xxx 参数可获取单个预设的扁平配置

🐛 其他修复

  • 修复 normalizeConfig 未清理残留字段导致的配置重复
  • 修复标签页池关闭检测不及时导致的卡死问题
  • 修复 _cleanup_unhealthy_tabs 删除 session 但未清理映射表的内存泄漏
  • 修复前端 token key 不一致(auth_token vs api_token

📝 已知问题

  • DrissionPage 补丁需在每次升级 DrissionPage 后重新执行
  • 部分 AI 站点的图片提取配置需手动测试验证

🔧 开发者说明

测试环境:

  • Python 3.13
  • DrissionPage 4.1.0.11

关键文件变更:

  • app/core/tab_pool.py — 标签页池扫描逻辑重写
  • app/services/config/engine.py — 预设系统实现 + 迁移逻辑
  • app/api/config_routes.py — 预设相关 API
  • static/js/components/panels/FilePastePanel.js — 预设感知修复
  • static/js/dashboard.jsnormalizeConfig 清理逻辑
  • patch_drissionpage.py — 新增

如有问题请提交 Issue 或加入交流群