雨云签到验证码怎么破?2026最新自动识别方案

雨云签到验证码怎么破?2026最新自动识别方案

上一篇保姆级教程《2026年最新 教你0元搭建雨云自动签到,每日自动领积分续费》中,我们已经实现了利用 GitHub Actions 每天全自动白嫖雨云积分。不少读者私信问:"脚本怎么自动过验证码的?用的是 2captcha 打码平台吗?要花钱吗?" 答案是:一分钱不花,纯本地 AI 识别。 今天这篇文章就带你深入了解 Rainyun-Qiandao 项目背后的雨云签到验证码自动破解技术,看看它为什么能在 GitHub Actions 的免费环境里稳定运行,以及到底比 2captcha 等付费方案强在哪。


雨云的验证码到底是什么类型?

雨云使用的是 腾讯 TCaptcha(防水墙) 验证码,如果你做过签到就一定见过它:一张包含多个小图案的背景图片,加上 3 个需要你按顺序点击的目标图块。

简单来说,它是一种 "文字/图案点选型" 验证码:

验证码类型典型代表破解难度
简单数字验证码老式论坛
滑动拼图早期极验、腾讯滑块⭐⭐
文字/图案点选腾讯 TCaptcha、极验 v4⭐⭐⭐⭐
reCAPTCHA v3Google 行为分析⭐⭐⭐⭐⭐

腾讯 TCaptcha 的难点在于:它不像简单滑块只需要计算一个偏移量,而是需要你 从背景图中精准定位 3 个目标图案的坐标并依次点击。这意味着破解程序不仅要"看懂"目标长什么样,还得在一张花花绿绿的大图里"找到"它们。

正因为它的前端渲染机制是基于 JavaScript 动态加载的,纯 HTTP 请求根本拿不到验证码的真实图片数据。所以项目选择了用 Selenium 模拟一个真实浏览器来跑。


为什么不用 2captcha?雨云2captcha签到替代方案

很多自动化教程会推荐 2captcha、Anti-Captcha 等第三方人工打码平台。它们的原理很简单:把验证码图片发到平台服务器,由真人或 AI 解答后返回结果。但对于"雨云每日签到"这个场景,这类方案有几个致命问题:

对比维度2captcha 等付费平台本方案(ddddocr 本地识别)
费用约 $2-3 / 1000次$0(完全免费)
速度10~60 秒(等人工)1~3 秒(本地推理)
隐私账号信息经过第三方全程本地,零数据外传
依赖需联网且平台随时关停离线运行,GitHub Actions 内置
GPU 要求无(服务端处理)无(CPU 即可,ddddocr 极致轻量)

换句话说,2captcha 那一套在"白嫖积分"的语境下完全没有性价比。你为了省钱才签到,结果打码费比积分还贵?

本项目的核心思路就是 "零成本、纯本地、全自动",用 AI 模型直接在运行环境里搞定一切。


技术方案全解:Selenium + ddddocr + OpenCV 三板斧

这套雨云自动签到验证码版方案的技术栈可以用一句话概括:Selenium 负责"操作浏览器",ddddocr 负责"看懂文字",OpenCV 负责"找到位置"。

下面逐层拆解。

第一层:Selenium,模拟真实浏览器环境

为什么要用 Selenium 而不是直接发 HTTP 请求?因为腾讯 TCaptcha 会做大量的前端检测:

项目使用 Chrome 无头模式(headless) 运行 Selenium,专为服务器环境优化:

# 无头模式 + 1080p 窗口(避免元素重叠导致误点)
ops.add_argument("--headless")
ops.add_argument("--window-size=1920,1080")
ops.add_argument("--no-sandbox")
ops.add_argument("--disable-dev-shm-usage")  # Docker/Actions 内存优化

为什么窗口设 1920×1080? 主要是为了模拟真实用户的浏览器环境。一个正常用户不可能用 800×600 的窗口浏览网页,设置标准分辨率有助于降低被风控系统识别为自动化工具的风险。

反检测:注入 stealth.js + 账号专属指纹

光跑个 headless Chrome 远远不够,Selenium 会被各种方式检测到。项目做了两层防护:

第一层:stealth.min.js 注入

这个文件不是手写的,而是从 puppeteer-extra-plugin-stealth(7.2k+ ⭐)中自动提取生成的。

