在web端与Android端,登录时会碰到图片验证与滑块验证,解决验证问题,下面上代码
图片验证
识别图片中文字,输入验证
滑块验证解决思路
1、获取滑块滑动的距离
2、模拟拖动滑块,通过验证。
web端滑动操作
from selenium.webdriver import ActionChains
action = ActionChains(driver)
source = driver.find_element_by_xpath("//*[@id='nc_1_n1t']/span") # 需要滑动的元素
action.click_and_hold(source).perform() # 鼠标左键按下不放
action.move_by_offset(298, 0) # 需要滑动的坐标
action.release().perform() # 释放鼠标
代码操作
import cv2
import requests
from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
import time
driver = webdriver.Chrome()
driver.get("https://www.douban.com/")
driver.maximize_window()
iframe = driver.find_element(By.CSS_SELECTOR, "#anony-reg-new > div > div.login > iframe")
driver.switch_to.frame(iframe)
phone = driver.find_element(By.CSS_SELECTOR,
"body > div.account-body.login-wrap.login-start.account-anonymous > div.account-tabcon-start > div.account-form > div:nth-child(3) > div > input")
phone.send_keys('15105408319')
time.sleep(1)
slider_ = driver.find_element(By.CSS_SELECTOR,
'body > div.account-body.login-wrap.login-start.account-anonymous > div.account-tabcon-start > div.account-form > div:nth-child(4) > div > div > a')
slider_.click()
time.sleep(3)
iframe = driver.find_element(By.CSS_SELECTOR, "#tcaptcha_iframe")
driver.switch_to.frame(iframe)
while True:
# 1、获取滑块及滑板地址
src = driver.find_element(By.CSS_SELECTOR, "#slideBg")
bug_src_url = src.get_attribute("src")
src = driver.find_element(By.CSS_SELECTOR, "#slideBlock")
small_src_url = src.get_attribute("src")
# 2、下载到本地图片
with open("../download/big_srs.jpg", "wb") as f:
f.write(requests.get(bug_src_url).content)
with open("../download/small_srs.jpg", "wb") as f:
f.write(requests.get(small_src_url).content)
# print(bug_src_url)
# print(small_src_url)
# 3、图片识别,匹配滑块验证码的距离,滑块和滑板的小图重叠后x轴的距离
# (0.5932352542877197, 0.8350041508674622, (486, 53), (172, 155))
big = cv2.imread("../download/big_srs.jpg", 0) # 以灰度方式加载图片
small = cv2.imread("../download/small_srs.jpg", 0) # 以灰度方式加载图片
res = cv2.matchTemplate(big, small, cv2.TM_CCORR_NORMED) # 匹配模式 小图在大图中的位置
value_num = cv2.minMaxLoc(res) # 匹配小图和大图最左边和最右边的位置
print(value_num)
x = value_num[2][0] # 横坐标
# 4、缩放比例及校准滑块偏移量。原图680x390,实际页面图283x162
print(x)
x = int(x * 283 / 680) # 缩放比例
print(x)
bk = 30 - int(20 * 283 / 680) # 偏移量
print(bk)
x = x - bk
print(x)
# 6、通过ActionChains滑动解锁
action = ActionChains(driver)
action.click_and_hold(src).perform() # 鼠标左键按下不放
# action.drag_and_drop_by_offset(src,x,0).perform() # 滑块滑动到指定坐标
action.move_by_offset(x, 0) # 需要滑动的坐标
action.release().perform() # 释放鼠标
try:
driver.find_element(By.CSS_SELECTOR, "#tcStatus > div.tc-status--right.table-wrap > div:nth-child(2)")
except:
break
time.sleep(5)
driver.quit()
Android端滑动操作
通过scroll_from_element、flick_element 方法来实现下拉操作
TouchAction提供的一些方法:
- double_tap(on_element) #双击
- flick_element(on_element, xoffset, yoffset, speed) #从元素开始以指定的速度移动
- long_press(on_element) #长按不释放
- move(xcoord, ycoord) #移动到指定的位置
- perform() #执行链中的所有动作
- release(xcoord, ycoord) #在某个位置松开操作
- scroll(xoffset, yoffset) #滚动到某个位置
- scroll_from_element(on_element, xoffset, yoffset) #从某元素开始滚动到某个位置
- tap(on_element) #单击
- tap_and_hold(xcoord, ycoord) #某点按住
因为我们模拟的是移动端的H5自动化测试,首先需要我们将浏览器设置成为手机浏览器(设置之后,模拟会更加真实)
1.以元素为起点向下滑动,实现下拉操作
scroll_from_element(on_element xoffset yoffset)
on_element:开始元素滚动。
xoffset:X偏移量。
yoffset:Y偏移量。注意:向下滑动为负数,向上滑动为正数
# 将页面滚动条拖到底部,需要设置sleep(1)
sleep(1)
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
# driver.execute_script("window.scrollTo(0, 10000);")
# sleep(3)
import time
from selenium import webdriver
from selenium.webdriver.common.touch_actions import TouchActions
"""设置手机的大小"""
mobileEmulation = {'deviceName': 'Apple iPhone 5'}
options = webdriver.ChromeOptions()
options.add_experimental_option('mobileEmulation', mobileEmulation)
driver = webdriver.Chrome(chrome_options=options)
driver.get('http://m.test.90dichan.com')
driver.maximize_window()
"""定位操作元素"""
button = driver.find_element_by_xpath('//*[@id="pullrefresh"]/div[2]/ul/li[2]/a/div[2]/span')
time.sleep(3)
Action = TouchActions(driver)
"""从button元素像下滑动200元素"""
Action.scroll_from_element(button, 0, -200).perform()
time.sleep(3)
driver.close()
2.以元素为起点用一定速度向下滑动,实现下拉操作
flick_element(on_element, xoffset, yoffset, speed);
on_element #操作元素定位
xoffset #x轴偏移量
yoffset #y轴偏移量
speed #速度注意:向上滑动为负数,向下滑动为正数
import time
from selenium import webdriver
from selenium.webdriver.common.touch_actions import TouchActions
"""设置手机的大小"""
mobileEmulation = {'deviceName': 'Apple iPhone 5'}
options = webdriver.ChromeOptions()
options.add_experimental_option('mobileEmulation', mobileEmulation)
driver = webdriver.Chrome(chrome_options=options)
driver.get('http://m.test.90dichan.com')
driver.maximize_window()
"""定位操作元素"""
button = driver.find_element_by_xpath('//*[@id="pullrefresh"]/div[2]/ul/li[2]/a/div[2]/span')
time.sleep(3)
Action = TouchActions(driver)
"""从button元素像下滑动200元素,以50的速度向下滑动"""
Action.flick_element(button, 0, 200, 50).perform()
time.sleep(3)
driver.close()
PC端滑块验证,模拟人工操作完整版
import cv2
import requests
from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
import time
def get_show_img():
iframe = driver.find_element(By.CSS_SELECTOR, "#anony-reg-new > div > div.login > iframe")
driver.switch_to.frame(iframe)
phone = driver.find_element(By.CSS_SELECTOR,
"body > div.account-body.login-wrap.login-start.account-anonymous > div.account-tabcon-start > div.account-form > div:nth-child(3) > div > input")
phone.send_keys('15105408311')
time.sleep(1)
slider_ = driver.find_element(By.CSS_SELECTOR,
'body > div.account-body.login-wrap.login-start.account-anonymous > div.account-tabcon-start > div.account-form > div:nth-child(4) > div > div > a')
slider_.click()
time.sleep(3)
iframe = driver.find_element(By.CSS_SELECTOR, "#tcaptcha_iframe")
driver.switch_to.frame(iframe)
def get_load_slider():
count = 5
while count > 0:
# 1、获取滑块及滑板地址
src = driver.find_element(By.CSS_SELECTOR, "#slideBg")
bug_src_url = src.get_attribute("src")
src = driver.find_element(By.CSS_SELECTOR, "#slideBlock")
small_src_url = src.get_attribute("src")
# 2、下载到本地图片
with open("../download/big_srs.jpg", "wb") as f:
f.write(requests.get(bug_src_url).content)
with open("../download/small_srs.jpg", "wb") as f:
f.write(requests.get(small_src_url).content)
# 3、图片识别,匹配滑块验证码的距离,滑块和滑板的小图重叠后x轴的距离
# (0.5932352542877197, 0.8350041508674622, (486, 53), (172, 155))
big = cv2.imread("../download/big_srs.jpg", 0) # 以灰度方式加载图片
small = cv2.imread("../download/small_srs.jpg", 0) # 以灰度方式加载图片
res = cv2.matchTemplate(big, small, cv2.TM_CCORR_NORMED) # 匹配模式 小图在大图中的位置
value_num = cv2.minMaxLoc(res) # 匹配小图和大图最左边和最右边的位置
x = value_num[2][0] # 横坐标
# 4、缩放比例及校准滑块偏移量。原图680x390,实际页面图283x162
x = int(x * 283 / 680) # 缩放比例
bk = 30 - int(20 * 283 / 680) # 偏移量
x = x - bk
# 6、通过ActionChains滑动解锁
action = ActionChains(driver)
action.click_and_hold(src).perform() # 鼠标左键按下不放
# action.drag_and_drop_by_offset(src,x,0).perform() # 滑块滑动到指定坐标
# 5、模拟人工操作轨迹
tracks = get_track(x)
ActionChains(driver).click_and_hold(src).perform()
for x in tracks:
ActionChains(driver).move_by_offset(xoffset=x, yoffset=0).perform()
ActionChains(driver).release(src).perform()
time.sleep(3)
# action.move_by_offset(x, 0) # 需要滑动的坐标
# action.release().perform() # 释放鼠标
try:
driver.find_element(By.CSS_SELECTOR, "#tcStatus > div.tc-status--right.table-wrap > div:nth-child(2)")
except:
break
count -= 1
def get_track(x):
'''
滑块移动轨迹
初速度 v =0
单位时间 t = 0.2
位移轨迹 tracks = []
当前位移 ccurrent = 0
:param x:
:return:
'''
v = 0
t = 0.6
tracks = []
current = 0
# mid = x*5/8#到达mid值开始减速
# x = x+10
while current < x:
a = 2
v0 = v
# 单位时间内位移公式
s = v0 * t + 0.5 * a * (t ** 2)
# 当前位移
current = current + s
tracks.append(round(s))
v = v0 + a * t
for i in range(3):
tracks.append(1)
for i in range(3):
tracks.append(-1)
return tracks
if __name__ == "__main__":
options = webdriver.ChromeOptions()
options.add_argument('--no-sandbox') # 解决DevToolsActivePort文件不存在的报错
options.add_argument('--disable-gpu') # 谷歌文档提到需要加上这个属性来规避bug
driver = webdriver.Chrome(chrome_options=options)
driver.get("https://www.douban.com/")
driver.maximize_window()
get_show_img()
get_load_slider()
time.sleep(5)
driver.quit()
版权归原作者 Yuno Wang 所有, 如有侵权,请联系我们删除。