文章目录
前言`
随着网络安全需求的不断发展,为防止机器操作导致网站安全、性能问题,验证码成了网站必选项,也给web自动化测试脚本提出了新需求,本文就介绍了web自动化验证码处理的基础内容。
一、验证码处理方式
1.添加验证码的原因
(1)验证码的主要目的是识别是否机器人操作
(2)因为大量的机器人(爬虫)操作会向服务器发送大量无效请求,这严重占用服务器资源,造成资源的大量浪费,影响服务器性能
2.Web自动化验证码处理方式如下:
1、使用万能验证码
针对有万能验证码的测试环境网站,可以输入万能验证码进行验证。
2、读取cookie直接跳过验证(以登录为例)
3、通过图片识别工具获取验证码输入
没有万能验证码,那么我们可以直接把验证码图片截下来,发给百度的人工智能接口,通过接口识别图片中的文字
4、滑块验证码验证
二、使用cookie跳过验证码步骤
1.登录web获取cookie
代码如下:
def test_login_function(self,driver):
# driver=webdriver.Firefox()
# driver.maximize_window()
# driver.implicitly_wait(5)
#2.输入网址,打开登录页面
driver.get('https://svr-6-9002.share.51env.net/accounts/login/')
#3.输入用户名
driver.find_element(By.ID,'id_login').clear()
driver.find_element(By.ID,'id_login').send_keys('wendt')
#4.输入密码
driver.find_element(By.ID,'id_password').clear()
driver.find_element(By.ID,'id_password').send_keys('Wdtldz123')
#5.输入验证码
# driver.find_element(By.ID,'id_captcha_1').clear()
# driver.find_element(By.ID,'id_captcha_1').send_keys('passed')
#6.点击登录按钮
driver.find_element(By.CLASS_NAME,'primaryAction').click()
#在登录两秒,确定服务器返回了响应结果,获取并打印登录成功后的cookie信息
time.sleep(2)
print(driver.get_cookies())
#[{'name': 'csrftoken', 'value': 'sDuJHGxcOx4SWw9Czr7WDqB6CK7rS5Fa2etTgVegeQpEJykSqZMhZmsf3Zdj6L5R', 'path': '/', 'domain': 'svr-6-9002.share.51env.net', 'secure': False, 'httpOnly': False, 'expiry': 1720609964, 'sameSite': 'Lax'}, {'name': 'sessionid', 'value': 'h48euayokh9q7hriezuakyz6t1ol36bj', 'path': '/', 'domain': 'svr-6-9002.share.51env.net', 'secure': False, 'httpOnly': True, 'expiry': 1690369964, 'sameSite': 'Lax'}]
2.使用获取到的cookie跳过登录验证
代码如下(示例):
def test_skip_login(self,driver):
driver.get('https://svr-6-9002.share.51env.net')
#1.打开首页后,设置在test_login5.py中获取的cookie信息
cookies=[{'name': 'csrftoken', 'value': 'sDuJHGxcOx4SWw9Czr7WDqB6CK7rS5Fa2etTgVegeQpEJykSqZMhZmsf3Zdj6L5R', 'path': '/', 'domain': 'svr-6-9002.share.51env.net', 'secure': False, 'httpOnly': False, 'expiry': 1720609964, 'sameSite': 'Lax'}, {'name': 'sessionid', 'value': 'h48euayokh9q7hriezuakyz6t1ol36bj', 'path': '/', 'domain': 'svr-6-9002.share.51env.net', 'secure': False, 'httpOnly': True, 'expiry': 1690369964, 'sameSite': 'Lax'}]
#2.打开首页后,设置cookie信息
for cookie in cookies:
#cookie是有有效期的,我们需要改下有效期,让它永远不过期
if 'expiry' in cookie.keys():
cookie['expiry']=int(time.time())+360000
driver.add_cookie(cookie)
#3.重新打开页面,相当于重新发送了一个带着登录成功cookie的请求,这时,服务器就以为你登录过了,就会返回登录后的界面
driver.get('https://svr-6-9002.share.51env.net')
driver.find_element(By.LINK_TEXT,'我的媒体').click()
print(driver.get_cookies())
该处使用的driver是浏览器驱动对象。
@pytest.fixture(scope='function')
def driver():
driver=webdriver.Firefox()
driver.maximize_window()
driver.implicitly_wait(10)
yield driver
# time.sleep(30)#如果需要观察程序运行过程,那么加时间等待
driver.quit()
三、图片识别验证码处理步骤
1、截图,base64格式的图片
代码如下:
captcha=driver.find_element(By.CLASS_NAME,'captcha').screenshot_as_base64
2、注册百度AI网站账号,创建个人应用,获取client_id和client_secret
百度AI网站:https://ai.baidu.com/
client_id='dfV9jwn3rmi8DblXrXW3sNKS'
client_secret='PWt51WDkYNSXVnG6etav94wuhYunuVOI'
3、在技术文档中找到获取ACCESS_TOKEN的接口说明文档,模拟请求,获取Access_Token的值
token_url='https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&' \
'client_id='+client_id+'&client_secret='+client_secret
access_token = requests.get(token_url).json()['access_token']
4、找到通用文字识别(精准)的接口说明文档,构建接口地址
accurate_url='https://aip.baidubce.com/rest/2.0/orc/v1/accurate_basic?access_token='+access_token
5、构建信息头,请求的消息体类型
headers={'Content-Type':'application/x-www-form-urlencoded'}
6、构造消息体,内容是验证码图片
image={'image':captcha}
7、发送请求需要接口的代码库requests,获取响应中的验证码
response=requests.post(accurate_url,header=headers,data=image)
8、定位验证码输入框,输入识别出来的验证码
driver.find_element(By.ID, 'id_captcha_1').send_keys(response.json()['words_result'][0]['words'])
四、滑块验证码处理
需下载代码库
pip install opencv-python
def test_register(self,driver):
driver.get('https://svr-6-9002.share.51env.net/accounts/signup/')
driver.execute_script('windows.scrollTo(0,1000)')
canvas=driver.find_element(By.CLASS_NAME,'verify_img_canvas')
block=driver.find_element(By.CLASS_NAME,'verify_sub_block')
#1、获取base64格式的背景图片和滑块图片
#renturn返回图片的base64格式的字符串
#argument[0]指的是后面的第一个参数,就是canvas这个元素
#toDataURL("img/png")就是获取元素base64格式字符串
#.substring(21)去掉字符串的前21位
canvas_b64=driver.execute_script('return arguments[0].toDataURL("image/png").substring(21)',canvas)
#2、把base64格式的图片保存到本地
canvas_data=base64.b64decode(canvas_b64)
with open('canvas.png','wb') as f:
f.write(canvas_data)
#同理,把滑块也保存到本地
block_b64 = driver.execute_script('return arguments[0].toDataURL("image/png").substring(21)', block)
# 2、把base64格式的图片保存到本地
block_data = base64.b64decode(block_b64)
with open('block.png', 'wb') as f:
f.write(block_data)
#3、用代码库cv2加载这两张图片
canvas_img=cv2.imread('canvas.png')
block_img=cv2.imread('canvas.png')
res=cv2.matchTemplate(canvas_img,block_img,cv2.TM_CCOEFF_NORMED)
min_val,max_val,min_loc,max_loc=cv2.minMaxLoc(res)#寻找最优匹配
#max_loc指的是最相似位置(x,y)
offset=max_loc[0]+10
#4、定位滑块的位置
move_block=driver.find_element(By.CLASS_NAME,'verify_move_block')
#拖动滑块
actions=ActionChains(driver)
actions.click_and_hold(move_block).move_by_offset(offset,0).release().perform()
AntionChains是selenium提供的模拟操作类,可以模拟鼠标、键盘等操作,由于篇幅有限,ActionChains类具体内容下篇介绍。
总结
以上就是今天要讲的内容,本文仅仅简单介绍了验证码处理的几种方式,初次写文章,如有不足还望指正,交流,感谢~