stealth 插件本来是 Puppeteer 专属的,它在浏览器打开页面时会通过 page.evaluateOnNewDocument() 注入一系列反检测脚本。而 extract-stealth-evasions 这个工具做了一件很巧妙的事:evaluateOnNewDocument 替换成一个"窃听器",只记录脚本内容而不执行

// 核心 trick:猴子补丁(Monkey Patch)
page.__proto__.evaluateOnNewDocument = function(func, args) {
  // 不执行,只把脚本源码拼接起来
  scripts += '(' + func.toString() + ')(' + JSON.stringify(args) + ');\n'
}

完整的生成流程是这样的:

  1. 启动 Puppeteer + stealth 插件
  2. 替换掉 evaluateOnNewDocumentevaluate 方法
  3. 打开空白页 → stealth 插件触发,所有 evasion 脚本开始注入
  4. 但注入全部被"窃听器"截获,写入 scripts 变量
  5. 关闭浏览器(浏览器其实白开了,只是为了触发插件)
  6. 用 Terser 压缩 scripts,加上文件头
  7. 输出 stealth.min.js

生成命令一行搞定:

npx extract-stealth-evasions   # 在当前目录生成 stealth.min.js

这个文件包含 16 个 evasion(反检测)模块,覆盖了所有常见的自动化检测点:

模块作用
navigator.webdriver删除 webdriver 属性(最基础的检测点)
chrome.runtime伪装 chrome.runtime(最复杂的模块)
chrome.app / csi / loadTimes补齐正常 Chrome 才有的 API
navigator.plugins伪装浏览器插件列表
navigator.languages伪装语言设置
navigator.permissions伪装权限查询结果
navigator.hardwareConcurrency伪装 CPU 核心数
iframe.contentWindow修复 iframe 跨域检测
media.codecs伪装媒体编解码器支持
window.outerdimensions伪装窗口尺寸
user-agent-override伪装 UA 和平台信息
sourceurl隐藏注入脚本的来源 URL

注入方式也很简单,通过 Chrome DevTools Protocol(CDP)在每个页面加载前自动执行:

# 读取生成好的 stealth.min.js
with open("stealth.min.js", "r") as f:
    stealth_js = f.read()

# 注入到浏览器,之后打开的每个页面都会自动执行反检测脚本
driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {"source": stealth_js})

这套方案的精髓在于:stealth.min.js 本来是为 Puppeteer(Node.js)设计的,但因为它最终只是一段纯 JS 代码,所以可以通过 CDP 注入到任何浏览器中使用,包括 Selenium 驱动的 Chrome。

第二层:账号专属浏览器指纹

基于账号 ID 生成确定性的 User-Agent 和指纹参数,同一账号每次运行指纹一致(模拟"同一个人"),不同账号指纹各异(避免关联检测):

# 每个账号生成专属 User-Agent
user_agent = get_random_user_agent(account_id)
ops.add_argument(f"--user-agent={user_agent}")

# 注入确定性浏览器指纹
fingerprint_js = generate_fingerprint_script(current_user)
driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {"source": fingerprint_js})

第二层:ddddocr,轻量级深度学习 OCR

ddddocr("带带弟弟OCR")是一个国人开源的通用验证码识别库,基于 ONNX Runtime 推理引擎。项目用到了它的两个核心能力:

功能作用对应模式
OCR 文字识别识别图案中的汉字/数字/字母DdddOcr(ocr=True)
目标检测在大图中定位所有可能的候选区域DdddOcr(det=True)

为什么选 ddddocr?

  1. 无需 GPU:基于 ONNX Runtime,纯 CPU 推理,完美适配 GitHub Actions 的免费 Runner(2核7GB内存)
  2. 超级轻量:模型仅几 MB,pip 安装即用,不需要安装 PyTorch/TensorFlow 等重型框架
  3. 准确率够用:对于中文汉字和常见图案的单字识别,准确率足以支撑多次重试策略

单例模式加载,避免 OOM

在多账号并发场景下,如果每个线程都加载一份模型,内存会瞬间炸掉。项目用了 双重检查锁定(Double-Checked Locking) 实现全局单例:

_ocr_model = None
_det_model = None
_model_lock = threading.Lock()
_inference_lock = threading.Lock()  # 推理锁,防止并发推理冲突

