您当前的位置:首页 > 计算机 > 编程开发 > Python

基于pytesseract的简单验证码识别

时间:06-03来源:作者:点击数:

今天我们谈谈简单验证码的识别工作,这里说的简单验证码是这样的:


验证码

说是简单验证码其实在网站验证中使用十分广泛,经常会出现。

一般来说验证码在网页中是以图片的形式显示出来, 在网页源码可能存在于以下几种方式:

  1. 是在html语句中直接放入编码后的验证码信息
  2. 是在html语句中直接放入请求的验证码url信息

针对第1种来说,普遍的使用base64进行编码。

名词解释

正式讲解前简单做一下名词解释:

  • 验证码

是一种区分用户是计算机还是人的公共全自动程序。可以防止:恶意破解密码、刷票、论坛灌水,有效防止某个黑客对某一个特定注册用户用特定程序暴力破解方式进行不断的登陆尝试,实际上用验证码是现在很多网站通行的方式,我们利用比较简易的方式实现了这个功能。这个问题可以由计算机生成并评判,但是必须只有人类才能解答。由于计算机无法解答验证码的问题,所以回答出问题的用户就可以被认为是人类(百度百科)。

  • base64

Base64是网络上最常见的用于传输8Bit字节码的编码方式之一,Base64就是一种基于64个可打印字符来表示二进制数据的方法。Base64编码是从二进制到字符的过程,可用于在HTTP环境下传递较长的标识信息。例如采用了Base64来将一个较长的唯一标识符(一般为128-bit的UUID)编码为一个字符串,用作HTTP表单和HTTP GET URL中的参数。在其他应用程序中,也常常需要把二进制数据编码为适合放在URL(包括隐藏表单域)中的形式。此时,采用Base64编码具有不可读性,需要解码后才能阅读(百度百科)。

  • OCR

是指电子设备(例如扫描仪或数码相机)检查纸上打印的字符,通过检测暗、亮的模式确定其形状,然后用字符识别方法将形状翻译成计算机文字的过程。

  • 方式1/2的区别

我随便找了两个网址,通过firefox对其访问过程进行了查看,对于第1种的访问过程是这样的:

对于第2种的访问过程是这样的:

通常我们在客户端显示随机验证码图片的时候是通过<img src="url"/>这个标签来显示的验证码图片。这个url就是随机验证码的图片。当网页将网站源码加载完成后,会再次通过这个url地址请求服务器,加重服务器负担(方式2)

然而<img src=”data:image/jpg;base64,imgcode...”>也可以显示图片的,需要做的就是将图片重新按base64格式进行编码。这样就不会再次发送一次HTTP请求,而是让客户端浏览器解析base64的代码(方式1)。

通过对比两张图可以发现,方式2确实是多了一次HTTP请求。

相关技术

验证码的解析我们这里用到的Python第三方库有requestsPillowpytesseract以及Tesseract-OCR引擎

  • requests:一个简单易用的Python HTTP访问库,总之很强大。
  • Pillow:Python里的图像处理库(PIL:Python Image Library),提供了广泛的文件格式支持,强大的图像处理能力,主要包括图像储存、图像显示、格式转换以及基本的图像处理操作等。
  • pytesseract:google的Tesseract-OCR引擎的一个python封装包,用于python的光学字符识别(OCR)工具。 它可以识别和“读取”图像中嵌入的文本。
  • Tesseract-OCR引擎:开源的OCR识别引擎,初期Tesseract引擎由HP实验室研发,后来贡献给了开源软件业,后经由Google进行改进,消除bug,优化,重新发布。

这里Pillow和pytesseract可以通过pip安装,Tesseract-OCR引擎需要下载exe文件安装,关注微信公众号:城东书院,发送:teocr,即可获得下载链接。

url或base64编码转成图片

验证码解析,首先要有验证码才行,这个必须是图片啊。但是我们看网页源码都是一长串的编码或者是url链接,这个该怎么办呢?类似这种的。

所以我们识别验证码的第一就是得到验证码图片,具体的代码如下:

import codecs, requests#使用codes打开文件可以指定具体的编码
from lxml import etree#lxml是以Python语言处理XML和HTML的功能的库。
from io import BytesIO#操作二进制文件
from PIL import Image#图形处理的库

with codecs.open("code.html","r","utf-8") as f:
    html = f.read()
tree = etree.HTML(html)#因为我们通过read()函数读取字符串,但是我们需要使用HTML文档,通过etree.HTML将得到的字符串进行HTML解析。
img_data = tree.xpath("//@src")
#对得到HTML文本进行xpath,找到验证码的具体内容。
#详细xpath的使用可以参考这篇文章:XPath 与 lxml - CSDN博客 是一门在 XML 文档中查找信息的语言。
# XPath 可用来在 XML 文档中对元素和属性进行遍历。XPath 是 W3C XSLT 标准的主要元素,并且 XQuery 和 XPointer 都构建于 XPath 表达之上。
# 详细可见:XPath 教程
img_data1 = img_data[0].partition(',')[-1]#得到的字符串按照','进行分割成列表,取最后一个,也就是base64编码
binary_img_data1 = img_data1.decode('base64')#base64解码
file_img1 = BytesIO(binary_img_data1)#对得到的二进制数据进行操作
img1 = Image.open(file_img1)
img1.save('img1.png')#保存验证码#url的验证码解析
response = requests.get(img_data[1])#访问具体的验证码url
file_img2 = BytesIO(response.content)#对得到的二进制数据进行操作
img2 = Image.open(file_img2)
img2.save('img2.png')#保存验证码

图片再处理

因为我们要使用OCR技术,为了使验证码图片更易识别,我们需要对图片进行一些处理。首先分析一下验证码图片。我们打开Photoshop对验证码进行取色分析(如下图),基本上可以得知背景色的RGB数值一般大于140,具体的验证码RGB数值一般都会小于这个数值,当然这个数值你可以根据自己观察的情况进行调整,只要符合你的要求就行。

所以我们形成了如下代码:

gray = img2.convert('L')
#图像对象转化(L:8位像素,表示黑和白)
#可以参考:Python图像处理库PIL的基本概念介绍 - icamera0的博客 - CSDN博客
bw = gray.point(lambda x:0 if x<140 else 255,'1')#如果RGB数值小于140的变成1,否则是255。也就是将验证码背景变成白色,具体字符变成黑色。
bw.save('aa.png')

效果如下:

读取验证码

使用pytesseract对验证码进行读取

vcode = pytesseract.image_to_string(bw).replace(' ', '')
print vcode

因为验证码中有空格,但是这个在网站验证中是不需要填入的,所以我们要去掉。

最终效果如下:

总结

今天介绍了简单的验证码识别,主要涉及到Pillowpytesseract这两个库的使用。以后有时间再谈谈复杂验证码的识别。

方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门