python实现滑动验证

做自动化测试的时候,需要自动登录QQ邮箱,在网上找的都是基于selenium的:参考链接,但是代码在本地运行并没有取得满意的效果:滑动不成功!
而且每个滑动解锁的网页不同,编码和格式就不同,复用率太低了!举个例子:

button = browser.find_element_by_id(‘tcaptcha_drag_button’)
x, y = button.location.get(‘x’), button.location.get(‘y’)
print(“location:”,x,y)
%title插图%num
这段代码是获取滑动解锁按钮坐标的,但是返回的是(33,193),而不是根据桌面像素(1920,1080)应该得到的坐标。

查看网页源码发现,这个验证框:width:300px,height:230px,因此坐标是根据这个iframe框架得到的,所以后面的拖动按钮并滑动就会出现问题,(比如拖动一点点就会报错:超出(300,230)边界错误),而且总是拖不到右边,搞了好久都不行(部分原因是我前端基础不牢固)
还有一些其他问题我就不再说了,反正就是心态爆炸:不想用selenium搞滑动了!
我就换了一个方法,按钮的图片定位,然后实现滑动验证:图片定位具体可以参考:ac.find_template识别图片并定位

直接上代码吧:

#coding=utf-8
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time
import paramiko
import pyautogui
import os
from time import sleep
from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
from Auto_Test.base_action import match

def login_in():
browser = webdriver.Firefox()
browser.maximize_window()
browser.get(“https://mail.qq.com/”)
browser.switch_to.frame(“login_frame”)
browser.find_element_by_class_name(“inputstyle”).clear()
browser.find_element_by_class_name(“inputstyle”).send_keys(“xxxxx”)
browser.find_element_by_class_name(“inputstyle.password”).clear()
browser.find_element_by_class_name(“inputstyle.password”).send_keys(“xxxxx”)
browser.find_element_by_id(“login_button”).click()
browser.find_element_by_class_name(“login_button”).click()
time.sleep(2)
browser.switch_to.frame(“tcaptcha_iframe”)

time.sleep(3)
# 等待图片加载出来
WebDriverWait(browser, 5, 0.5).until(
EC.presence_of_element_located((By.ID, “tcaptcha_drag_button”)))
# button = browser.find_element_by_id(‘tcaptcha_drag_button’)
# x, y = button.location.get(‘x’), button.location.get(‘y’)
# print(“location:”,x,y)
lx,ly=match(“QQmail-slick”)
lz=[x for x in range(120,200,3)]
for i in lz:
pyautogui.moveTo(lx,ly)
pyautogui.dragRel(i,0,duration=2,button=’left’)
time.sleep(1)
pyautogui.moveRel(-i,0)

try:
alert = browser.find_element_by_id(‘guideText’).text
except Exception as e:
print(‘get alert error: %s’ % e)
alert = ”
if alert:
print(u’滑块位移需要调整: %s’ % alert)
sleep(3)
else:
print(‘滑块验证通过’)
browser.switch_to.parent_frame() # 验证成功后跳回*外层页面
break

from Auto_Test.base_action import match中的函数如下:

def match(target, show=True):
target_path = target.split(“-“)[0]
target_name = target.split(“-“)[1]
# 防止截全屏的页面没反应过来
time.sleep(1)
ttime_s = time.time()

global root_dir
appname = root_dir + ‘/APP_Action_Icons/’+target_path+”/”+target_name+’.png’
appname_2 = root_dir + ‘/APP_Action_Icons/’+target_path+”/”+target_name+’_2.png’
appname_3 = root_dir + ‘/APP_Action_Icons/’+target_path+”/”+target_name+’_3.png’
print(appname)
print(“root_dir =”, root_dir)

##根据桌面路径进行截屏
hwnd = win32gui.FindWindow(None, root_dir)
app = QApplication(sys.argv)
screen = QApplication.primaryScreen()
img = screen.grabWindow(hwnd).toImage()

##保存截屏
root_desk = root_dir + ‘/Screen_Shots/Test_Screen_shots/desktop.jpg’
img.save(root_desk)
##等待图片保存
time.sleep(0.5)
# 支持图片名为中英文名,也支持路径中英文
imsrc = cv2.imdecode(np.fromfile(root_desk, dtype=np.uint8), -1)
imobj = cv2.imdecode(np.fromfile(appname, dtype=np.uint8), -1)

##根踞名称匹配截图,只支持图片为英文名
# imsrc = ac.imread(root_desk)
# imobj = ac.imread(appname)

# 匹配图标位置
pos = ac.find_template(imsrc, imobj, 0.5,bgremove=True)
if pos == None and os.path.exists(appname_2):
print(“*张图标没匹配到,现匹配第二张:”, end=””)
print(appname_2)
imobj_2 = cv2.imdecode(np.fromfile(appname_2, dtype=np.uint8), -1)
# imobj_2 = ac.imread(appname_2)
pos = ac.find_template(imsrc, imobj_2, 0.5,bgremove=True)
if pos == None and os.path.exists(appname_3):
print(“第二张图标没匹配到,现匹配第三张:”, end=””)
print(appname_3)
imobj_3 = cv2.imdecode(np.fromfile(appname_3, dtype=np.uint8), -1)
# imobj_3 = ac.imread(appname_3)
pos = ac.find_template(imsrc, imobj_3, 0.5,bgremove=True)

# 如果第三张还未匹配到,用另一种方法重新截图
if pos == None:
print(“2秒后重新截全屏…”)
time.sleep(2)

##保存截屏
root_desk = root_dir + ‘/Screen_Shots/Test_Screen_shots/desktop_2.jpg’
img = ImageGrab.grab()
img.save(root_desk)
##等待图片保存
time.sleep(0.5)
# 支持图片名为中英文名,也支持路径中英文
imsrc = cv2.imdecode(np.fromfile(root_desk, dtype=np.uint8), -1)
imobj = cv2.imdecode(np.fromfile(appname, dtype=np.uint8), -1)

# 匹配图标位置
pos = ac.find_template(imsrc, imobj, 0.5,bgremove=True)
if pos == None and os.path.exists(appname_2):
print(“*张图标没匹配到,现匹配第二张:”, end=””)
print(appname_2)
imobj_2 = cv2.imdecode(np.fromfile(appname_2, dtype=np.uint8), -1)
pos = ac.find_template(imsrc, imobj_2, 0.5,bgremove=True)
if pos == None and os.path.exists(appname_3):
print(“第二张图标没匹配到,现匹配第三张:”, end=””)
print(appname_3)
imobj_3 = cv2.imdecode(np.fromfile(appname_3, dtype=np.uint8), -1)
pos = ac.find_template(imsrc, imobj_3, 0.5,bgremove=True)

if pos == None:
print(“*终没能匹配到:” + target)
else:
ttime_e = time.time()
__time = ttime_e – ttime_s

if show == True:
try:
show_and_save(root_desk, target, pos, __time)
except Exception as e:
print(“保存匹配结果show_and_save这里出错,错误原因为{}”.format(e))
print(pos)
point = pos[‘result’]
pyautogui.moveTo(point)
print(“匹配成功:{}”.format(target))
time.sleep(0.5)
print(pyautogui.position())
pyautogui.click(clicks=2)
return point

亲测有效,如果有问题,可以联系我,看到了就会*时间回复!
互相交流,互相学习,共同进步!