def get_shared_ocr_models():
    global _ocr_model, _det_model
    if _ocr_model is None or _det_model is None:
        with _model_lock:
            if _ocr_model is None or _det_model is None:
                import ddddocr
                _ocr_model = ddddocr.DdddOcr(ocr=True, show_ad=False)
                _det_model = ddddocr.DdddOcr(det=True, show_ad=False)
    return _ocr_model, _det_model

即使 10 个账号同时跑,也只加载一份模型,内存占用控制在可接受范围内。

第三层:OpenCV,多算法融合定位

光靠 ddddocr "认字"还不够。验证码里的目标可能是汉字,也可能是不规则图形、小图标甚至数字。项目设计了一套 两阶段、多算法融合 的定位策略。

阶段一:目标检测 + 智能匹配(精确优先)

  1. 下载验证码图片:Selenium 从 iframe 中提取背景大图(captcha.jpg)和 3 个目标小图(sprite.jpg,按 1/3 宽度切割为 sprite_1/2/3.jpg)
  2. 目标检测:用 ddddocr 的 det 模式扫描大图,框出所有可能包含目标的候选区域(bounding box)
  3. 逐一匹配打分:对每个"待选目标×候选区域"的组合,运行混合评分器:
    • OCR 语义匹配(最高优先级):如果目标和候选区域 OCR 识别出相同的汉字/数字/字母,直接给高分(75~100分)
    • 二值形状匹配:对目标和候选区域做二值化 → 裁切前景 → 归一化到 64×64 画布 → 计算 IoU 和轮廓相似度
    • SIFT 特征点匹配(用于不规则图形):提取 SIFT 关键点 → BFMatcher 暴力匹配 → RANSAC 单应性校验,统计几何一致的内点数
  4. 全局最优分配:用全排列搜索(3个目标 → N个候选框),找到总分最高且无冲突的组合
评分公式示意(简化版):

if OCR识别(目标) == OCR识别(候选) 且 形状分 ≥ 阈值:
    得分 = 75 + 形状分 × 25    # 语义命中,强信号
elif 形状分 ≥ 0.55:
    得分 = 形状分 × 20          # 形状高度匹配
else:
    得分 = SIFT内点数            # 几何特征兜底

阶段二:全图边缘模板降级搜索(鲁棒兜底)

如果阶段一的总置信分低于阈值(比如候选框截得不准,或者背景太花导致目标检测遗漏),系统会自动降级到 全图扫描模式

  1. 连通域分析:对验证码大图做多级灰度阈值二值化,用 cv2.connectedComponentsWithStats 提取所有暗色连通域,按面积过滤出合理大小的候选
  2. Canny 边缘模板匹配:对目标图案和大图分别提取 Canny 边缘轮廓,施加多角度旋转(±15°),用 cv2.matchTemplate 做归一化互相关匹配
  3. 字形专用的二值模板匹配:如果目标被识别为"字形"(文字/数字),额外启用基于二值 mask 的旋转模板匹配

最终,从全图搜索的候选中选出总分最高、且彼此距离足够远的 3 个点作为点击坐标。

这个两阶段设计的核心思想是:能精确就精确(快),精确不了就暴力搜索(稳)

坐标转换与精准点击

找到目标在原始图片中的像素坐标后,还需要转换为浏览器中的实际点击位置。因为验证码图片在 DOM 中的渲染尺寸和原始图片尺寸可能不同:

# 原始图片坐标 → DOM 渲染坐标
width_raw, height_raw = captcha.shape[1], captcha.shape[0]   # 原图尺寸
width, height = float(get_width_from_style(style)), ...       # DOM渲染尺寸
final_x = int(-width/2 + x / width_raw * width)              # 相对于元素中心的偏移
final_y = int(-height/2 + y / height_raw * height)

# 使用 ActionChains 移动到精确位置并点击
ActionChains(driver).move_to_element_with_offset(slideBg, final_x, final_y).click().perform()

失败了怎么办?自动重试机制详解

雨云签到验证码的识别率不可能 100%。原作者给出的经不严谨测试数据是约 48.3% 单次通过率。但这完全不是问题,因为项目内置了 多级自动重试

验证码级别重试(换一张图再来)

每次验证码提交后,脚本会检查结果元素的 class 属性:

这个过程是递归式的,只要浏览器还活着,就会不断重试。

账号级别重试(从头再来)

如果整个签到流程失败(网络超时、页面结构变化等),外层还有账号级别的重试机制:

