安装

首先安装 Tesseract-OCR,在 Mac 端可直接使用 Homebrew 进行安装

brew install tesseract

然后是 pytesseract,这是对 Tesseract 的封装,可直接在 Python 中调用。

pip install pytesseract

和用于图片处理的 PIL

pip install pillow

以及用于发送 HTTP 请求的 requests

pip install requests

代码实现

用 Chrome 打开教务系统首页,登录页面如图

img

首先的问题是如何获取验证码。

打开开发者工具切换到 Network 标签下,点击“看不清,换一张”刷新验证码,获取到如下请求

img

其只有一个参数为随机生成的 0-1 之间的浮点数。

captcha_url = 'http://urp.xxxx.cn/validateCodeAction.do'

captcha_data = {
    'random': random.random()
}

response = session.get(captcha_url, params=captcha_data)

file = open('captcha.png', 'wb')
file.write(response.content)
file.close()

获取一张验证码保存至本地,验证码类似于此

img

但是由于背景的干扰,直接对此图片进行识别成功率很低,所以还需要对它进行处理。

打开刚才保存的图片,由于图片太小影响识别,首先将其放大两倍。

im = Image.open('captcha.png')
w, h = im.size
im = im.resize((w*2, h*2))

然后进行灰度处理。

gray = im.convert('L')

接下来是最重要的一步操作 —— 二值化

简单地来说,就是将灰度图像大于某个临界灰度值的像素灰度设为灰度极大值,把小于这个值的像素灰度设为灰度极小值,从而呈现出明显的黑白效果。

threshold = 150
able = []
for i in range(256):
    if i < threshold:
        table.append(0)
    else:
        table.append(1)
out = gray.point(table, '1')
out.save('captcha_thresholded.png')

处理之后的效果如图

img

对比原图可以说清晰了不少,此时就可以较为精确地识别内容了。

由于依然不能保证 100% 的识别准确度,我还对识别结果进行了一些处理。

首先去除结果字符串中除字母和数字外的其它字符,然后验证结果是否为四位长度。如果长度不对,就刷新获取新的验证码进行识别。

最终的识别函数如下:

def get_captcha(session):
    for i in range(10):
        captcha_url = 'http://urp.xxxx.cn/validateCodeAction.do'

        captcha_data = {
            'random': random.random()
        }

        response = session.get(captcha_url, params=captcha_data)

        file = open('captcha.png', 'wb')
        file.write(response.content)
        file.close()

        im = Image.open('captcha.png')
        w, h = im.size
        im = im.resize((w*2, h*2))
        gray = im.convert('L')  # 灰度处理

        threshold = 150
        table = []
        for i in range(256):
            if i < threshold:
                table.append(0)
            else:
                table.append(1)
        out = gray.point(table, '1')
        out.save('captcha_thresholded.png')

        th = Image.open('captcha_thresholded.png')
        code = pytesseract.image_to_string(th)

        code = filter(str.isalnum, code)
        code = ''.join(list(code))

        if len(code) == 4:
            break

    return code

获取到验证码,就可以进行登录了。

在账号、密码和验证码栏随便填写一些信息并点击登录,在所有请求中找到这一条为登录请求

img

点开详细信息划到最下面,得到登录信息的表单结构,其中 zjh 为账号,mm 为密码,v_yzm 为验证码,其它项为空可忽略(先把命名的拖出去枪毙 5 分钟,这都什么鬼名字)。

img

仿照此结构构造登录表单

post_data = {
    'zjh': username,
    'mm': password,
    'v_yzm': captcha
}

发送登录请求

session.post(login_url, data=post_data)

最后,我们可以通过登录成功页面中的地址来判断是否登录成功,如果登录成功 ststus_code 即为 200。

outline_url = 'http://urp.xxxx.cn/outlineAction.do'
response = session.get(outline_url)

if(response.status_code == 200):
    print('success')
else:
    print('false')
Last modification:December 17th, 2019 at 08:18 pm
If you think my article is useful to you, please feel free to appreciate