python selenium 模拟实现滑块验证码

canndy_test.py
import cv2
import numpy as np


def matchImg(imgPath1, imgPath2):
    imgs = []

    # 原始图像,用于展示
    sou_img1 = cv2.imread(imgPath1)
    sou_img2 = cv2.imread(imgPath2)

    # 原始图像,灰度
    # 最小阈值100,最大阈值500
    img1 = cv2.imread(imgPath1, 0)
    blur1 = cv2.GaussianBlur(img1, (5, 5), 0)
    canny1 = cv2.Canny(blur1, 120, 500)
    cv2.imwrite('temp1.png', canny1)

    img2 = cv2.imread(imgPath2, 0)
    blur2 = cv2.GaussianBlur(img2, (5, 5), 0)
    canny2 = cv2.Canny(blur2, 120, 500)
    cv2.imwrite('temp2.png', canny2)

    target = cv2.imread('temp1.png')
    template = cv2.imread('temp2.png')

    # 调整显示大小
    target_temp = cv2.resize(sou_img1, (250, 250))
    target_temp = cv2.copyMakeBorder(target_temp, 5, 5, 5, 5, cv2.BORDER_CONSTANT, value=[255, 255, 255])

    template_temp = cv2.resize(sou_img2, (250, 250))
    template_temp = cv2.copyMakeBorder(template_temp, 5, 5, 5, 5, cv2.BORDER_CONSTANT, value=[255, 255, 255])

    imgs.append(target_temp)
    imgs.append(template_temp)

    theight, twidth = template.shape[:2]

    # 匹配拼图
    result = cv2.matchTemplate(target, template, cv2.TM_CCOEFF_NORMED)

    # 归一化
    cv2.normalize(result, result, 0, 1, cv2.NORM_MINMAX, -1)

    min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
    # 如果不需要看后面的效果,只要返回位置,把下面的注释去掉
    return max_loc[0]


def fix_img(filename):
    # 获取滑块的大小
    #  1.为了更高的准确率,使用二值图像
    img = cv2.imread(filename)
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    _, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
    # 2.将轮廓提取出来
    contours, _ = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
    # 3.用绿色(0, 255, 0)来画出最小的矩形框架
    x, y, w, h = cv2.boundingRect(contours[0])
    rect_x = x + w
    rect_y = y + h
    # print(x, y, rect_x, rect_y)  # x,y是矩阵左上点的坐标,w,h是矩阵的宽和高
    rect_img = cv2.rectangle(img, (x, y), (rect_x, rect_y), (0, 255, 0), 1)
    # 3.根据滑块的高度和宽度进行截图
    mixintu = rect_img[y:rect_y, x:rect_x]
    return mixintu


def compute_gap(fadebg, fullbg):
    # 1.对滑块进行图片处理
    tp_img = fix_img(fadebg)  # 裁掉透明部分,找出滑块的大小
    tp_pic = cv2.cvtColor(cv2.Canny(tp_img, 100, 200), cv2.COLOR_GRAY2BGR)
    # 2.对背景进行图片处理
    bg_pic = cv2.cvtColor(cv2.Canny(cv2.imread(fullbg), 100, 200), cv2.COLOR_GRAY2BGR)
    # 3.模板匹配matchTemplate
    res = cv2.matchTemplate(bg_pic, tp_pic, cv2.TM_CCOEFF_NORMED)
    min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
    # print(min_val, max_val, min_loc, max_loc)  # 最小值,最大值,最小值的位置,最大值的位置
    # 返回滑块移动距离
    return max_loc[0]

webmethod.py

from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.by import By
import time
import base64
from canndy_test import compute_gap
from selenium import webdriver

url = "https://xxxxxxxxxxxx/admin-web/#/login"
account = "admin"
password = "123456"
username_input = '[placeholder="请输入用户名"]'
password_input = '[placeholder="请输入密码"]'
login_button = '[class="login-submit"]'
# 获取谷歌驱动
driver = webdriver.Chrome()
# 打开网址
driver.get(url)
# 窗口最大化
driver.maximize_window()
# 等待元素加载完成
driver.implicitly_wait(20)
# 输入账号
driver.find_element(By.CSS_SELECTOR, username_input).send_keys(account)
# 输入密码
driver.find_element(By.CSS_SELECTOR, password_input).send_keys(password)
# 点击登录
driver.find_element(By.CSS_SELECTOR, login_button).click()
time.sleep(4)


def skip_code():
    """
    滑动滑块
    """
    time.sleep(3)

    flag = 1
    # 如果没有滑动成功,将一直重新定位并滑动滑块,直到进入系统
    while flag:
        try:
            # 获取背景图src
            targetUrl1 = driver.find_elements(By.TAG_NAME, 'img')[1].get_attribute('src')  # 定位背景图片元素,并获取该元素src属性值
            imgData = base64.b64decode(targetUrl1.split(',')[1])  # 获取的src属性经过base64编码了,所以需要解码
            with open('targetUrl.png', 'wb') as file:        # 保存到当前目录
                file.write(imgData)

            # 获取拼图src
            tempUrl2 = driver.find_elements(By.TAG_NAME, 'img')[2].get_attribute('src')
            imgData = base64.b64decode(tempUrl2.split(',')[1])
            with open('tempUrl.png', 'wb') as file:
                file.write(imgData)

            # 计算移动距离
            move = compute_gap('tempUrl.png', 'targetUrl.png')

            distance = int(move + 13.5)    # 计算出的move会有偏差,所以这里需要反复实验出实际值
            # 查找滑动箭头元素
            draggable = driver.find_element(By.CSS_SELECTOR, '[class="verify-move-block"]')
            # 将鼠标悬停在滑动箭头元素上
            ActionChains(driver).click_and_hold(draggable).perform()

            # 拖动
            ActionChains(driver).move_by_offset(xoffset=distance, yoffset=0).perform()

            ActionChains(driver).release().perform()
            time.sleep(2)

        except:
            flag = 0

    time.sleep(2)
    # 关闭浏览器
    driver.quit()


skip_code()

 

posted @ 2023-06-09 17:00  **绵绵羊**  阅读(509)  评论(0编辑  收藏  举报