脚本如何识别图形验证码

wen 实用脚本 19

本文目录导读:

脚本如何识别图形验证码

  1. 核心思路
  2. 环境准备
  3. 方法一:传统图像处理 + Tesseract OCR(最简方案)
  4. 方法二:使用深度学习框架(PaddleOCR/DBNet + SVTR)
  5. 方法三:训练自定义深度学习模型(高阶方案)
  6. 方法四:第三方打码平台(工程化最优方案)
  7. 总结:如何选择?
  8. 重要提醒:法律与道德

识别图形验证码(CAPTCHA)是一个典型的计算机视觉与模式识别问题,脚本实现这一功能通常依赖于OCR(光学字符识别)图像预处理以及近年来主流的深度学习

根据验证码的复杂程度(从简单的数字字母到复杂的扭曲、粘连、背景干扰),识别的技术路线也不同,以下是几种主流的实现方式和脚本示例。

核心思路

  1. 获取图像:下载或截图验证码图片。
  2. 图像预处理:去除背景噪点、灰度化、二值化、分割字符。
  3. 识别:将处理后的图像转换为文本。
    • 传统方法:使用 OCR 库(如 Tesserocr)。
    • 机器学习方法:使用深度学习模型(如 CNN + RNN + CTC)。
  4. 返回结果:输出识别出的文本字符串。

环境准备

建议使用 Python 环境,需要安装以下库:

# 基础库
pip install requests pillow opencv-python
# OCR 方法(适用于简单验证码)
pip install pytesseract
# 还需要安装 Tesseract-OCR 引擎:https://github.com/tesseract-ocr/tesseract
# 深度学习端到端方法(适用于复杂验证码)
pip install torch torchvision torchaudio
pip install paddleocr  # 或使用 PaddleOCR

传统图像处理 + Tesseract OCR(最简方案)

适用场景:背景干净、字符无严重扭曲、未粘连的简单字母数字验证码。

import cv2
import requests
import pytesseract
from PIL import Image
import numpy as np
def clean_image(image_path):
    """图像预处理:去噪、二值化"""
    # 读取图片
    img = cv2.imread(image_path)
    # 转为灰度图
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    # 高斯滤波去噪
    blurred = cv2.GaussianBlur(gray, (3, 3), 0)
    # 二值化(阈值分割)
    _, binary = cv2.threshold(blurred, 150, 255, cv2.THRESH_BINARY_INV)
    return binary
def recognize_by_ocr(image_path):
    """使用 Tesseract 识别"""
    processed_img = clean_image(image_path)
    # 配置参数:PSM 8 表示单字符识别,--oem 1 表示 LSTM 引擎
    config = r'--oem 3 --psm 7 -c tessedit_char_whitelist=ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
    text = pytesseract.image_to_string(processed_img, config=config, lang='eng')
    # 去除空格和换行
    return text.strip().replace('\n', '').replace(' ', '')
# 使用示例
result = recognize_by_ocr('captcha.png')
print(f"识别结果: {result}")

优点:代码简单,无需训练模型。 缺点:对扭曲、粘连、噪点多的验证码准确率很低(< 30%)。


使用深度学习框架(PaddleOCR/DBNet + SVTR)

适用场景:大多数常见的复杂验证码,如:字符旋转、粘连、加噪、线条干扰。

PaddleOCR 是百度开源的 OCR 工具包,内置了专门针对验证码的识别模型。

from paddleocr import PaddleOCR
import cv2
# 初始化 OCR
# 使用检测+识别模型,加载预训练参数
ocr = PaddleOCR(
    use_angle_cls=True,  # 启用文本方向分类
    lang='en',           # 英文模型
    det_db_thresh=0.3,   # 检测阈值(调低可应对较淡的字符)
    rec_char_dict_path=None,  # 使用默认字典(0-9 A-Z)
    use_gpu=False        # 如果显卡不够,建议 False
)
def recognize_by_paddle(image_path):
    """使用 PaddleOCR 识别验证码"""
    result = ocr.ocr(image_path, cls=True)
    code = ''
    if result[0] is not None:
        # 提取识别文本
        for line in result[0]:
            code += line[1][0]  # line[1][0] 是识别字符串
    return code
