用于UI自动化登录拼图滑动验证码

  1 #!/usr/bin/env python
  2 # -*- coding: utf-8 -*-
  3 # @Time    : 2019/11/15 14:32
  4 # @Site    : 
  5 # @File    : puzzleCaptcha.py
  6 # @Software: PyCharm
  7 
  8 import os
  9 import cv2
 10 import time
 11 from PIL import Image
 12 from SiteTest.datas.data_Files import *#自行创建的package,存放页面元素数据
 13 from selenium.webdriver import ActionChains
 14 from selenium.webdriver.common.by import By
 15 
 16 path = os.path.abspath(os.path.dirname(os.getcwd()))
 17 
 18 class puzzleCaptcha():
 19     def __init__(self):
 20 
 21         #常量和元素数据加载
 22         self.Data = Datas()#可按照分类保存元素路径数据
 23         self.data = self.Data.puzzleCaptchaData()#实例化所需数据方法,用到该参数的地方都需要按照实际建立的数据文件取值self.data.****
 24 
 25     def analog_drag(self,driver,distance,bgImagePath,sliderImagePath):#滑动过程
 26         """
 27         滑动过程
 28         :param driver: 浏览器
 29         :param distance 滑块滑动距离
 30         :param bgImagePath 函数pic_get()获取的背景图片保存路径
 31         :param sliderImagePath 函数pic_get()获取的滑块图片保存路径
 32         :return: 背景图和滑块图
 33         """
 34         # time.sleep(1)#防止加载缓慢找不到元素buttonDrag
 35         buttonDrag = driver.find_element(By.XPATH,self.data.buttonDrag_xpath)
 36         ActionChains(driver).click_and_hold(buttonDrag).move_by_offset(distance,0).perform()
 37         time.sleep(1)#移动到指定距离后停留1s再释放鼠标
 38         ActionChains(driver).release(buttonDrag).perform()
 39         flag = self.ifElementExist(driver,By.XPATH,self.data.succes_xpath)
 40         while True:
 41             if flag == False:#拼图不成功一直重试
 42                 # time.sleep(0.5)
 43                 driver.refresh()
 44                 self.pic_get(driver,bgImagePath,sliderImagePath)
 45                 distance01 = self.move_Distance(bgImagePath,sliderImagePath)
 46                 self.analog_drag(driver,distance01,bgImagePath,sliderImagePath)
 47             else:#拼图成功后输入账户密码并登陆
 48                 # time.sleep(0.5)
 49                 driver.find_element_by_class_name(self.data.userName_class).send_keys(self.data.userName)
 50                 driver.find_element(By.XPATH,self.data.pwd_xpath).send_keys(self.data.pwd)
 51                 driver.find_element(By.XPATH,self.data.btnLogin_xpath).click()
 52             break
 53         time.sleep(1)#便于查找元素
 54 
 55     def ifElementExist(self,driver,method,elementPath):
 56         """
 57         判断查找的元素是否存在
 58         :param driver: 浏览器
 59         :param method:查找元素方法(By.XPATH,By.CLASS_NAME,By.LINK_TEXT,By.ID,By.NAME等)
 60         :param elementPath: 元素在html中的路径
 61         :return: 背景图和滑块图
 62         """
 63         try:
 64             time.sleep(1)#防止页面加载过慢,找不到元素导致拼图成功时 flag==False
 65             driver.find_element(method,elementPath)
 66             flag = True
 67         except:
 68             flag=False
 69         return flag
 70 
 71     def pic_get(self,driver,bgImagePath,sliderImagePath):
 72         """
 73         获取拼图图片
 74         :param driver: 浏览器
 75         :param bgImagePath: 背景图片
 76         :param liderImagePath:滑块图片
 77         :return: 背景图和滑块图
 78         """
 79         time.sleep(1)
 80         buttonDrag = driver.find_element(By.XPATH,self.data.buttonDrag_xpath)
 81         ActionChains(driver).click_and_hold(buttonDrag).perform()
 82 
 83         bgImage = driver.find_element(By.XPATH,self.data.bgPic_xpath)#背景图片元素获取
 84         driver.save_screenshot(bgImagePath)
 85         # print bgImage.location
 86         # print(bgImage.size)
 87         left_bg = bgImage.location['x']
 88         top_bg = bgImage.location['y']
 89         right_bg = bgImage.location['x'] + bgImage.size['width']
 90         bottom_bg = bgImage.location['y'] + bgImage.size['height']
 91         im_bg = Image.open(bgImagePath)
 92         im_bg = im_bg.crop((left_bg, top_bg, right_bg, bottom_bg))
 93         im_bg.save(bgImagePath)
 94         self.change_bgImage(bgImagePath)
 95 
 96         sliderImage =driver.find_element(By.XPATH,self.data.sliderPic_xpath)#滑块图片元素获取
 97         driver.save_screenshot(sliderImagePath)
 98         # print sliderImage.location
 99         # print(sliderImage.size)
100         left_slider = sliderImage.location['x']
101         top_slider = sliderImage.location['y']
102         right_slider = sliderImage.location['x'] + sliderImage.size['width']
103         bottom_slider = sliderImage.location['y'] + sliderImage.size['height']
104         im_slider = Image.open(sliderImagePath)
105         im_slider = im_slider.crop((left_slider, top_slider, right_slider, bottom_slider))
106         im_slider.save(sliderImagePath)
107         # print(im_bg,im_slider)
108         return im_slider,im_bg
109 
110     def change_bgImage(self,bgImagePath):#选用,点击才会出现拼图时有用,
111         """
112         覆盖函数pic_get()获取背景图片中滑块凸起
113         :param bgImagePath 函数pic_get()获取的背景图片保存路径
114         :return: 背景图和滑块图
115         """
116         img = cv2.imread(bgImagePath)
117         img2 = img[0:150,65:120]
118         img[0:150,10:65]=img2
119         cv2.imwrite(bgImagePath,img)
120 
121     def move_Distance(self,bgImagePath, sliderImagePath):
122         """
123         找出图像中最佳匹配位置
124         :param target: 目标即背景图
125         :param template: 模板即需要找到的图
126         :return: 返回最佳匹配及其最差匹配和对应的坐标
127         """
128         target_rgb = cv2.imread(bgImagePath)
129         target_gray = cv2.cvtColor(target_rgb, cv2.COLOR_BGR2GRAY)
130         template_rgb = cv2.imread(sliderImagePath, 0)
131         # template_gray = cv2.cvtColor(template_rgb,cv2.COLOR_BGR2GRAY)
132         res = cv2.matchTemplate(target_gray, template_rgb, cv2.TM_CCOEFF_NORMED)
133         value = cv2.minMaxLoc(res)
134         value2 = value[3][0]-10
135         # print(value)
136         # print(value2)
137         return value2
138 
139 if __name__ == '__main__':
140     puzzleCaptcha()