字符型验证码(十四)

一、验证码简介

1.什么是验证码

在开发爬虫的过程中会遇到一种常见的反爬措施,验证码。验证码(CAPTCHA)是“Completely Automated Public Turing test to tell Computers and Humans Apart”(全自动区分计算机和人类的图灵测试)的缩写,是一种区分用户是计算机还是人的公共全自动程序

2.验证码种类

验证码自面世以来,不断发展,图形验证码可以分为以下几类:

  • 字符型验证码:这类验证码大多是计算机随机产生一个字符串,在把字符串增加噪点、干扰线、变形、重叠、不同颜色、扭曲组成一张图片来增加识别难度。

  • 滑动验证码:也叫行为验证码,比较流行的一种验证码,通过用户的操作行为来完成验证,其中最出名的就是极验。

    滑动验证码的原理就是使用机器学习中的深度学习技术,根据一些特征来区分是否为正常用户。通过记录用户的滑动速度,还有每一小段时间的瞬时速度,用户鼠标点击情况,以及滑动后的匹配程度来识别。而且,不是说滑动到正确位置就是验证通过,而是根据特征识别来区分是否为真用户,滑到正确位置只是一个必要条件。

  • 点触验证码:点击类验证码都是给出一张包含文字的图片,通过文字提醒用户点击图中相同字的位置进行验证。

二、图像处理库

pillow(https://www.jianshu.com/p/cd6f4e138af6


官方文档:https://pillow.readthedocs.io/en/latest/installation.html

三、简单字符串验证码的处理

1.灰度化

像素点是最小的图片单元,一张图片由很多像素点构成,一个像素点的颜色是由RGB三个值来表现的,所以一个像素点对应三个颜色向量矩阵,我们对图像的处理就是对这个像素点的操作。

图片的灰度化,就是让像素点矩阵中的每一个像素点满足 R=G=B,此时这个值叫做灰度值,白色为255,黑色为0
灰度转化一般公式为:

R=G=B = 处理前的 RX0.3 + GX0.59 + B*0.11

from PIL import Image
image = Image.open('code.jpg')
im = image.convert('L')

2.二值化

图像的二值化,就是将图像的像素点矩阵中的每个像素点的灰度值设置为0(黑色)或255(白色),从而实现二值化,将整个图像呈现出明显的只有黑和白的视觉效果。

二值化原理是利用设定的一个阈值来判断图像像素是0还是255, 一般小于阈值的像素点变为0, 大于的变成255。

这个临界灰度值就被称为阈值,阈值的设置很重要,阈值过大或过小都会对图片造成损坏。

选择阈值的原则是:既要尽可能保存图片信息,又要尽可能减少背景和噪声的干扰。

二值化的优点:进一步的减小数据量,尽可能保存图片的信息,尽可能的减少背景的噪声干扰。

常用阈值选择的方法是:
​----灰度平局值法: 取127 (0~255的中数, (0+255)/2 = 127)
平均值法:
​ ----计算像素点矩阵中的所有像素点的灰度值的平均值avg
-----迭代法: 选择一个近似阈值作为估计值的初始值,然后进行分割图像,根据产生的子图像的特征来选取新的阈值,在利用新的阈值分割图像,经过多次循环,使得错误分割的图像像素点降到最小。

from PIL import Image


def to_value(img):
    # 获取尺寸
    w, h = img.size
    print('这个宽为%s,高为%s' % (w, h))
    # 获取像素
    pixes = img.load()
    total = []
    for i in range(w):
        for j in range(h):
            total.append(pixes[i, j])
    print(total)
    # 计算平均值
    avg = sum(total)//len(total)
    #进行二值化处理(使图像显示出来要么是白色,要么是黑色)
    for i in range(w):
        for j in range(h):
            if pixes[i, j] < avg:
                pixes[i, j] = 0
            else:
                pixes[i, j] = 255
    # return img.point(lambda x: 0 if x < avg else 255)返回一个新的img对象


img = Image.open('genimage.png')
# # 增强对比度
img = img.point(lambda x: 1.2*x)
# 进行图像灰度化处理
img = img.convert('L')
to_value(img)
img.show()

3.降噪

经过了二值化处理,整个图片像素就被分为了两个值0和255, 如果一个像素点是图片或者干扰因素的一部分,那么她的灰度值一定是0(黑色),如果一个点是背景,其灰度值应该是255(白色)。

所以对于孤立的噪点,他的周围应该都是白色,或者大多数点都是白色的,所以在判断的时候条件应该放宽,一个点是黑色并且相邻的点为白色的点的个数大于一个固定的值,那么这个点就是噪点。

from PIL import Image

def noise_reduction(img):
    w, h = img.size
    pixes = img.load()
    # 先处理4条边
    # 顶边
    for i in range(w):
        if pixes[i,0] == 0:
            if pixes[i, 1] == 255:
                pixes[i, 0] = 255
    # 底边
    for i in range(w):
        if pixes[i,h-1] == 0:
            if pixes[i, h-2] == 255:
                pixes[i, h-1] = 255

    # 左边
    for i in range(h):
        if pixes[0, i] == 0:
            if [1, i] == 255:
                pixes[0, i] = 255

    # 右边
    for i in range(h):
        if pixes[w-1, i] == 0:
            if [w-2, i] == 255:
                pixes[w-1, i] = 255

    # 处理其他的点
    for i in range(1, w-1):
        for j in range(1, h-1):
            if pixes[i, j] == 0:
                sum = pixes[i+1, j] + pixes[i, j+1] + pixes[i-1, j] + pixes[i, j-1] + pixes[i-1, j-1] + pixes[i+1, j-1] + pixes[i+1, j+1] + pixes[i-1, j+1]
                if sum // 255 > 4:
                    pixes[i, j] = 255

    return img

四、识别

字符识别可使用谷歌开源项目------Tesseract OCR

1.工具安装

1.1Tesseract OCR引擎安装

github地址:https://github.com/tesseract-ocr/tesseract/wiki

1.2 Python Tesseract安装

Python -Tesseract是一种用于Python的光学字符识别(OCR)工具。也就是说,它将识别和“读取”图像中嵌入的文本。Python-tesseract是对谷歌Tesseract OCR引擎的python封装。它还可用作Tesseract的独立调用脚本,因为它可以读取Pillow和Leptonica图像库支持的所有图像类型,包括jpeg、png、gif、bmp、tiff等。

官方文档:https://github.com/madmaze/pytesseract

安装:
pip install pytesseract
简单使用:
try:
    from PIL import Image
except ImportError:
    import Image
import pytesseract

# If you don't have tesseract executable in your PATH, include the following:
pytesseract.pytesseract.tesseract_cmd = r'<full_path_to_your_tesseract_executable>'
# Example tesseract_cmd = r'C:\Program Files (x86)\Tesseract-OCR\tesseract'

# Simple image to string
print(pytesseract.image_to_string(Image.open('test.png')))

# French text image to string
print(pytesseract.image_to_string(Image.open('test-european.jpg'), lang='fra'))
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350