# 使用示例
result = recognize_by_paddle('complex_captcha.png')
print(f"识别结果: {result}")

优点:开箱即用,准确率较高(约 70%-90%),适应性强。 缺点:首次运行需下载模型(约 100MB),推理速度比 Tesseract 慢(约 0.5-1秒/张)。


训练自定义深度学习模型(高阶方案)

适用场景:特定网站的高强度验证码(如极验滑动验证码除外),批量自动化需要高准确率(>95%)。

常见架构CNN(特征提取) + RNN/Transformer(序列建模) + CTC Loss(无需对齐)

# 伪代码展示流程,此处省略具体网络实现
import torch
import torch.nn as nn
import torchvision.transforms as transforms
from PIL import Image
class CaptchaModel(nn.Module):
    """简单的 CNN+BiLSTM+CTC 模型"""
    # ... (具体的层定义)
def predict_captcha(model, image_path, char_dict):
    """
    推理步骤:
    1. 加载图片,缩放到固定尺寸 (e.g., 100x40)
    2. 转为 Tensor -> 模型前向传播 -> 输出概率矩阵
    3. 使用贪心解码或 Beam Search 获得字符索引序列
    4. 将索引映射回字符
    """
    # 模型加载 & 预处理
    image = Image.open(image_path).convert('L')
    transform = transforms.Compose([
        transforms.Resize((40, 100)),  # (h, w)
        transforms.ToTensor(),
        transforms.Normalize([0.5], [0.5])
    ])
    x = transform(image).unsqueeze(0)  # batch dim
    with torch.no_grad():
        logits = model(x)  # [seq_len, batch, num_classes]
        # 取 argmax 得到预测索引序列
        pred_indices = logits.argmax(dim=-1).squeeze()
        # 去重 (CTC 解码) 并映射为字符
        code = ''.join([char_dict[i] for i in pred_indices if i != 0])  # 0 为 blank
    return code

数据准备:你需要收集大量(至少几千张)该网站的验证码并人工标注。 训练耗时:GPU 训练需 2-10 小时。


第三方打码平台(工程化最优方案)

适用场景:生产环境,需要极高成功率(>99%),但不想投入研发训练模型。

通过 HTTP 接口将验证码图片发给人工打码平台(如 2Captcha、打码兔、AI开放平台的 Captcha 识别服务)。

import requests
import base64
def recognize_by_api(image_path, api_key='YOUR_KEY'):
    """调用第三方打码平台"""
    with open(image_path, 'rb') as f:
        img_base64 = base64.b64encode(f.read()).decode()
    # 以超级鹰为例
    url = 'http://upload.chaojiying.com/upload/Processing'
    data = {
        'user': 'your_username',
        'pass': 'your_password',
        'softid': 'your_softid',
        'codetype': 1902  # 常见验证码类型代码
    }
    files = {'userfile': ('captcha.jpg', img_base64, 'image/jpeg')}
    resp = requests.post(url, data=data, files=files)
    return resp.json().get('pic_str')
# 使用示例
result = recognize_by_api('hard_captcha.png')
print(f"打码结果: {result}")

优点:识别率极高,无需维护模型,稳定性好。 缺点:有费用(每次约 0.01~0.05元),且有延迟(人工打码通常 1~5秒)。


如何选择?

验证码类型 推荐方案 预期准确率 成本
简单数字/字母,无扭曲 Tesseract + 预处理 60%-80% 免费
中等复杂(线条干扰、轻微扭曲) PaddleOCR (SVTR) 80%-95% 免费
高度扭曲、粘连、有字符阴影 PaddleOCR + 针对性后处理 70%-90% 免费
特定网站、批量、要求极高成功率 第三方打码平台 99%+ 按次收费
长期、大规模且预算有限 自训练 CNN+CTC 模型 95%+ 免费+算力

重要提醒:法律与道德

  • 遵守 Robots 协议:识别验证码通常用于自动化爬虫,请确保你有权访问目标网站的数据。
  • 不用于攻击:不要使用验证码识别技术去攻击银行、政府、邮箱等安全系统的验证码,这可能构成非法获取计算机信息系统数据罪
  • 不用于滥用:不要利用此技术进行刷票、抢票、黄牛等影响正常商业秩序的行为。

抱歉,评论功能暂时关闭!