使用SCF快速部署验证码识别接口

Posted 乂乂又又

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用SCF快速部署验证码识别接口相关的知识,希望对你有一定的参考价值。

一、本文介绍

验证码识别是搞爬虫

实现自动化脚本避不开的一个问题,


通常验证码识别程序要么部署在本地,

要么部署在服务器端,


如果部署在服务器端就需要

自己去搭建配置网络环境并编写调用接口,

这是一个极其繁琐耗时的过程。


但是现在我们通过无服务器云函数(SCF),

就可以快速将本地验证码识别程序发布上线,

极大地提高了开发效率。


废话少说,上图 ↓


使用SCF快速部署验证码识别接口



一种比较简单的验证码



使用SCF快速部署验证码识别接口



识别扭曲变形的验证码


可以看到,识别效果还是蛮好的,

甚至超过了肉眼识别率。


二、操作步骤


传统的验证码识别流程是


  1. 图像预处理(灰化,去噪,切割,二值化,去干扰线等)

  2. 验证码字符特征提取(SVM,CNN等)

  3. 验证码识别


下面我就带大家一起来创建、编写

并发布上线一个验证识别云函数


第一步:新建python云函数


参见我之前的系列文章

《万物皆可Serverless之使用SCF+COS快速开发全栈应用》


第二步:编写验证识别云函数




一个简单的验证码


Life is short, show me the code.

这里我就以一个

最简单的验证码识别程序为例,

直接上代码


 
   
   
 

import io

import os

import time

from PIL import Image as image

import json


#字符特征

chars = {

    '1': [11101, ...],

    '2': [10010, ...],

    '3': [01001, ...],

    # 其他字符特征...

}



# 灰度处理

def covergrey(img):

    return img.convert('L')


# 去除验证码边框

def clearedge(img):

    for y in range(img.size[1]):

        img.putpixel((0, y), 255)

        img.putpixel((1, y), 255)

        img.putpixel((2, y), 255)

        img.putpixel((img.size[0]-1, y), 255)

        img.putpixel((img.size[0]-2, y), 255)

        img.putpixel((img.size[0]-3, y), 255)

    for x in range(img.size[0]):

        img.putpixel((x, 0), 255)

        img.putpixel((x, 1), 255)

        img.putpixel((x, 2), 255)

        img.putpixel((x, img.size[1]-1), 255)

        img.putpixel((x, img.size[1]-2), 255)

        img.putpixel((x, img.size[1]-3), 255)

    return img


# 去除干扰线并转换为黑白照片

def clearline(img):

    for y in range(img.size[1]):

        for x in range(img.size[0]):

            if int(img.getpixel((x, y))) >= 110:

                img.putpixel((x, y), 0xff)

            else:

                img.putpixel((x, y), 0x0)

    return img


# 去噪/pnum-去噪效率

def del_noise(impnum=3):

    w, h = im.size

    white = 255

    black = 0

    for i in range(0, w):

        im.putpixel((i, 0), white)

        im.putpixel((i, h - 1), white)

    for i in range(0, h):

        im.putpixel((0, i), white)

        im.putpixel((w - 1, i), white)

    for i in range(1, w - 1):

        for j in range(1, h - 1):

            val = im.getpixel((i, j))

            if val == black:

                cnt = 0

                for ii in range(-12):

                    for jj in range(-12):

                        if im.getpixel((i + ii, j + jj)) == black:

                            cnt += 1

                if cnt < pnum:

                    im.putpixel((i, j), white)

            else:

                cnt = 0

                for ii in range(-12):

                    for jj in range(-12):

                        if im.getpixel((i + ii, j + jj)) == black:

                            cnt += 1

                if cnt >= 7:

                    im.putpixel((i, j), black)

    return im


# 图片数据二值化

def two_value(code_data):

    table = []

    for i in code_data:

        if i < 140:  # 二值化分界线140

            table.append(0)

        else:

            table.append(1)

    return table


# 图片预处理



def pre_img(img):

    img = covergrey(img)  # 去色

    img = clearedge(img)  # 去边

    img = clearline(img)  # 去线

    img = del_noise(img)  # 去噪

    return img


# 处理图片数据

def data_img(img):

    code_data = []  # 验证码数据列表

    for i in range(4):  # 切割验证码

        x = 5 + i * 18  # 可用PS确定图片切割位置

        code_data.append(img.crop((x, 9, x + 1833)).getdata())

        code_data[i] = two_value(code_data[i])  # 二值化数据

    return code_data


# 验证码识别

def identify(data):

    code = ['']*4  # 验证码字符列表

    diff_min = [432]*4  # 初始化最小距离--不符合的数据点个数(共120数据点)

    for char in chars:  # 遍历验证码字符(每个字符比较一次4个验证码)

        diff = [0]*4  # 各验证码差距值(每个字符判断前重置此距离)

        for i in range(4):  # 计算四个验证码

            for j in range(432):  # 逐个像素比较验证码特征

                if data[i][j] != chars[char][j]:

                    diff[i] += 1  # 距离+1

        for i in range(4):

            if diff[i] < diff_min[i]:  # 比已有距离还要小(更加符合)

                diff_min[i] = diff[i]  # 刷新最小距离

                code[i] = char  # 刷新最佳验证码

    return ''.join(code)  # 输出结果



def predict(imgs):

    code = ''

    img = imgs.read()

    img = image.open(io.BytesIO(img))

    img = pre_img(img)  # 预处理图片

    data = data_img(img)  # 获取图片数据

    code = identify(data)  # 识别验证码

    return code



def apiReply(replycode=200):

    return {

        "isBase64Encoded"False,

        "statusCode": code,

        "headers": {'Content-Type''application/json'"Access-Control-Allow-Origin""*"},

        "body": json.dumps(reply, ensure_ascii=False)

    }



def main_handler(eventcontext):

    main_start = time.time()

    flag = True if 'image' in event['queryString'else False

    code = predict(event['queryString']['image']if 'image' in event['queryString'else '无效的请求'

    return apiReply({

        'ok': flag,

        'code': code,

        'spendTime'str(time.time()-main_start)

    })


以上是关于使用SCF快速部署验证码识别接口的主要内容,如果未能解决你的问题,请参考以下文章

Kaggle+SCF端到端验证码识别从训练到部署

中文项目:快速识别验证码,CNN也能为爬虫保驾护航

验证码识别与生成类API调用的代码示例合集:六位图片验证码生成四位图片验证码生成简单验证码识别等

CNN+BLSTM+CTC的验证码识别从训练到部署

爬虫遇到头疼的验证码?Python实战讲解弹窗处理和验证码识别

5行Python实现验证码识别,太稳了