python 识别图形验证码_Python网络爬虫之如何用代码识别图片验证码

验证码

当我们在爬取某些网站的时候,对于一些频繁请求,网站会识别你是机器还是人。如果是机器,直接不允许你访问这个网站了,直接返回404或者禁止访问。

最常见的方式就是验证码。验证码的主要功能就是区分当前访问网站的是人还是代码。越难识别或者越模糊的验证码区分能力却强。网站想方设法的搞一些手段来对付技术,就是想让服务器不用承受代码大量访问的压力,这样就能够为正常用户提供流畅的服务了。

但是,技术又能对付人们的想法。一来一去,就有了各种各样的变态验证码,也有了各种各样的应对方式。

常见的验证码有这么几种:

  • 图像验证
  • 语音验证
  • 短信验证
  • 极验验证
  • 点击验证

如何识别图像验证码

来看看这些图片验证码:

python 识别图形验证码_Python网络爬虫之如何用代码识别图片验证码_第1张图片

这些验证码大多是数字和字母组成,然后在此之上再添加一些模糊的噪点或者横线竖线,或者把这些字符扭曲一下,增加识别难度。

接下来我们思考一下,我们要识别这类验证码要怎么做呢?

首先要处理一下验证码图片,什么乱七八糟的噪点都尽量把它们去掉,让图片尽量黑白,尽量只剩下字符本身,然后再用 python 强大的 OCR 工具:

Python-tesseract

来识别我们优化好的图片,这样正确率就会大大的提高。

我们用 python 搞几张识别难度不同的验证码:

第一张

a7c28491d5051e36b9327ce58437a31b.png

难度系数: ★,一颗星

第二张

693205d6c14acbeab2d3b8eb918c3685.png

难度系数: ★★,两颗星

第三张

fd419856999852bf3f45e0c1ab32db08.png

难度系数: ★★★,三颗星

第四张

5168bc2f2277bf1270daa6c51913a4c7.png

难度系数: ★★★★,四颗星

第五张

daeef32ca5254f50054ba7aa04588ae5.png

难度系数 : ★★★★★,五颗星

先对第一张进行识别。第一张看起来比较清晰,识别起来没有难度。

先安装一下 pytesseract :

pip install pytesseract

接着安装一下 tesseract-ocr:

如果是 ubuntu 系统可以直接使用如下命令安装:

sudo apt install tesseract-ocr

如果是 win 系统自行百度一下安装 tesseract-ocr 以及环境变量配置。

完了之后就导入相关模块到代码文件中:

try:    from PIL import Imageexcept ImportError:    import Imageimport pytesseract

接着打开第一张图片,使用 pytesseract 识别,打印出结果:

captcha = Image.open("captcha1.png")result = pytesseract.image_to_string(captcha)print(result)

结果:

d0817a2ef3a857ca4b61a24e7c966dd9.png

识别成功!

接着来识别第 2 张:

693205d6c14acbeab2d3b8eb918c3685.png
captcha = Image.open("claptcha2.png")result = pytesseract.image_to_string(captcha)print(result)

结果是

7cb935ced4b22f997280cbcdada079ca.png

1924,结果有误!pytesseract 准确率没那么高,没办法识别太多噪点的图片。如果这个图片再加上一点彩色背景如下图:

fd419856999852bf3f45e0c1ab32db08.png

对 pytesseract 来说更有难度。

所以我们先对这张图片灰度处理一下:

captcha = Image.open("captcha2.png")result = captcha.convert('L')result.show()

图片就变成灰了:

python 识别图形验证码_Python网络爬虫之如何用代码识别图片验证码_第2张图片

虽然灰了,但是还不够。除了处理灰度还需要对其进行“二值化”:

def convert_img(img,threshold):    img = img.convert("L")  # 处理灰度    pixels = img.load()    for x in range(img.width):        for y in range(img.height):            if pixels[x, y] > threshold:                pixels[x, y] = 255            else:                pixels[x, y] = 0    return img

调用一下:

convert_img(captcha,150)

图片就变成了:

python 识别图形验证码_Python网络爬虫之如何用代码识别图片验证码_第3张图片

非常清晰!

这时候对这张图片识别一下:

# 识别一下result = pytesseract.image_to_string(result)print(result)

成功识别!

27cc4fe73260ff720b3942077c5c67e1.png

接下来再来看看有毛有噪的图片:

5168bc2f2277bf1270daa6c51913a4c7.png

这时候直接去识别是识别不出来的。所以还是老办法,先处理灰度,再进行“二值化”。这次再降一下噪:

data = img.getdata()    w,h = img.size    count = 0    for x in range(1,h-1):        for y in range(1, h - 1):            # 找出各个像素方向            mid_pixel = data[w * y + x]            if mid_pixel == 0:                top_pixel = data[w * (y - 1) + x]                left_pixel = data[w * y + (x - 1)]                down_pixel = data[w * (y + 1) + x]                right_pixel = data[w * y + (x + 1)]                if top_pixel == 0:                    count += 1                if left_pixel == 0:                    count += 1                if down_pixel == 0:                    count += 1                if right_pixel == 0:                    count += 1                if count > 4:                    img.putpixel((x, y), 0)

图片变成这样了:

2ce07d8a26bed523010b62e10a54246a.png

再识别一下:

27cc4fe73260ff720b3942077c5c67e1.png

不过,pytesseract 不是万能的,对于稍微复杂一点的就识别不出来了。至于这张:

daeef32ca5254f50054ba7aa04588ae5.png

我们肉眼都很难看出它是 1l1l0oO0,更不要说用代码去识别了,所以 pytesseract 也识别不了。

对于一些简单的验证码,使用 pytesseract 还是可以的。如果我们想提高 pytesseract 识别率,还可以去搞些图片去训练一下 tesseract-ocr。这样,当我们遇到一些登录需要验证码的网站时,直接引入本文识别验证码的方法就可以继续爬数据了。

你可能感兴趣的:(python,识别图形验证码,python如何让图片镜像翻转,python识别验证码去干扰,向图片添加扰动python代码)