WebUI自动化处理滑块验证码的方法/思路

from playwright.sync_api import sync_playwright
import cv2  # OpenCV库
import numpy as np
import time

def calculate_slide_distance(bg_path, slide_path):
    """使用OpenCV计算滑动距离"""
    # 读取背景图和滑块图
    bg_img = cv2.imread(bg_path)
    slide_img = cv2.imread(slide_path)

    # 转换为灰度图
    bg_gray = cv2.cvtColor(bg_img, cv2.COLOR_BGR2GRAY)
    slide_gray = cv2.cvtColor(slide_img, cv2.COLOR_BGR2GRAY)

    # 使用模板匹配算法
    res = cv2.matchTemplate(bg_gray, slide_gray, cv2.TM_CCOEFF_NORMED)
    _, max_val, _, max_loc = cv2.minMaxLoc(res)  # 获取最佳匹配位置

    print(f"匹配度:{max_val},建议阈值>0.4")
    return max_loc[0]  # 返回缺口x坐标

def drag_slider(page, slider, distance):
    """执行滑动操作"""
    slider_box = slider.bounding_box()
    
    # 计算起始位置(滑块中心)
    start_x = slider_box['x'] + slider_box['width']/2
    start_y = slider_box['y'] + slider_box['height']/2
    
    # 模拟人类滑动轨迹
    page.mouse.move(start_x, start_y)
    page.mouse.down()
    
    # 添加随机抖动
    steps = int(distance / 2)  # 控制步数
    for i in range(steps):
        x = start_x + (i * distance/steps) + np.random.uniform(-2,2)
        y = start_y + np.random.uniform(-1,1)
        page.mouse.move(x, y)
        time.sleep(0.05)
    
    # 最后小幅回拉模拟真实操作
    page.mouse.move(start_x + distance - 3, start_y)
    time.sleep(0.1)
    page.mouse.up()

def test_slide_verification():
    with sync_playwright() as p:
        browser = p.chromium.launch(headless=False)
        page = browser.new_page()
        
        try:
            page.goto("https://your-registration-page.com")
            
            # 1.获取验证码元素
            bg_element = page.locator(".captcha-bg")  # 背景图选择器
            slide_element = page.locator(".captcha-slide")  # 滑块图选择器
            
            # 2.截图保存元素图片
            bg_element.screenshot(path="bg.png")
            slide_element.screenshot(path="slide.png")
            
            # 3.计算滑动距离
            distance = calculate_slide_distance("bg.png", "slide.png")
            print(f"计算得到的滑动距离:{distance}px")
            
            # 4.获取滑动轨道元素
            slider_track = page.locator(".slider-track")  # 滑动轨道选择器
            
            # 5.执行滑动操作(需根据实际页面结构调整偏移量)
            drag_slider(page, slider_track, distance + 10)  # +10px补偿误差
            
            # 验证是否成功
            success = page.locator(".captcha-success").is_visible(timeout=3000)
            assert success, "滑动验证失败"
            
        finally:
            browser.close()

if __name__ == "__main__":
    test_slide_verification()

关键实现说明:

  1. 图像识别核心

    • 使用OpenCV的模板匹配算法(matchTemplate

    • 通过对比背景图和滑块图找到缺口位置

    • 返回需要滑动的像素距离

  2. 滑动轨迹模拟

    • 添加随机抖动(np.random.uniform

    • 分步移动鼠标模拟人类操作

    • 最终回拉3px增加成功率

  3. 注意事项

    • 需要安装OpenCV:pip install opencv-python

    • 页面元素选择器需要根据实际情况调整

    • 可能需要添加补偿值(不同网站的缺口位置偏移量不同)

    • 建议设置匹配度阈值(一般>0.4有效)

增强方案:

# 在calculate_slide_distance函数中添加阈值判断
if max_val < 0.4:
    raise Exception("图像匹配度不足,可能验证码已更新")

# 在drag_slider函数中添加重试机制
for attempt in range(3):
    drag_slider(...)
    if page.locator(".captcha-success").is_visible():
        break
else:
    assert False, "滑动验证三次尝试均失败"

 

常见问题处理:

  1. 验证码更新

    • 每次操作前重新截图

    • 添加失败重试逻辑

  2. 动态阴影干扰

# 在图像处理前添加高斯模糊
bg_gray = cv2.GaussianBlur(bg_gray, (3,3), 0)
slide_gray = cv2.GaussianBlur(slide_gray, (3,3), 0)

  3. 多缺口验证码

# 在calculate_slide_distance函数中处理多个匹配结果
threshold = 0.4
loc = np.where(res >= threshold)
return loc[0][0]  # 取第一个匹配结果

该方案通过动态图像识别实现滑动验证,可适应不同滑动距离的场景。建议配合以下措施:

  1. 与开发团队确认测试环境验证策略

  2. 添加测试专用验证码白名单

  3. 在CI/CD中配置Headless模式运行

posted @ 2026-06-04 14:21  术科术  阅读(37)  评论(0)    收藏  举报