python入门教程之识别验证码

那我来讲解关于“Python入门教程之识别验证码”的攻略。

1. 前言

验证码是目前防止自动化机器人攻击的一种重要方式。而在自动化测试、爬虫等场景下,我们又需要自动识别验证码。因此,学习如何识别验证码也是学习Python的重要一环。

2. 主要技术

本教程将采用Python 3.7版本,涉及到如下技术:

  • 图像处理

  • 机器学习

  • 神经网络

3. 环境和库的准备

首先我们需要准备开发环境,这里我们建议使用Anaconda来安装Python。然后我们需要安装相关库来进行图像处理、机器学习以及神经网络的开发。这里数Python基本的库:NumPy、SciPy等。在机器学习和神经网络的开发中,我们推荐使用tensorflow。

4.验证码的识别过程

验证码的识别主要涉及以下几个步骤:

  • 数据集的准备

  • 图像预处理

  • 训练模型

  • 验证码测试

4.1 数据集的准备

为了训练模型,我们需要一个包含验证码的数据集,这里我们可以直接通过网络爬虫爬取,或者通过收集公开数据集来获取。可以通过以下方式获取训练集:

import requests
import os

def save_image(url, filename):
    with open(filename, "wb") as f:
        f.write(requests.get(url).content)

def download_captcha(count):
    for i in range(count):
        url = "http://www.example.com/captcha/{0}.png".format(str(i))
        filename = os.path.join("captcha", "{0}.png".format(str(i)))
        save_image(url, filename)

if __name__ == '__main__':
    download_captcha(10000)   #下载10000个验证码

4.2 图像预处理

预处理是为了让原始图像更适合机器学习或神经网络算法的处理,预处理中可以包括以下技术:

  • 二值化

  • 去噪

  • 分割

import glob
import cv2

def preprocess_image(image_path):
    gray = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)
    gray = cv2.resize(gray, (200, 60))
    _, binary = cv2.threshold(gray, 180, 255, cv2.THRESH_BINARY)
    kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
    binary = cv2.morphologyEx(binary, cv2.MORPH_CLOSE, kernel)
    binary = cv2.medianBlur(binary, 3)
    return binary

if __name__ == '__main__':
    paths = glob.glob(os.path.join("captcha", "*.png"))
    for image_path in paths:
        binary = preprocess_image(image_path)
        cv2.imwrite(os.path.join("captcha_preprocessed", os.path.basename(image_path)), binary)

4.3 训练模型

这里我们使用tensorflow来训练一个卷积神经网络模型(CNN),用于识别验证码:

import tensorflow as tf
import os

def train_cnn():
    char_set = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
    char_set_len = len(char_set)
    input_height, input_width = 60, 200
    input_channel = 1
    batch_size = 100
    epochs = 100
    output_node_names = "output"
    model_dir = os.path.join("captcha_model", "model.ckpt")

    X = tf.placeholder(tf.float32, [None, input_height, input_width, input_channel])
    Y = tf.placeholder(tf.float32, [None, char_set_len * 4])

    logits = cnn(X, char_set_len)
    loss = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits=logits, labels=Y))
    optimizer = tf.train.AdamOptimizer(learning_rate=0.001).minimize(loss)

    predict = tf.reshape(logits, [-1, 4, char_set_len])
    max_pred = tf.argmax(predict, axis=2)
    decoded_pred = tf.reduce_join(tf.transpose(tf.argmax(predict, axis=2), perm=[1, 0]), 1)

    saver = tf.train.Saver()
    with tf.Session() as session:
        session.run(tf.global_variables_initializer())
        for epoch in range(epochs):
            avg_loss = 0.
            total_batch = int(len(X_train) / batch_size)
            for i in range(total_batch):
                batch_X = X_train[i*batch_size:(i+1)*batch_size]
                batch_Y = Y_train[i*batch_size:(i+1)*batch_size]
                _, c = session.run([optimizer, loss], feed_dict={X: batch_X, Y: batch_Y})
                avg_loss += c / total_batch
            print("Epoch:", '%d' % (epoch + 1), "cost=", "{:.9f}".format(avg_loss))

        saver.save(session, model_dir)
        print("Model saved!")

if __name__ == '__main__':
    train_cnn()

4.4 验证码测试

训练好模型后,我们可以用训练好的模型去测试验证码的识别效果了。验证码测试主要步骤如下:

  • 从验证码中分割出4个字符

  • 对每个字符进行预处理

  • 利用模型进行识别

import glob
import cv2
import os
import numpy as np
import tensorflow as tf

