验证码处理
一般情况公司如果涉及web自动化测试需要对验证码进行处理的方式一般有一下几种:
- 关闭验证码功能(开发处理)
- 设置万能验证码(开发处理)
- 使用智能识别库进行验证
- 通过第三方打码平台识别验证码
1. 跳过验证功能
需要开发配合,关闭验证码功能或者设置万能验证码
2. 使用智能识别库进行验证(不推荐)
使用ddddocr库
基于深度学习的工具
主要用于识别图片中的文字以及数字内容
主要 特点:易用,正确率以及高效的优势
from ddddocr import DdddOcr # 截取验证码图片 img = driver.find_element(By.XPATH, '//*[@id="verify"]').screenshot_as_png # 使用识别库 verify = DdddOcr(show_ad=False).classification(img)
注意点:识别成功率会根据图片的复杂程度决定,所以使用程度并不高,但是可以进行对应的
优化,比如识别之后的验证码准确的判断
3. 通过第三方打码平台识别验证码
#截取验证码图片 driver.find_element(By.ID, 'slideBg').screenshot("vertify.png")
通过第三方接口发送请求识别验证码内容
超级鹰官方平台:https://www.chaojiying.com/price.html
识别验证码的接口地址:https://upload.chaojiying.net/Upload/Processing.php
登录平台,注册并生成软件ID
3.1 封装识别验证码函数
新建一个utils模块定义一个函数来识别验证
需要识别验证码,只需要调用对应的函数即可
函数中需要处理的逻辑就是识别返回结果
utils.py
#!/usr/local/bin/python3 # @IDE: PyCharm # @.py: get_code #-*- coding : utf-8 # @Author:may # @Time: 2024/4/27 import requests # 打码平台识别验证码 def img_code(): url = 'https://upload.chaojiying.net/Upload/Processing.php' # 传递实参数据 data = { # 用户名 "user": "young", # 密码 "pass": "3db3a2****80c675da4", # 用户id "sofid": "95**27", # 验证码类型编号 "codetype": 1004} # 提取验证码图片 files = {"userfile": open("verify.png", "rb")} # 发送接口请求识别验证码 resp = requests.post(url, data=data, files=files) # 查看响应信息 # print(resp.json()) res = resp.json() print(res) if res["err_no"] == 0: code = res["pic_str"] print(f"验证码识别成功:{code}") return code else: print("验证码识别失败") return False
"codetype": 1004 是1~4 位英文数字
使用
from common.utils import img_code # 获取验证码图片,保存至本地 driver.find_element(By.ID, '***').screenshot("verify.png") # 调用验证码图片识别 code = img_code()
调用成功结果:
3.2 滑块验证
验证码类型 9103 的返回结果如下:
验证码 9101 的返回结果:
以豆瓣登录为例:
切换焦点并下载验证图片,将焦点切换至滑块验证区域,并下载加载好的滑块验证背景图片。
点击登录按钮后,就会出现滑块验证区域,这是一个新增的frame区域,此时我们需要将切换的焦点从主页面转换到这个frame区域上
driver.switch_to.frame('tcaptcha_iframe_dy')
获取验证码图片
# 获取验证码图片,保存至本地 driver.find_element(By.ID, 'slideBg').screenshot("verify.png")
左边匹配的滑块的位置
有很多方法,但是好像都不是很适用这个,不知道是不是 mac上画布不大一样。。。要么就是很麻烦。。。
selenium 与 超级鹰结合完成自动登录验证-CSDN博客
【Python从入门到进阶】39、使用Selenium自动验证滑块登录_selenium滑块验证码实现-CSDN博客
*4. 通过cookie保持登录
需要保持登录状态方式:
通过cookie信息的唯一标识符id进行验证
让标识符id一直保持登录的状态,那么再次访问页面的时候就是已登录的状态
通过cookie的机制原理先获取已登录的id然后再未登录的页面中进行使用即可
需要退出登录状态方式:
关闭整个浏览器
自动清除cookie信息
删除已登录的表示id
刷新页面,自动退出登录的状态
注意点:对页面的cookie值进行修改完成之后,一定要刷新页面才生效,需要清楚缓存
使用selenium提供的方法,get_cookies提取当前页面中所有的cookie信息
4.1 封装自动化获取cookie
在第一次登录完成之后,把页面的已登录的cookie信息进行保存(唯一标识符的id)
在第二次及所有需要登录的页面中直接使用已登录的cookie信息,直接绕过登录
定义2个函数来获取cookie和使用cookie
utils.py
import json def save_cookies(drier): # 将已登录页面中的cookie进行保存 cookies = drier.get_cookies() with open("cookies.json", "w") as f: f.write(json.dumps(cookies)) def load_cookies(driver): try: with open("cookies.json") as f: cookies = json.loads(f.read()) # 遍历字典获取cookie信息进行添加 for cookie in cookies: driver.add_cookie(cookie) else: # 刷新页面,清除缓存 driver.refresh() except: print("目前没有可以使用的已登录cookie信息")
4.2 使用cookie绕过登录
使用cookie信息进行绕过登录,保持登录状态:
import time from webdriver_helper import get_webdriver # import requests as requests # from selenium.webdriver.common.by import By from common.utils import img_code, load_cookies, save_cookies driver = get_webdriver() # 启动浏览器 driver.get("https://accounts.douban.com/passport/login") # 控制浏览器 driver.maximize_window() time.sleep(3) # 使用cookie信息 load_cookies(driver) # 完成登录用例脚本,解决验证码的处理 # driver.find_element(By.XPATH, '//*[@id="verify"]').screenshot("verify.png") # code = img_code() # driver.find_element(By.XPATH, '/html/body/form/table/tbody/tr/td[3]/table/tbody/tr[2]/td[2]/input').send_keys("admin") # driver.find_element(By.XPATH, '/html/body/form/table/tbody/tr/td[3]/table/tbody/tr[3]/td[2]/input').send_keys("msjy123") # driver.find_element(By.XPATH, '/html/body/form/table/tbody/tr/td[3]/table/tbody/tr[5]/td[2]/input').send_keys(code) # driver.find_element(By.XPATH, '//*[@id="login_btn"]').click() # 保存cookie信息 # save_cookies(driver) time.sleep(5) driver.quit()