简单图形验证码的识别

目前,许多网站采取各种各样的措施来反爬虫,其中一个措施是使用验证码。随着技术的发展,验证码的花样越来越多。验证码最初是几个数字组合的简单的图形验证码,后来加入了英文字母和混淆曲线。有的网站还可能看到中文字符的验证码。

后来 12306 验证码的出现使得行为验证码开始发展起来,用过 12306 的用户肯定多少为它的验证码头疼过。我们需要识别文字,点击与文字描述相符的图片,验证码完全正确,验证才能通过。现在这种交互式验证码越来越多,如极验滑动验证码需要滑动拼合滑块才可以完成验证,点触验证码需要完全点击正确结果才可以完成验证,另外还有滑动宫格验证码、计算题验证码等。

图形验证码的识别

图形验证码,是最简单的一种验证码,这种验证码最早出现,现在也很常见,一般由 4 位字母或者数字组成。例如,中国知网的注册页面有类似的验证码,链接为 http://my.cnki.net/elibregister/commonRegister.aspx,如下图:
简单图形验证码的识别_第1张图片
表单的最后一项就是图形验证码,我们必须完全正确输入图中的字符才能够完成注册。

因此这里我们讲解一种能将图片翻译成文字的技术。将图片翻译成文字一般被称为光学文字识别(Optical Character Recognition),简写为OCR。

本节目标

以知网的验证码为例,利用 OCR 技术识别图形验证码。

准备工作

识别图形验证码需要库 tesserocr 。因此需要提前进行安装。

获取验证码

为了便于实验,我们先将验证码的图片保存到本地。打开开发者工具,找到对应的验证码元素。验证码元素是一张照片,它的src属性是 CheckCode.aspx 。我们打开这个链接后将其保存为图片格式,命名为 code.jpg。
简单图形验证码的识别_第2张图片
这样我们就得到一张验证码图片,以供测试识别使用。

识别测试

接下来新建一个项目,将验证码图片放到项目根目录下,使用 tesserocr 库识别验证码,代码如下:

import tesserocr
from PIL import Image

image = Image.open('code.jpg')
result = tesserocr.image_to_text(image)
prin(result)

这里我们新建了一个 Image 对象,然后调用 tesserocr 的 image_to_text() 方法。传入该 Image 对象即可完成识别。结果如下所示:


另外,tesserocr 还有一个更加简单的方法,这个方法可以直接将图片文件转为字符串,代码如下:

import tesserocr

print(tesserocr.file_to_text('code.jpg'))

不过,此种方法的识别效果不如上一种好。

验证码处理

接下来我们换一个验证码,将其命名为 code2.jpg,如下图:
简单图形验证码的识别_第3张图片
重新使用之前的代码来测试:

import tesserocr
from PIL import Image

image = Image.open('code2.jpg')
result = tesserocr.image_to_text(image)
print(result)

可以看到如下输出结果:


这次识别和实际结果有偏差,这是因为验证码内的多余线条干扰了图片的识别。对于这种情况,我们还需要做一下额外的处理,如转灰度、二值化等操作。

# 我们可以使用Image对象的convert()方法传入'L'参数,将图片转化为灰度图像

image = image.convert('L')
image.show()

# 传入‘1’即可将图片进行二值化处理

image = image.convert('1')
image.show()

我们还可以指定二值化的阈值。上面的方法采用的阈值默认是127。不过我们不能直接转化原图,要将原图转化为灰度图,然后指定二值化阈值,进行二值化处理。代码如下:

image = image.convert('L')
threshold = 80
table = []
for i in range(256):
    if i < threshold:
        table.append(0)
    else:
        table.append(1)
image = image.point(table, '1')
image.show()

在这里,变量 threshold 代表二值化阈值,阈值设置为80。然后通过 point() 方法将其做二值化处理。结果如下:

我们发现原来验证码中的线条已经去除,整个验证码变得黑白分明。这时重新识别验证码,代码如下:

import tesserocr
from PIL import Image

image = Image.open('code2.jpg')
image = image.convert('1')
result = tesserocr.image_to_text(image)
print(result)

运行结果如下:

那么,针对一些有干扰的图片,我们可以做一些灰度和二值化处理,这样会提高图片识别的正确率。

你可能感兴趣的:(模块,爬虫,笔记)