Selenium+Tesseract破解登录验证码

前言

我破解的登录验证码类型是数学公式的这种,即 .......是不是看起来比较简单,但是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 pytesseract

 

2 识别代码

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[1] == ".":  # -号经常别识别成.,替换为-号
            data[1] = "-"

        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,否则截不到想要的验证码。
 

你可能感兴趣的:(selenium,tesseract,python,验证码,python爬虫)