原理:
1,获取页面验证码的元素坐标位置
2,将页面验证码元素截取为图片
3,将验证码图片放入第三方AI平台OCR的方法中,会返回验证码数据给你
我这里用的是百度的AI开放平台(文字识别---高精度)
APP_ID,API_KEY,SECRET_KEY代码中所需的这三个自行在百度AI平台中去控制台创建应用
代码如下
#!/user/bin/env python3
# -*- coding: utf-8 -*-
from selenium import webdriver
from selenium.webdriver.common.by import By
import time
# PIL官方版不支持py3,只是支持python2。在python3.7中,PIL库已经更名为:pillow。直接"pip install pillow"就行。
from PIL import Image
# 百度ocr pip install baidu-aip # cmd命令下载
from aip import AipOcr
from os import path
import os
def baiduOCR_verificationCode(code_element):
# 创建存放验证码的文件夹
path_mkdir = os.path.abspath('VerificationCode')
try:
# 判断是否已经存在该目录
if not os.path.exists(path_mkdir):
# 目录不存在,进行创建操作
os.mkdir(path_mkdir)
print("目录新建成功:" + path_mkdir)
else:
print("目录已存在!!!")
except BaseException as msg:
print("新建目录失败:" + msg)
# (1)登录页面截图
browser.save_screenshot(path_mkdir + "/code.png")
time.sleep(2)
# (2)获取图片验证码坐标
print("验证码的坐标为:", code_element.location)
print("验证码的大小为:", code_element.size)
# (3)图片4个点的坐标位置
left = code_element.location['x'] # x点的坐标
top = code_element.location['y'] # y点的坐标
right = code_element.size['width'] + left # 上面右边点的坐标
down = code_element.size['height'] + top # 下面右边点的坐标
image = Image.open(path_mkdir + '/code.png') # 截取你整个的登录页面
# (4)将图片验证码截取
code_image = image.crop((left, top, right, down))
code_image.save(path_mkdir + '/code_new.png') # 截取的验证码图片保存为新的文件
verificationCode_img = path_mkdir + '/code_new.png'
filename = path.basename(verificationCode_img) # 图片名称
# 百度提供
""" 你的 APPID AK SK """
APP_ID = '' # 这是你产品服务的appid
API_KEY = '' # 这是你产品服务的appkey
SECRET_KEY = '' # 这是你产品服务的secretkey
client = AipOcr(APP_ID, API_KEY, SECRET_KEY)
i = open(verificationCode_img, 'rb')
img = i.read()
print("正在识别图片:\t" + filename)
""" 调用通用文字识别(高精度版) """
message = client.basicAccurate(img)
print("识别的数据:"+str(message))
i.close()
# {'words_result': [{'words': 'HdO5'}], 'words_result_num': 1, 'log_id': 1643580276821765811}
if len(message.get('words_result')) == 0:
print("\033[1;31mError:验证码识别失败,words_result里的数据为空\033[0m")
VerificationCode_Date = "\033[1;31mError:验证码识别失败,words_result里的数据为空\033[0m"
return VerificationCode_Date
else:
VerificationCode_Date = str(message["words_result"][0]["words"]).strip()
print("识别成功,验证码为:" + VerificationCode_Date)
return VerificationCode_Date
if __name__ == '__main__':
browser = webdriver.Chrome()
browser.maximize_window()
browser.implicitly_wait(10)
path2 = os.path.dirname(os.path.abspath(__file__))
# 需要识别验证码的网站
file_path = 'file:///' + path2 + '/html/code.html'
browser.get(file_path)
code_element = browser.find_element(By.XPATH, '//*[@id="code"]')
# 参数表示:页面中需要识别的验证码元素位置
verificationCode = baiduOCR_verificationCode(code_element)
print(verificationCode)
input_verify = browser.find_element(By.XPATH, "//*[@id='vcode']")
input_verify.send_keys(verificationCode) # 写入验证码
验证码html页面
<!DOCTYPE HTML>
<html>
<head>
<title>注册模块</title>
<meta charset="utf-8">
<style>
#vcode {
height: 35px;
width: 40%;
font-size: 15pt;
margin-left: 15%;
border-radius: 5px;
border: 1;
padding-left: 8px;
}
#code {
color: #ffffff;
/*字体颜色白色*/
background-color: #000000;
font-size: 20pt;
font-family: "华康娃娃体W5";
padding: 5px 35px 10px 35px;
margin-left: 5%;
cursor: pointer;
}
#search_pass_link {
width: 70%;
text-align: right;
margin: 0 auto;
padding: 5px;
}
.btns {
width: 30%;
margin-left: 13%;
height: 40px;
border: 0;
font-size: 14pt;
font-family;
"微软雅黑";
background-color: #FC5628;
color: #ffffff;
cursor: pointer;
/*设置指针鼠标的样式*/
border-radius: 20px;
/*设置圆角样式*/
border: 0;
}
</style>
</head>
<body leftmargin="0" onload="changeImg()">
<div class="main_bar">
<form action="login.html" onsubmit="return check()">
<input type="text" id="vcode" placeholder="验证码" value="验证码" onfocus="this.value=''" onblur="if(this.value=='')this.value='验证码'" /><span id="code" title="看不清,换一张"></span>
<div id="search_pass_link">
</div>
<input type="submit" id="submit" value="登录" class="btns" onmouseover="this.style.backgroundColor='#FF8D00'" onmouseout="this.style.backgroundColor='#FC5628'">
<input type="reset" value="取消" class="btns" onmouseover="this.style.backgroundColor='#FF8D00'" onmouseout="this.style.backgroundColor='#FC5628'">
</form>
</div>
</body>
<script type="text/javascript">
var code; //声明一个变量用于存储生成的验证码
document.getElementById("code").onclick = changeImg;
function changeImg() {
var arrays = new Array(
'1', '2', '3', '4', '5', '6', '7', '8', '9', '0',
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
'u', 'v', 'w', 'x', 'y', 'z',
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
'U', 'V', 'W', 'X', 'Y', 'Z'
);
code = ''; //重新初始化验证码
//alert(arrays.length);
//随机从数组中获取四个元素组成验证码
for(var i = 0; i < 4; i++) {
//随机获取一个数组的下标
var r = parseInt(Math.random() * arrays.length);
code += arrays[r];
}
document.getElementById('code').innerHTML = code; //将验证码写入指定区域
}
//效验验证码(表单被提交时触发)
function check() {
//获取用户输入的验证码
var input_code = document.getElementById('vcode').value;
if(input_code.toLowerCase() == code.toLowerCase()) {
//验证码正确(表单提交)
return true;
}
alert("请输入正确的验证码!");
//验证码不正确,表单不允许提交
return false;
}
</script>
</html>