说明
利用 python selenium 库自动获取考试成绩时,发现多次请求后需要填写验证码,本方案利用 pytesseract 识别验证码并自动填入。
跳转到原文
文中代码方案实现的功能有:
- [x] 检测登录时是否需要填写验证码
- [x] 验证码本地保存
- [x] 验证码识别+结果获取
验证码展示
验证码处理后:
0、准备
- python3.9
- Tesseract-OCR软件
- 安装
GitHub 地址:https://github.com/tesseract-ocr/tesseract
安装包官方下载地址:https://digi.bib.uni-mannheim.de/tesseract/tesseract-ocr-setup-4.00.00dev.exe - 配置环境变量
- 配置环境变量的教程
- 或者手动引用
# 配置环境变量 pytesseract.pytesseract.tesseract_cmd = 'C:/Program Files (x86)/Tesseract-OCR/tesseract.exe' tessdata_dir_config = '--tessdata-dir "C:/Program Files (x86)/Tesseract-OCR/tessdata"'
- 安装
1、方案实现
1.1、检测登录时是否需要填写二维码
# 检查是否存在该元素
def isElementExist(self, element):
try:
# 通过元素名称查找
self.browser.find_element_by_name(element)
return True
except:
return False
1.2、验证码保存、识别、获取结果、自动填入
处理办法:
- 检测到需要填写验证码,则确认验证码在浏览器窗口中可见,截图保存为 image1.png
- 在浏览器代码中获取验证码元素在浏览器的位置和大小(此数据即为验证码在 image1.png 中的位置),在 image1.png 中对应位置裁出验证码,保存为 code1.png
- 将验证码(code1.png)二值化,图像加强,保存为(code2.png)
- 利用 pytesseract 函数识别 code2.png ,获取结果
- 填写到输入框
import pytesseract
from PIL import Image, ImageEnhance
# 检查验证码是否存在、并处理验证码
if self.isElementExist(element="yzwb_checkcode"):
print("处理验证码")
# 窗口最大化(如果确认验证码在窗口中可见,则不需要此操作)
self.browser.maximize_window()
# 获取图像验证码在当前屏幕中显示的位置、大小信息
imgelement = self.browser.find_element_by_xpath('//*[@id="app"]/div/form[2]/div[5]/div/div[2]/img')
location = imgelement.location
size = imgelement.size
rangle = (
int(location['x']), int(location['y']), int(location['x'] + size['width']),
int(location['y'] + size['height'])
)
# 截取浏览器显示窗口,并保存
self.browser.get_screenshot_as_file('./img/image1.png')
# 等待保存
# time.sleep(1)
# 利用验证码位置、大小信息,裁剪,获取验证码本码
im = Image.open('./img/image1.png')
region = im.crop(rangle)
region.save("./img/code1.png")
# time.sleep(1)
# 验证码二值化、对比度加强
im = Image.open("./img/code1.png")
imgry = im.convert('L') # 图像加强,二值化
sharpness = ImageEnhance.Contrast(imgry) # 对比度增强
sharp_img = sharpness.enhance(2.0)
sharp_img.save("./img/code2.png")
# 识别验证码,获取验证码内容
code = pytesseract.image_to_string(sharp_img).replace(' ', '')
# 填入验证码
self.browser.find_element_by_name("yzwb_checkcode").send_keys(code)
else:
# 不存在验证码