def test_captcha():
    char_set = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
    char_set_len = len(char_set)
    input_height, input_width = 60, 200
    input_channel = 1
    model_dir = os.path.join("captcha_model", "model.ckpt")

    X = tf.placeholder(tf.float32, [None, input_height, input_width, input_channel])
    logits = cnn(X, char_set_len)
    predict = tf.reshape(logits, [-1, 4, char_set_len])
    max_pred = tf.argmax(predict, axis=2)
    decoded_pred = tf.reduce_join(tf.transpose(tf.argmax(predict, axis=2), perm=[1, 0]), 1)

    saver = tf.train.Saver()
    with tf.Session() as session:
        saver.restore(session, model_dir)
        paths = glob.glob(os.path.join("captcha", "*.png"))
        for image_path in paths:
            image = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)
            _, binary = cv2.threshold(image, 100, 255, cv2.THRESH_BINARY)
            contours, hierarchy = cv2.findContours(binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
            c_len = len(contours)
            if c_len != 4:
                print("can't recognize captcha.")
                continue
            part_digits = []
            for j in range(c_len):
                x, y, w, h = cv2.boundingRect(contours[j])
                part_image = binary[y:y+h, x:x+w]
                part_image = cv2.resize(part_image, (input_width, input_height))
                part_digits.append(part_image)
            part_digits_array = np.array(part_digits) / 255.0
            predict_res = session.run(decoded_pred, feed_dict={X: part_digits_array[:, :, :, np.newaxis]})
            print(predict_res)

if __name__ == '__main__':
    test_captcha()

以上就是关于“Python入门教程之识别验证码”的攻略了。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:python入门教程之识别验证码 - Python技术站

(0)
上一篇 2023年6月3日
下一篇 2023年6月3日

相关文章

  • 如何在Python中创建频率表

    在Python中创建频率表可以通过使用字典(dictionary)来实现,以下是具体步骤: 读取数据并将其存储在列表中。假设我们要分析的数据包含在一个名为data的列表中。 创建一个新的字典用于存储频率数据。我们可以使用collections模块中的defaultdict函数来创建一个在访问不存在键时默认返回0的字典。 from collections im…

    python-answer 2023年3月25日
    00
  • 一篇文章带你了解python标准库–math模块

    一篇文章带你了解Python标准库–math模块 简介 math 模块是 Python 标准库中的一个数学模块,提供了许多数学函数,如三角函数、幂函数、对数函数等等,很多时候我们在处理数据或进行科学计算时会用到这些数学函数。本文将以实例的方式,介绍 math 模块中一些比较常用的函数。 函数 acos(x) 返回 x 的反余弦值,其中参数 x 的取值范围在…

    python 2023年5月14日
    00
  • Python – 检查列表中的重复项并将重复项添加在一起以使用总和值更新列表

    【问题标题】:Python – Checking duplicates in a list and adding duplicates together to update the list with the summed valuePython – 检查列表中的重复项并将重复项添加在一起以使用总和值更新列表 【发布时间】:2023-04-07 00:10:…

    Python开发 2023年4月7日
    00
  • python 3的kivy中是否有任何将textinput(小部件)的文本访问到另一个类的方法?

    【问题标题】:Is there any to access textinput (widget)’s text into another class in kivy of python 3?python 3的kivy中是否有任何将textinput(小部件)的文本访问到另一个类的方法? 【发布时间】:2023-04-05 16:53:02 【问题描述】: 我…

    Python开发 2023年4月5日
    00
  • 如何在Python中更新Microsoft SQL Server数据库中的数据?

    以下是如何在Python中更新Microsoft SQL Server数据库中的数据的完整使用攻略,包括连接Microsoft SQL Server数据库、执行更新语句等步骤。同时,提供了两个示例以便更好理解如何在Python中更新Microsoft SQL Server数据库中的数据。 步骤1:连接Microsoft SQL Server数据库 在Pyth…

    python 2023年5月12日
    00
  • 在Python中评估Hermite_e数列在点x上广播的系数列

    我们来详细讲解一下如何在Python中评估Hermite_e数列在点x上广播的系数列。 步骤一:导入Numpy和Scipy库 在Python中实现Hermite_e数列,我们需要使用Numpy和Scipy库。因此,我们在代码文件的开头插入以下代码: import numpy as np from scipy.special import hermite_e …

    python-answer 2023年3月25日
    00
  • Python根据当前日期取去年同星期日期

    要取得当前日期的上一年同星期日期,可以利用Python的datetime模块和timedelta类来实现。 首先,我们需要获取当前日期,可以使用datetime模块中的now()函数,然后再使用timedelta类的days属性来表示时间偏移量。示例代码如下: import datetime # 获取当前日期 now_date = datetime.date…

    python 2023年6月2日
    00
  • 如何用python处理excel表格

    下面是详细讲解“如何用Python处理Excel表格”的完整实例教程。 1. 准备工作 在Python中处理Excel表格需要安装openpyxl库,使用pip命令安装: pip install openpyxl 2. 读取Excel表格数据 使用openpyxl库可以很方便地读取Excel表格数据。假设我们有一个名为test.xlsx的Excel文件,文件…

    python 2023年5月13日
    00
合作推广
合作推广
分享本页
返回顶部