Python技能树共建验证码实操2案例

Posted 梦想橡皮擦

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python技能树共建验证码实操2案例相关的知识,希望对你有一定的参考价值。

Python 验证码是什么

如果你是一个数据挖掘爱好者,那么验证码是你避免不过去的一个天坑,和各种验证码斗争,必然是你成长的一条道路,

本篇文章为你带来验证码的入门案例,来吧,一起 Coding 吧。

怎么用

数字+字母的验证码

我随便在百度图片搜索了一个验证码,如下

今天要做的是验证码识别中最简单的一种办法,采用pytesseract解决,它属于 Python 当中比较简单的OCR识别库

库的安装

使用pytesseract之前,你需要通过 pip 安装一下对应的模块 ,需要两个

pytesseract 库还有图像处理的 pillow 库了

pip install pytesseract
pip install pillow

如果你安装了这两个库之后,编写一个识别代码,一般情况下会报下面这个错误

pytesseract.pytesseract.TesseractNotFoundError: tesseract is not installed or it's not in your path

这是由于你还缺少一部分内容

安装一个 Tesseract-OCR 软件。这个软件是由 Google 维护的开源的 OCR 软件。

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

中文包的下载地址 > https://github.com/tesseract-ocr/tessdata

选择你需要的版本进行下载即可

pillow 库的基本操作

命令释义
open()打开一个图片
from PIL import Image
im = Image.open(“1.png”)
im.show()
save()保存文件
convert()convert() 是图像实例对象的一个方法,接受一个 mode 参数,用以指定一种色彩模式,mode 的取值可以是如下几种:
· 1 (1-bit pixels, black and white, stored with one pixel per byte)
· L (8-bit pixels, black and white)
· P (8-bit pixels, mapped to any other mode using a colour palette)
· RGB (3x8-bit pixels, true colour)
· RGBA (4x8-bit pixels, true colour with transparency mask)
· CMYK (4x8-bit pixels, colour separation)
· YCbCr (3x8-bit pixels, colour video format)
· I (32-bit signed integer pixels)
· F (32-bit floating point pixels)

Filter

from PIL import Image, ImageFilter
im = Image.open(1.png’)
# 高斯模糊
im.filter(ImageFilter.GaussianBlur)
# 普通模糊
im.filter(ImageFilter.BLUR)
# 边缘增强
im.filter(ImageFilter.EDGE_ENHANCE)
# 找到边缘
im.filter(ImageFilter.FIND_EDGES)
# 浮雕
im.filter(ImageFilter.EMBOSS)
# 轮廓
im.filter(ImageFilter.CONTOUR)
# 锐化
im.filter(ImageFilter.SHARPEN)
# 平滑
im.filter(ImageFilter.SMOOTH)
# 细节
im.filter(ImageFilter.DETAIL)

Format

format 属性定义了图像的格式,如果图像不是从文件打开的,那么该属性值为 None;
size 属性是一个 tuple,表示图像的宽和高(单位为像素);
mode 属性为表示图像的模式,常用的模式为:L 为灰度图,RGB 为真彩色,CMYK 为 pre-press 图像。如果文件不能打开,则抛出 IOError 异常。

验证码识别

注意安装完毕,如果还是报错,请找到模块 pytesseract.py 这个文件,对这个文件进行编辑

一般这个文件在 C:\\Program Files\\Python36\\Lib\\site-packages\\pytesseract\\pytesseract.py 位置

文件中 tesseract_cmd = 'tesseract' 改为自己的地址
例如: tesseract_cmd = 'C:\\Program Files (x86)\\Tesseract-OCR\\tesseract.exe'

如果报下面的 BUG,请注意

Error opening data file \\Program Files (x86)\\Tesseract-OCR\\tessdata/chi_sim.traineddata Please make sure the TESSDATA_PREFIX environment variable

解决办法也比较容易,按照它的提示,表示缺失了 TESSDATA_PREFIX 这个环境变量。你只需要在系统环境变量中添加一条即可

将 TESSDATA_PREFIX=C:\\Program Files (x86)\\Tesseract-OCR 添加环境变量

重启 IDE 或者重新 CMD,然后继续运行代码,这个地方注意需要用管理员运行你的 py 脚本

步骤分为

  1. 打开图片 Image.open()
  2. pytesseract 识别图片
import pytesseract
from PIL import Image

def main():
    image = Image.open("1.jpg")

    text = pytesseract.image_to_string(image,lang="chi_sim")
    print(text)

if __name__ == '__main__':
    main()

测试英文,数字什么的基本没有问题,中文简直惨不忍睹。空白比较大的可以识别出来。唉~不好用
当然刚才那个7364 十分轻松的就识别出来了。

带干扰的验证码识别

接下来识别如下的验证码,我们首先依旧先尝试一下。运行代码发现没有任何显示。接下来需要对这个图片进行处理

