滑动验证码(无原图片处理)

滑动验证码(无原图片处理)

 

 

    from _pytest.mark import param from seleniumbase.config import settings from urllib3 import request from pageobject.basepage import BasePage import allure from PIL import Image from io import BytesIO import re import random import base64 from tools import common from selenium.webdriver import ActionChains import cv2 from pageobject.page.navigation_bar import Navigation import requests import settings import json import time

class Login(BasePage):     url = '/login'     usernameInput = "//input[@name='username']"     passwordInput = "//input[@name='password']"     loginButton = "//input[@value='登录']/.."     slider = "//div[@id='slider']"     smallImageblocks = "//img[@class='smallImageblocks']"     bgImage = "//img[@class='bgImage']"
    def open(self):         '''         打开账号密码登录页         '''         self._open(self.url)
    def type_name(self, value):         '''         输入用户名         '''         self.input(self.usernameInput, value)
    def type_pw(self, value):         '''         输入密码         '''         self.input(self.passwordInput, value)
    def click_login(self):         '''         点击登录         '''         self.click(self.loginButton)
    def hover_slider(self):         '''         停留在滑块上,并设置图片可见         '''         self.hover_on_element(self.slider)         self.set_attribute(self.bgImage+"/..", 'class', 'slidePanel')
    def set_slider_success(self):         '''         设置图片验证成功         '''         self.set_attribute(self.slider+"/../..", 'class',                            "sliderContainer sliderContainer_success")

class VerificationCode(Login):     def get_img(self, loc):         '''         获取图片         :param driver:         :param div_class:         :param num:         :return:         '''         imge_url = ''         location = {}         imge_url = self.get_attribute(loc, 'src')         try:             location['x'] = re.findall(                 r'padding-top: (.*?)px;', self.get_attribute(loc, 'style'))[0]         except Exception:             location['x'] = 0         try:             location['y'] = re.findall(                 r'padding-top: (.*?)px; left: (.*?)px;', self.get_attribute(loc, 'style'))[1]         except Exception:             location['y'] = 0         b64_data = imge_url.split(';base64,')[1]         data = base64.b64decode(b64_data)         img_content = BytesIO(data)         image = Image.open(img_content)         image = image.convert('RGB')         name = f'{common.dir}/file/temporary/{str(random.randint(1, 100))}.jpg'         image.save(name)         return name
    def get_track(self, x):         '''         滑块移动轨迹         初速度 v =0         单位时间 t = 0.2         位移轨迹 tracks = []         当前位移 ccurrent = 0         :param x:         :return:         '''         # 移动轨迹, 即每次移动的距离,为一个列表,总和等于偏移量         track = []         # 当前位移, 也即记录当前移动了多少距离         current = 0         # 减速阈值, 也即开始减速的位置,这里设置为偏移量的9/10处开始减速,可以更改         # mid = x * 4 / 5         # 计算用的时间间隔         t = 1         # 初始速度         v = 1
        while current < x:             # if current < mid:             #     # 当前位移小于4/5的偏移量时,加速度为2             #     a = 1             # else:             #     # 当前位移大于4/5的偏移量时,加速度为-3             #     a = -3             # a = 0             # # 初始速度v0             # v0 = v             # # 本次移动完成之后的速度v = v0 + at             # v = v0 + a * t             # # 本次移动距离x = v0t + 1/2 * a * t^2             # move = v0 * t + 1 / 2 * a * t * t             move = v * t             # 当前位移, 这里都将move四舍五入取整             current += round(move)             # 将move的距离放入轨迹列表             track.append(round(move))             # print("轨迹列表:", track)         return track
    def exchange(self, image):         image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)         for row in range(0, image.shape[0]):             for col in range(0, image.shape[1]):                 m = image[row][col]/255.00                 if m <= 0.2700:                     image[row][col] = 0                 elif m > 0.2700 and m <= 0.5000:                     image[row][col] = (m-0.27)/0.23*127                 elif m > 0.5000 and m <= 0.7200:                     image[row][col] = (m-0.5)/0.22*255+(0.72-m)/0.22*127                 else:                     image[row][col] = 255         return image
    def identify_gap(self, bg, tp, out):         '''         获取缺口位置         bg: 背景图片         tp: 缺口图片         out:输出图片         '''         # 读取背景图片和缺口图片         bg_img = cv2.imread(bg)  # 背景图片         tp_img = cv2.imread(tp)  # 缺口图片         # time.sleep(1)         # bg_img = self.exchange(bg_img)         # tp_img = self.exchange(tp_img)
        # 识别图片边缘         bg_edge = cv2.Canny(bg_img, 100, 200)         tp_edge = cv2.Canny(tp_img, 100, 200)         # 转换图片格式         bg_pic = cv2.cvtColor(bg_edge, cv2.COLOR_GRAY2RGB)         tp_pic = cv2.cvtColor(tp_edge, cv2.COLOR_GRAY2RGB)
        # 缺口匹配         res = cv2.matchTemplate(bg_pic, tp_pic, cv2.TM_CCOEFF_NORMED)         min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)  # 寻找最优匹配         # 绘制方框         th, tw = tp_pic.shape[:2]         tl = max_loc  # 左上角点的坐标         br = (tl[0]+tw, tl[1]+th)  # 右下角点的坐标         cv2.rectangle(bg_img, tl, br, (0, 0, 255), 2)  # 绘制矩形         cv2.imwrite(out, bg_img)  # 保存在本地         # 返回缺口的X坐标         # print(bg_img.shape[0])         # if abs(bg_img.shape[0]-205) > 0:         #     tl[0] += bg_img.shape[0]-205         return tl[0]
    def move_slider(self,  track):         """根据轨迹列表,拖动滑块到缺口处         :param slider: 滑块         :param track: 轨迹         """         ActionChains(self.driver.driver).click_and_hold(             self.findelement(self.slider)).perform()         for x in track:             ActionChains(self.driver.driver).move_by_offset(                 xoffset=x, yoffset=0).perform()         ActionChains(self.driver.driver).release().perform()

class Login_Action(VerificationCode):     @ allure.step('输入用户名密码登录')     def login(self, userName, userpw):         '''         输入用户名密码登录         :param:userName:用户名         :param:userpw:密码         '''         self.type_name(userName)         self.type_pw(userpw)         self.drag_slider()         # self.quick_slider()         self.click_login()         assert Navigation(self.driver).get_username() == userName
    def drag_slider(self):         '''         第一种方法:移动滑块,完成验证         '''         self.hover_slider()         name1 = self.get_img(self.bgImage)         name2 = self.get_img(self.smallImageblocks)         out = common.dir+"/file/temporary/out.jpg"         x = self.identify_gap(             name1, name2, out)         print(x)         if x > 200:             x = x+20  # pass         elif x > 150:             x = x+16         else:             x = x+12  # pass         tracks = self.get_track(x)         self.move_slider(tracks)
    def quick_slider(self):         '''          第二种方法:通过接口获取验证成功         '''         response1 = requests.post(             url=settings.Backstage_URL+"/share-auth/getImageVerifyCode")         assert response1.status_code == 200         content = json.loads(response1.text)         for n in range(80, 230, 5):             response = requests.get(url=settings.Backstage_URL + "/share-auth-center/validateUnlock",                                     params={                                         'checkMoveId': content['data']['checkMoveId'], 'xWidth': str(n)}                                     )             if response.text == 'true':                 print(n)                 break             time.sleep(3)         self.set_slider_success()
上一篇:#力扣LeetCode1704. 判断字符串的两半是否相似 @FDDLC


下一篇:python工具——removebg