算个账:单次通过率 48.3%,3 次验证码级重试的通过率 = 1 - (1-0.483)³ ≈ 86.2%,再叠加 3 次账号级重试,最终成功率趋近 99%+


增强稳定性的实用技巧

如果你已经搭建好了基础签到教程,以下几个进阶配置可以进一步提升稳定性:

1. 配置代理 IP 防封(PROXY_API_URL

如果你有多个账号,它们从同一个 GitHub Actions Runner 出发,IP 是一样的。大量签到请求从同一 IP 发出,可能触发雨云的风控。

配置 PROXY_API_URL 后,每个账号签到前会单独请求一次代理接口获取新 IP,实现 "一号一IP"。即使代理获取失败,也会自动降级用本地 IP 继续,不会因为代理问题导致签到失败。

2. Cookie 持久化免登录

项目利用 GitHub Actions Cache 缓存登录后的 Cookie。好处是:

Cookie 以 JSON 格式保存在 temp/cookies/ 目录,文件名基于账号哈希生成,不泄露原始账号信息。

3. 无头模式窗口尺寸的重要性

很多人跑 headless 浏览器时会忽略窗口大小设置,导致默认窗口很小(通常 800×600)。这会引起严重的验证码识别问题:

项目强制设置 --window-size=1920,1080,确保在无头模式下也有标准的 1080p 渲染空间。

4. 截图策略选择

通过 SCREENSHOT_MODE 环境变量控制:

此外,验证码识别失败时,脚本会自动保存一个"调试包"到 logs/captcha_debug/ 目录,里面包含原始验证码图片、目标图块、元数据 JSON 等,非常方便开发者排查问题。


常见疑问解答

Q: 这套方案在 GitHub Actions 上跑真的免费吗?

是的。GitHub Actions 对公开仓库提供 无限免费额度(私有仓库才有每月 2000 分钟的限制),单次签到耗时约 3~5 分钟,完全不需要担心额度问题。ddddocr 模型推理也完全在 Runner 的 CPU 上完成,不需要任何外部 API 调用。

Q: ddddocr 能识别所有验证码类型吗?

不能。ddddocr 擅长中文汉字、英文字母、数字的单字识别。对于复杂的不规则图形(如"点击所有帽子"),项目靠的是 OpenCV 的 SIFT 特征匹配和 Canny 边缘匹配来弥补。这也是为什么项目要设计多算法融合的原因,没有银弹,但组合拳可以打得很稳

Q: 验证码更新了怎么办?

腾讯 TCaptcha 的底层框架相对稳定(验证码图片都在 #slideBg 元素中),只要页面结构不发生大改,脚本就能继续工作。如果遇到兼容性问题,我们会第一时间更新适配,欢迎到 GitHub 仓库 提 Issue 反馈。

Q: 2captcha 等打码平台还有必要用吗?

在雨云签到这个场景下,完全没必要。本方案的 ddddocr 本地识别已经是雨云2captcha签到的完美替代,零成本、低延迟、无隐私风险。除非你需要破解 reCAPTCHA v3 这类纯行为分析型验证码,才需要考虑付费平台。


总结

技术组件角色关键特性
Selenium浏览器自动化无头模式、stealth.js 反检测、账号专属指纹
ddddocr文字/目标识别CPU 推理、双模型单例、线程安全推理锁
OpenCV图像匹配定位SIFT+RANSAC、Canny边缘模板、连通域分析、二值形状IoU
重试机制容错保障验证码级递归重试 + 账号级定时重试
Cookie 缓存减少风控Actions Cache 持久化、哈希命名、自动失效检测

这套雨云自动签到验证码版方案的精髓在于:不追求单次 100% 的识别率,而是通过多算法融合 + 多级重试,把最终成功率推到 99% 以上

如果你还没搭建过基础的自动签到,请先参考:《2026年最新 教你0元搭建雨云自动签到,每日自动领积分续费(保姆级教程)》,3 步即可完成部署。

仓库地址:https://github.com/LeapYa/Rainyun-Qiandao
觉得有用的话,别忘了给仓库点个 Star ⭐!


🚨 法律风险提示:本文涉及的自动化签到及验证码识别技术可能违反雨云平台《用户协议》及相关服务条款,存在账号封禁、积分清零等风险。此类技术方案属于灰色地带,仅供学习 Selenium 自动化、OCR 识别及计算机视觉技术原理,请勿用于生产环境或大规模商业用途。使用即视为您已充分评估风险并自愿承担后果。