基本原理都是完全一样的

  1. 彩色转灰度
  2. 灰度转二值
  3. 二值图像识别

彩色转灰度

im = im.convert('L')

灰度转二值,解决方案比较成套路,采用阈值分割法,threshold 为分割点

def initTable(threshold=140):
    table = []
    for i in range(256):
        if i < threshold:
            table.append(0)
        else:
            table.append(1)
    return table

调用

binaryImage = im.point(initTable(), '1')
binaryImage.show()

调整之后

今天你要学习的验证码采用通过第三方 AI 平台开放的 OCR 接口实现,OCR 文字识别技术目前已经比较成熟了,而且第三方比较多,今天采用的是百度的。

借用第三方平台解决验证码

官方网址:http://ai.baidu.com/
接下来申请

接下来创建一个简单应用之后,就可以使用了,我们找到

阅读文字识别相关文档

你需要具备基本的阅读第三方文档的能力,打开我们需要的文档

https://cloud.baidu.com/doc/OCR/OCR-API.html

这个页面基本上已经把我们需要做的所有内容都已经标识清楚了

编写获取 accesstoken 的代码

在目前主流的 API 开发模式下,都是需要你进行 accesstoken 的获取的

代码如下 ,重点需要参照文档进行传参的设计

    def get_accesstoken(self):
        res = requests.post(self.url.format(self.key,self.secret),headers=self.header)
        content = res.text
        if (content):
            return json.loads(content)["access_token"]

得到 accesstoken 之后,你可以继续下面的操作

import requests
import json

import base64

import urllib.request, urllib.parse

class GetCode(object):

    def __init__(self):
        self.url = "https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=&client_secret="
        self.api = "https://aip.baidubce.com/rest/2.0/ocr/v1/general_basic?access_token="
        self.header = 
            "Content-Type":'application/json; charset=UTF-8'
        

        self.key = "你的KEY"
        self.secret = "你的SECRET"

验证码识别阶段

普通没有干扰的验证码,我们直接识别即可,但是有的验证码还是有干扰的,在识别之前,需要对它进行基本的处理,我们采用和上篇文章类似的办法进行,对它进行灰度处理和二值化操作。部分代码我直接硬编码了,不过最终识别的效果并没有比想象的优化多少。

 def init_table(self,threshold=155):
        table = []
        for i in range(256):
            if i < threshold:
                table.append(0)
            else:
                table.append(1)
        return table



    def opt_image(self):
        im = Image.open("66.png")

        im = im.convert('L')
        im = im.point(self.init_table(), '1')
        im.save('66_s.png')
        return "66_s.png"

调用验证码接口

调用百度的验证码接口,不使用百度给的模块直接编写。按照它对应的文档,书写即可。
在这个地方尤其注意官方文档提示

    def get_file_content(self,file_path):
        with open(file_path, 'rb') as fp:
            base64_data = base64.b64encode(fp.read())
            s = base64_data.decode()

            data = 
            data['image'] = s

            decoded_data = urllib.parse.urlencode(data)
            return decoded_data


    def show_code(self):
        image = self.get_file_content(self.opt_image())
        headers = 
            "Content-Type":	"application/x-www-form-urlencoded"
        
        res = requests.post(self.api.format(self.get_accesstoken()),headers=headers,data=image)
        print(res.text)

通过百度模块调用验证码识别

安装百度 AI

 pip install baidu-aip

安装之后,就可以使用啦

  1. 声明一些常量,你在百度创建应用之后就可以获取
  2. 初始化文字识别类
  3. 调用对应的方法

参考代码

from aip import AipOcr


# 定义常量
APP_ID = '15736693'
API_KEY = '你的KEY'
SECRET_KEY = '你的SECRET'

# 初始化文字识别
aipOcr=AipOcr(APP_ID, API_KEY, SECRET_KEY)

# 读取图片
filePath = "1.jpg"

def get_file_content(filePath):
    with open(filePath, 'rb') as fp:
        return fp.read()

# 定义参数变量
options = 
    'detect_direction': 'true',
    'language_type': 'CHN_ENG',


# 网络图片文字文字识别接口
result = aipOcr.webImage(get_file_content(filePath),options)


print(result)

扩展部分

这种通过第三方 OCR 技术识别验证码的方式,本质上和上篇文章的原理是一致的
在实测过程中发现,没有太多干扰线,搜狗腾讯有道 基本表现一致

对于这种方式,学会即可~,道理都是一致的,当然你可以用 Python 实现一个图片转文字的小应用是没有任何问题的

以上是关于Python技能树共建验证码实操2案例的主要内容,如果未能解决你的问题,请参考以下文章

Python技能树共建Python爬虫模拟登录

Python技能树共建python selectolax 模块

Python技能树共建python autoscraper 模块

Python技能树共建pyspider框架的使用

技能树共建Python requests 模块

Python技能树共建python urllib 模块