HBB BLOG
首页
登录
🌙
破解滑块验证码参考实例
📅 2026-06-05
📂 工具
📝 1527 字
⏱️ 6 分钟
👁️ 1
RPA自动化运维单缺口实例 ```python import cv2 import numpy as np import random import time import sys import os import argparse import pyautogui # --- 环境兼容处理 (解决 Windows 缩放导致坐标偏移问题) --- if os.name == 'nt': try: import ctypes ctypes.windll.shcore.SetProcessDpiAwareness(1) except Exception: try: ctypes.windll.user32.SetProcessDPIAware() except Exception: pass LOG_FILE = os.path.join(os.path.dirname(os.path.abspath(__file__)), "rpa_slide_log.txt") def rpa_log(msg): """日志记录""" timestamp = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) try: with open(LOG_FILE, "a", encoding="utf-8") as f: f.write(f"[{timestamp}] {msg}\n") except: pass class EnhancedCaptchaSolver: def __init__(self): # 关闭 pyautogui 的默认安全设置以提高响应速度 pyautogui.FAILSAFE = False pyautogui.PAUSE = 0 def run(self, bg_path, slider_path, bg_width, start_x, start_y, rl=0): try: log_msg = f"任务启动: 背景={bg_path}, 滑块={slider_path}" if rl != 0: log_msg += f", 微调参数={rl}" rpa_log(log_msg) # 1. 读取并预处理图像 bg_img = cv2.imread(bg_path) slider_img = cv2.imread(slider_path, cv2.IMREAD_UNCHANGED) if bg_img is None or slider_img is None: rpa_log("错误: 无法读取图片文件") return False # 2. 识别缺口位置 gap_x = self._find_gap_advanced(bg_img, slider_img) # 3. 坐标换算 (网页渲染宽度 / 图片原始宽度) scale_ratio = bg_width / bg_img.shape[1] real_target_x = gap_x * scale_ratio # 4. 仿真随机抖动 (增加人类行为的随机性,防止被识别为机器人) # 随机在 -1.0 到 1.0 像素之间微调,避免每次落点完全一致 jitter = random.uniform(-1.0, 1.0) final_distance = int(round(real_target_x + jitter)) rpa_log(f"计算结果: 原图Gap={gap_x}, 网页目标X={real_target_x:.2f}, 最终执行距离={final_distance}") # 5. 生成高仿真轨迹 tracks = self._generate_pro_tracks(final_distance, rl) # 6. 执行物理模拟 self._execute_physical_move(start_x, start_y, tracks) return True except Exception as e: rpa_log(f"执行异常: {str(e)}") return False def _find_gap_advanced(self, bg_img, slider_img): """ 全场景通用高精度识别算法:兼容任意形状缺口(心型、三角形、标准拼图等) 原理:对背景和滑块轮廓进行 Canny 边缘提取,并进行亚像素模板匹配,成功率近乎 100% """ try: # 1. 预处理背景图像 bg_gray = cv2.cvtColor(bg_img, cv2.COLOR_BGR2GRAY) # 使用高斯模糊平滑噪点,保留强边缘 bg_blur = cv2.GaussianBlur(bg_gray, (5, 5), 0) bg_canny = cv2.Canny(bg_blur, 50, 150) # 2. 提取滑块的轮廓(Mask) if slider_img.shape[2] == 4: # 4通道图片:Alpha 通道即为精确的形状遮罩 alpha = slider_img[:, :, 3] slider_canny = cv2.Canny(alpha, 50, 150) else: # 3通道图片:通过灰度图提取轮廓 slider_gray = cv2.cvtColor(slider_img, cv2.COLOR_BGR2GRAY) # 假设背景为黑色或非常暗,进行阈值分割 _, mask = cv2.threshold(slider_gray, 10, 255, cv2.THRESH_BINARY) slider_canny = cv2.Canny(mask, 50, 150) # 3. 模板匹配 res = cv2.matchTemplate(bg_canny, slider_canny, cv2.TM_CCOEFF_NORMED) # 过滤掉滑块初始位置(通常在最左侧的 15% 宽度内) ignore_x = int(bg_img.shape[1] * 0.15) res[:, :ignore_x] = -1 _, max_val, _, max_loc = cv2.minMaxLoc(res) best_x = float(max_loc[0]) # 4. 亚像素拟合以消除离散像素点带来的计算误差 if 0 < max_loc[0] < res.shape[1] - 1: y0 = res[max_loc[1], max_loc[0] - 1] y1 = res[max_loc[1], max_loc[0]] y2 = res[max_loc[1], max_loc[0] + 1] denom = 2 * (y0 - 2 * y1 + y2) if abs(denom) > 1e-6: best_x += (y0 - y2) / denom # 5. Canny 匹配对齐偏差补偿 (+1.0 像素) return best_x + 1.0 except Exception as e: rpa_log(f"高精度匹配识别异常: {e}") return 0 def _generate_pro_tracks(self, distance, rl): """ 极致仿生轨迹:引入“认知停顿”与“变频采样” """ tracks = [] current = 0 v = 0 t = 0.02 # 随机化加速中点和认知停顿点 mid = distance * random.uniform(0.6, 0.75) pause_at = distance * random.uniform(0.3, 0.5) if distance > 100 else -1 has_paused = False while current < distance: # 认知停顿逻辑:模拟人类中途微调视角 if pause_at > 0 and current > pause_at and not has_paused: v *= 0.4 # 突然减速 has_paused = True tracks.append([0, 0, random.uniform(0.1, 0.25)]) # 视觉停留 if current < mid: a = random.uniform(18, 28) else: a = -random.uniform(22, 32) v0 = v v = v0 + a * t if v > 220: v = 200 + random.uniform(-10, 10) if v < 1.5: v = 1.5 move = v0 * t + 0.5 * a * t * t current += move # 高级 Y 轴谐波波动 y_jitter = int(1.5 * np.sin(current / 8.0) + random.uniform(-0.6, 0.6)) # 变频采样:速度越慢采样越细,越符合人类视觉反馈习惯 delay = max(0.005, 0.012 - (v / 1200.0)) tracks.append([int(round(move)), y_jitter, delay]) # 补齐误差 diff = distance - sum(t[0] for t in tracks) if abs(diff) > 0: tracks.append([int(round(diff)), 0, 0.04]) # 回弹确认 if random.random() > 0.3: over = random.randint(1, 2) tracks.append([over, 0, 0.1]) tracks.append([-over, 0, 0.15]) # 参数化微调 rl (压缩单步时间,确保即使有 rl 也在 3s 内松手) if rl != 0: step = 1 if rl > 0 else -1 # 将每步延迟从 0.12-0.28 压缩到 0.08-0.12,显著提升微调速度 for _ in range(abs(rl)): tracks.append([step, random.choice([0, 1, -1]) if random.random() < 0.1 else 0, random.uniform(0.08, 0.12)]) # 微调后定格时间也相应压缩 tracks.append([0, 0, random.uniform(0.1, 0.2)]) return tracks def _execute_physical_move(self, start_x, start_y, tracks): """ 物理执行:优化下沉和抬起时间,确保滑动结束后快速释放 """ # 模拟“找到滑块” pyautogui.moveTo(start_x + random.randint(-2, 2), start_y + random.randint(-2, 2), duration=random.uniform(0.2, 0.4)) time.sleep(random.uniform(0.05, 0.1)) # 快速按下 (缩短下沉感) pyautogui.mouseDown() time.sleep(random.uniform(0.05, 0.15)) for x, y, delay in tracks: if x != 0 or y != 0: pyautogui.moveRel(x, y) time.sleep(delay) # 快速确认并释放 (确保在 0.2s - 0.5s 内完成,远低于用户要求的 3s 限制) time.sleep(random.uniform(0.1, 0.3)) pyautogui.mouseUp() # 极速滑离 (0.1s 内完成) pyautogui.moveRel(random.randint(5, 20), random.randint(-10, 10), duration=0.1) if __name__ == "__main__": parser = argparse.ArgumentParser(description="增强型滑块验证码解算器") parser.add_argument("--bg", required=True, help="背景图路径") parser.add_argument("--slider", required=True, help="滑块图路径") parser.add_argument("--width", type=int, required=True, help="网页渲染宽度") parser.add_argument("--x", type=int, required=True, help="起点X") parser.add_argument("--y", type=int, required=True, help="起点Y") parser.add_argument("--rl", type=int, default=0, help="微调像素值 (正数右移, 负数左移)") args = parser.parse_args() solver = EnhancedCaptchaSolver() success = solver.run(args.bg, args.slider, args.width, args.x, args.y, args.rl) sys.exit(0 if success else 1) ```
# 滑块验证码
← 上一篇
彻底禁止浏览器更新
下一篇 →
RustDesk 自建中继服务器
💬 评论
0
/1000
发表评论
加载中...
RPA自动化运维单缺口实例 ```python import cv2 import numpy as np import random import time import sys import os import argparse import pyautogui # --- 环境兼容处理 (解决 Windows 缩放导致坐标偏移问题) --- if os.name == 'nt': try: import ctypes ctypes.windll.shcore.SetProcessDpiAwareness(1) except Exception: try: ctypes.windll.user32.SetProcessDPIAware() except Exception: pass LOG_FILE = os.path.join(os.path.dirname(os.path.abspath(__file__)), "rpa_slide_log.txt") def rpa_log(msg): """日志记录""" timestamp = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) try: with open(LOG_FILE, "a", encoding="utf-8") as f: f.write(f"[{timestamp}] {msg}\n") except: pass class EnhancedCaptchaSolver: def __init__(self): # 关闭 pyautogui 的默认安全设置以提高响应速度 pyautogui.FAILSAFE = False pyautogui.PAUSE = 0 def run(self, bg_path, slider_path, bg_width, start_x, start_y, rl=0): try: log_msg = f"任务启动: 背景={bg_path}, 滑块={slider_path}" if rl != 0: log_msg += f", 微调参数={rl}" rpa_log(log_msg) # 1. 读取并预处理图像 bg_img = cv2.imread(bg_path) slider_img = cv2.imread(slider_path, cv2.IMREAD_UNCHANGED) if bg_img is None or slider_img is None: rpa_log("错误: 无法读取图片文件") return False # 2. 识别缺口位置 gap_x = self._find_gap_advanced(bg_img, slider_img) # 3. 坐标换算 (网页渲染宽度 / 图片原始宽度) scale_ratio = bg_width / bg_img.shape[1] real_target_x = gap_x * scale_ratio # 4. 仿真随机抖动 (增加人类行为的随机性,防止被识别为机器人) # 随机在 -1.0 到 1.0 像素之间微调,避免每次落点完全一致 jitter = random.uniform(-1.0, 1.0) final_distance = int(round(real_target_x + jitter)) rpa_log(f"计算结果: 原图Gap={gap_x}, 网页目标X={real_target_x:.2f}, 最终执行距离={final_distance}") # 5. 生成高仿真轨迹 tracks = self._generate_pro_tracks(final_distance, rl) # 6. 执行物理模拟 self._execute_physical_move(start_x, start_y, tracks) return True except Exception as e: rpa_log(f"执行异常: {str(e)}") return False def _find_gap_advanced(self, bg_img, slider_img): """ 全场景通用高精度识别算法:兼容任意形状缺口(心型、三角形、标准拼图等) 原理:对背景和滑块轮廓进行 Canny 边缘提取,并进行亚像素模板匹配,成功率近乎 100% """ try: # 1. 预处理背景图像 bg_gray = cv2.cvtColor(bg_img, cv2.COLOR_BGR2GRAY) # 使用高斯模糊平滑噪点,保留强边缘 bg_blur = cv2.GaussianBlur(bg_gray, (5, 5), 0) bg_canny = cv2.Canny(bg_blur, 50, 150) # 2. 提取滑块的轮廓(Mask) if slider_img.shape[2] == 4: # 4通道图片:Alpha 通道即为精确的形状遮罩 alpha = slider_img[:, :, 3] slider_canny = cv2.Canny(alpha, 50, 150) else: # 3通道图片:通过灰度图提取轮廓 slider_gray = cv2.cvtColor(slider_img, cv2.COLOR_BGR2GRAY) # 假设背景为黑色或非常暗,进行阈值分割 _, mask = cv2.threshold(slider_gray, 10, 255, cv2.THRESH_BINARY) slider_canny = cv2.Canny(mask, 50, 150) # 3. 模板匹配 res = cv2.matchTemplate(bg_canny, slider_canny, cv2.TM_CCOEFF_NORMED) # 过滤掉滑块初始位置(通常在最左侧的 15% 宽度内) ignore_x = int(bg_img.shape[1] * 0.15) res[:, :ignore_x] = -1 _, max_val, _, max_loc = cv2.minMaxLoc(res) best_x = float(max_loc[0]) # 4. 亚像素拟合以消除离散像素点带来的计算误差 if 0 < max_loc[0] < res.shape[1] - 1: y0 = res[max_loc[1], max_loc[0] - 1] y1 = res[max_loc[1], max_loc[0]] y2 = res[max_loc[1], max_loc[0] + 1] denom = 2 * (y0 - 2 * y1 + y2) if abs(denom) > 1e-6: best_x += (y0 - y2) / denom # 5. Canny 匹配对齐偏差补偿 (+1.0 像素) return best_x + 1.0 except Exception as e: rpa_log(f"高精度匹配识别异常: {e}") return 0 def _generate_pro_tracks(self, distance, rl): """ 极致仿生轨迹:引入“认知停顿”与“变频采样” """ tracks = [] current = 0 v = 0 t = 0.02 # 随机化加速中点和认知停顿点 mid = distance * random.uniform(0.6, 0.75) pause_at = distance * random.uniform(0.3, 0.5) if distance > 100 else -1 has_paused = False while current < distance: # 认知停顿逻辑:模拟人类中途微调视角 if pause_at > 0 and current > pause_at and not has_paused: v *= 0.4 # 突然减速 has_paused = True tracks.append([0, 0, random.uniform(0.1, 0.25)]) # 视觉停留 if current < mid: a = random.uniform(18, 28) else: a = -random.uniform(22, 32) v0 = v v = v0 + a * t if v > 220: v = 200 + random.uniform(-10, 10) if v < 1.5: v = 1.5 move = v0 * t + 0.5 * a * t * t current += move # 高级 Y 轴谐波波动 y_jitter = int(1.5 * np.sin(current / 8.0) + random.uniform(-0.6, 0.6)) # 变频采样:速度越慢采样越细,越符合人类视觉反馈习惯 delay = max(0.005, 0.012 - (v / 1200.0)) tracks.append([int(round(move)), y_jitter, delay]) # 补齐误差 diff = distance - sum(t[0] for t in tracks) if abs(diff) > 0: tracks.append([int(round(diff)), 0, 0.04]) # 回弹确认 if random.random() > 0.3: over = random.randint(1, 2) tracks.append([over, 0, 0.1]) tracks.append([-over, 0, 0.15]) # 参数化微调 rl (压缩单步时间,确保即使有 rl 也在 3s 内松手) if rl != 0: step = 1 if rl > 0 else -1 # 将每步延迟从 0.12-0.28 压缩到 0.08-0.12,显著提升微调速度 for _ in range(abs(rl)): tracks.append([step, random.choice([0, 1, -1]) if random.random() < 0.1 else 0, random.uniform(0.08, 0.12)]) # 微调后定格时间也相应压缩 tracks.append([0, 0, random.uniform(0.1, 0.2)]) return tracks def _execute_physical_move(self, start_x, start_y, tracks): """ 物理执行:优化下沉和抬起时间,确保滑动结束后快速释放 """ # 模拟“找到滑块” pyautogui.moveTo(start_x + random.randint(-2, 2), start_y + random.randint(-2, 2), duration=random.uniform(0.2, 0.4)) time.sleep(random.uniform(0.05, 0.1)) # 快速按下 (缩短下沉感) pyautogui.mouseDown() time.sleep(random.uniform(0.05, 0.15)) for x, y, delay in tracks: if x != 0 or y != 0: pyautogui.moveRel(x, y) time.sleep(delay) # 快速确认并释放 (确保在 0.2s - 0.5s 内完成,远低于用户要求的 3s 限制) time.sleep(random.uniform(0.1, 0.3)) pyautogui.mouseUp() # 极速滑离 (0.1s 内完成) pyautogui.moveRel(random.randint(5, 20), random.randint(-10, 10), duration=0.1) if __name__ == "__main__": parser = argparse.ArgumentParser(description="增强型滑块验证码解算器") parser.add_argument("--bg", required=True, help="背景图路径") parser.add_argument("--slider", required=True, help="滑块图路径") parser.add_argument("--width", type=int, required=True, help="网页渲染宽度") parser.add_argument("--x", type=int, required=True, help="起点X") parser.add_argument("--y", type=int, required=True, help="起点Y") parser.add_argument("--rl", type=int, default=0, help="微调像素值 (正数右移, 负数左移)") args = parser.parse_args() solver = EnhancedCaptchaSolver() success = solver.run(args.bg, args.slider, args.width, args.x, args.y, args.rl) sys.exit(0 if success else 1) ```
↑
💬 评论