验证码的识别
随着爬虫越来越多,许多网站都采取了各种各样的反爬虫机制,其中最常见的就是使用验证码,现在随着技术的发展,验证码已经由数字演变成了字母,滑动,九宫格等各种验证码
前言
由于tesserocr库是比较老的库,目前只更新到只吃python3.7,而由于我的是python3.8经过多次尝试之后,发现还是无法使用,经过查看大量的资料,我使用了另外一个库—pytesseract
pytesseract这个库原理几乎和tesserocr库相同
图形验证码识别
我们先识别一下最简单的一种验证码,即图形验证码。这种验证码最早出现,也很常见,一般是由4位字母或者数字组成。例如http://my.cnki.net/Register/CommonRegister.aspx的登录验证码
获取验证码
首先需要安装pytesseract库
为了便于实验,我们先将验证码图片保存在本地,先测试一下
首先F12打开开发者工具,查看验证码的url
接下来访问一下这个aspx
由于验证码是动态的 所以也没有什么太大的关系
加下来把这个aspx保存下来,命名为code.png
代码:1
2
3
4
5
6
7
8
9import pytesseract
from PIL import Image
image=Image.open('D:\\code.png')
image=image.convert('RGB')
print(pytesseract.image_to_string(image))
输出结果:
Gsee
这里新建了一个Image对象,调用了pytesseract的image_to_string()方法,传入该对象即可完成识别,但是要注意的是,由于pytesseract的特殊性,处理图片时,由于图片可能不是RGBA通路的,所以最后在打开图片后等增加image.convert(‘RGB’)语句,保证图片是RGB格式的
验证码处理
接下来我们换一个验证码,命名为code2.png
重新用以下代码来测试:1
2
3
4
5
6import pytesseract
from PIL import Image
image=Image.open('D:\\code2.png')
image=image.convert('RGB')
print(pytesseract.image_to_string(image))
我刷新的这个验证码并没有出现偏差,但是例如
就会出现偏差1
2
3
4
5
6
7
8
9import pytesseract
from PIL import Image
image=Image.open('D:\\test.jpg')
image=image.convert('RGB')
print(pytesseract.image_to_string(image))
输出结果:
thye
这个时候,其实是因为验证码多余的线条干扰了图片的识别,我们在这里还需要进行额外的处理,如转灰度,二值化等操作
我们可以利用Image对象的convert()方法传入L,即可将图片转为灰度图像1
2image=image.convert('L')
image.show()
这样就成功将其灰度化
传入1即可将图片进行二值化处理1
2image=image.convert('1')
image.show()
我们还可以指定二值化的阈值,上面的方法默认采用的是127.不过我们不能直接转换,需要将图片先灰度化,然后化再指定阈值1
2
3
4
5
6
7
8
9
10image=image.convert('L')
threshold=110
table=[]
for i in range(256):
if i<threshold:
table.append(0)
else:
table.append(1)
image=image.point(table,'1')
image.show()
这里将阈值调整为110 图片中的内容才能显示完成,阈值的值是根据验证码的情况来确定的,并不是一个定值
我们看到经过处理之后的验证码,线条已经被去除,验证码变得黑白分明,这个时候才重新识别验证码1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18import pytesseract
from PIL import Image
image=Image.open('D:\\test.png')
image=image.convert('RGB')
image=image.convert('L')
threshold=110
table=[]
for i in range(256):
if i<threshold:
table.append(0)
else:
table.append(1)
image=image.point(table,'1')
print(pytesseract.image_to_string(image))
输出结果:
fhYe
针对一些有干扰的图片,我们就可以做一些灰度和二值化的处理,以此来提高图片的正确率
总结
1.tesseror库比较过时,而且版本更新较慢,目前只支持到了python3.7的版本
2.由于tesseror库无法使用,所以采用了pytesseract库,但是由于pytesseract库的特性,只会识别RGB通道的图片,所以需要在每条语句的后面都添加上image.convert(‘RGB’)
3.文字验证码较为简单,但是会有一些斑点或线条等进行干扰,所以需要采用灰度和二值化来进行处理
4.二值化处理之前需要先进行灰度化的处理,并且每个图片需要设置的阈值可能会不同,阈值不是一个定值,需要经常进行更换