Selenium+Tesseract破解登录验证码
前言 我破解的登录验证码类型是数学公式的这种,即http://www.51testing.com/attachments/2020/06/15243603_202006291343521Kvmj.jpg.......是不是看起来比较简单,但是Tesseract对这种图片的识别率也很低,后期要提升识别率的话,我觉得一是要对图片进行降噪和锐化等处理,二是要对Tesseract预先训练,训练的工具我推荐jTessBoxEditor,大家有兴趣的可以了解一下。
1 安装Tesseract
1.1 下载Tesseract。地址为:Windows Installer made with MinGW-w64,下载完直接安装即可,安装完成后配置一下环境变量。编辑一下系统变量里的path,添加如下环境变量。
C:\Program Files(x86)\Tesseract-OCR安装完成后,在cmd命令行窗口输入
tesseract -v
出现如下内容证明安装成功。
1.2 安装pytesseract
pip install pytesseract2 识别代码 2.1 识别逻辑。首先使用selenium到浏览器找到验证码标签,然后截图保存下来,再用tesseract去识别这张图片。如果识别失败,再用selenium点击一下验证码图片,重新生成一张验证码,再重复之前的识别逻辑。如果识别成功,使用eval计算出算式的数值,填入后点击登录按钮。
2.2 代码
import time
import pytesseract
from selenium.webdriver import Chrome
from PIL import Image
driver = Chrome(executable_path=r'D:\Chrome Downloads\chromedriver.exe')# chromedriver的存放路径
url = "http://60.210.111.130:8002/Login.aspx"
print("开始爬取,url为{}".format(url))
driver.get(url=url)
time.sleep(2)
# 找到username的input标签,填入用户名
username = driver.find_element_by_id('txtUserName')
username.clear()
username.send_keys('your username')
# 找到password的input标签,填入密码。如果再次点击验证码时密码被清空,那么这段代码要放到while循环内部
password = driver.find_element_by_id('pwd')
password.clear()
password.send_keys('your password')
# 进行20次尝试
times = 0
while True:
try:
element = driver.find_element_by_id('validimg')
element.click()
# 每次请求的验证码图片都不一样,所以只能截图,保存至本地。
driver.save_screenshot('validImage.png')
# windows系统要注意页面缩放比例,如果是150%,那么每项都*1.5。linux系统不需要
left = element.location['x']*1.5
top = element.location['y']*1.5
right = element.location['x']*1.5 + element.size['width']*1.5
bottom = element.location['y']*1.5 + element.size['height']*1.5
im = Image.open('validImage.png')
im = im.crop((left, top, right, bottom))# 抠图
im.save('validImage.png')
data = pytesseract.image_to_string(Image.open('validImage.png'))
if len(data) < 3:# 未识别
continue
if len(data) == 4:# 识别的带=号,去掉=号
data = data[:3]
if data == ".":# -号经常别识别成.,替换为-号
data = "-"
print("ocr识别结果", data)
valid_code = driver.find_element_by_id('validcode')
valid_code.clear()
valid_code.send_keys(eval(data))
time.sleep(1)
btnLogin = driver.find_element_by_id('btnLogin')
btnLogin.click()
# 获取cookie
login_cookie = driver.get_cookie('ASP.NET_SessionId')
total_cookie = 'ASP.NET_SessionId={}; autoLogin=null; user=null; pwd=null'.format(login_cookie['value'])
print("total_cookie,{}".format(total_cookie))
break
except Exception as e:
time.sleep(2)
times += 1
print("破解验证码失败,重试第{}次".format(times))
if times == 20:
raise RuntimeError
# linux系统要注意退出chromedriver。否则如果多次执行的话,会生成大量的chromedriver进程。
driver.quit()执行结果如下:
其中比较坑的一点就是,windows系统显示有缩放比例。可以在桌面右键-显示设置-缩放与布局中看到。如果缩放比例是150%的话,那么截图部分,每项参数都要*1.5,否则截不到想要的验证码。
谢谢
学习
页:
[1]