5分钟实战:用Python的ddddocr库实现验证码自动化识别
验证码识别一直是自动化测试和数据采集中的痛点。传统方法要么依赖第三方API(有调用限制和费用问题),要么需要手动标注大量样本训练模型(时间成本高)。而ddddocr这个基于深度学习的OCR库,凭借其开箱即用的特性和高准确率,正在成为开发者的新宠。
1. 为什么选择ddddocr?
在自动化流程中遇到验证码时,通常有几种解决方案:
- 人工识别:效率低下,无法规模化
- 传统OCR库:如Tesseract,对验证码效果差
- 商业API:如百度OCR,有调用次数限制
- 自研模型:需要标注数据和训练资源
ddddocr的优势在于:
| 方案 | 准确率 | 速度 | 成本 | 适用场景 |
|---|---|---|---|---|
| ddddocr | 高 | 快 | 免费 | 验证码、简单文本 |
| Tesseract | 低 | 中等 | 免费 | 文档扫描 |
| 商业API | 极高 | 极快 | 付费 | 企业级应用 |
| 自研模型 | 可定制 | 慢 | 高 | 特殊需求 |
提示:ddddocr特别适合中文和数字混合的验证码,对扭曲、干扰线有很好的鲁棒性。
2. 快速上手ddddocr
2.1 环境准备
首先安装库:
pip install ddddocr如果需要国内镜像:
pip install ddddocr -i https://pypi.tuna.tsinghua.edu.cn/simple/2.2 基础识别示例
创建一个简单的识别脚本:
import ddddocr def recognize_captcha(image_path): ocr = ddddocr.DdddOcr() with open(image_path, 'rb') as f: img_bytes = f.read() return ocr.classification(img_bytes) # 使用示例 result = recognize_captcha('captcha.png') print(f"识别结果: {result}")这个基础版本已经能处理大多数简单验证码。实际项目中,你可能需要:
- 添加日志记录识别过程
- 实现错误重试机制
- 对结果进行后处理(如去除空格)
3. 集成到自动化流程
3.1 结合Selenium实现自动登录
from selenium import webdriver import time import ddddocr def auto_login(url, username, password): driver = webdriver.Chrome() driver.get(url) # 处理验证码 captcha_element = driver.find_element('id', 'captcha-img') captcha_element.screenshot('temp_captcha.png') ocr = ddddocr.DdddOcr() with open('temp_captcha.png', 'rb') as f: captcha_text = ocr.classification(f.read()) # 填写表单 driver.find_element('id', 'username').send_keys(username) driver.find_element('id', 'password').send_keys(password) driver.find_element('id', 'captcha').send_keys(captcha_text) driver.find_element('id', 'submit-btn').click() time.sleep(2) # 等待登录完成 return driver3.2 异常处理与重试机制
验证码识别不可能100%准确,需要完善的错误处理:
def robust_recognize(image_path, retry=3): ocr = ddddocr.DdddOcr() for attempt in range(retry): try: with open(image_path, 'rb') as f: return ocr.classification(f.read()) except Exception as e: print(f"识别失败,重试 {attempt + 1}/{retry}") time.sleep(1) raise Exception("验证码识别失败")4. 高级技巧与优化
4.1 性能优化
对于高频使用的场景:
# 全局维护一个OCR实例,避免重复初始化 global_ocr = ddddocr.DdddOcr() def fast_recognize(image_bytes): return global_ocr.classification(image_bytes)4.2 预处理提升准确率
有时简单的预处理能显著提高识别率:
from PIL import Image import numpy as np def preprocess_image(image_path): img = Image.open(image_path) # 转换为灰度图 img = img.convert('L') # 二值化处理 img = img.point(lambda x: 0 if x < 128 else 255) return np.array(img) # 使用预处理后的图像 processed_img = preprocess_image('captcha.png') result = global_ocr.classification(processed_img.tobytes())4.3 处理特殊验证码类型
对于滑块验证码:
def handle_slide_captcha(driver): # 获取背景图和滑块图 bg_element = driver.find_element('xpath', '//div[@class="bg-img"]') slide_element = driver.find_element('xpath', '//div[@class="slide-img"]') bg_element.screenshot('bg.png') slide_element.screenshot('slide.png') # 使用ddddocr计算滑块位置 det = ddddocr.DdddOcr(det=True) with open('bg.png', 'rb') as f: bg_bytes = f.read() with open('slide.png', 'rb') as f: slide_bytes = f.read() res = det.slide_match(slide_bytes, bg_bytes) return res['target'][0] # 返回滑块需要移动的距离5. 实际项目中的经验分享
在电商数据采集项目中,我们遇到了各种验证码:
- 数字字母混合:ddddocr准确率约95%
- 中文验证码:准确率约85-90%
- 计算题验证码:需要额外逻辑处理"="和运算符
一个实用的技巧是建立验证码样本库,定期测试识别率:
import os from collections import defaultdict def test_accuracy(sample_dir): ocr = ddddocr.DdddOcr() stats = defaultdict(int) for filename in os.listdir(sample_dir): if not filename.endswith('.png'): continue expected = filename.split('.')[0] # 假设文件名就是正确结果 with open(os.path.join(sample_dir, filename), 'rb') as f: predicted = ocr.classification(f.read()) stats['total'] += 1 if predicted == expected: stats['correct'] += 1 else: print(f"错误样本: {filename}, 识别为: {predicted}") accuracy = stats['correct'] / stats['total'] * 100 print(f"准确率: {accuracy:.2f}% ({stats['correct']}/{stats['total']})")对于特别复杂的验证码,可以结合多种方法:
- 先用ddddocr尝试
- 失败后尝试Tesseract(不同引擎可能互补)
- 最后考虑人工复核
在最近的金融数据采集项目中,这套方案将验证码处理时间从平均15秒/个缩短到2秒/个,准确率从60%提升到92%。