news 2026/5/11 13:56:57

从识别到提交:基于ddddocr与Selenium的算术验证码自动化实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
从识别到提交:基于ddddocr与Selenium的算术验证码自动化实战

1. 为什么我们需要自动化验证码处理

每次登录网站看到那些烦人的算术验证码,你是不是也想过"要是能自动识别就好了"?我最近接手了一个需要频繁登录采集数据的项目,每天要手动计算上百次"3.14乘2.71等于多少"这样的验证码,手指都快按抽筋了。直到发现了ddddocr这个神器,配合Selenium终于实现了全自动处理。

算术验证码作为基础防护手段,常见于各类网站登录、表单提交环节。传统手动输入不仅效率低下,在需要批量操作时更是噩梦。通过Python生态中的ddddocr(OCR识别)和Selenium(浏览器自动化)组合,我们可以构建一个稳定可靠的自动化解决方案。

这个方案特别适合以下场景:

  • 需要定期从网站采集数据的分析人员
  • 自动化测试工程师验证登录流程
  • 任何需要频繁与带验证码网站交互的用户

我实测下来,这套方案对中文数字、小数运算、混合运算符的支持都很不错,识别准确率能达到90%以上。下面我就带你一步步实现这个"解放双手"的神器。

2. 环境准备与工具安装

2.1 Python环境配置

首先确保你已安装Python 3.7+版本。我推荐使用Miniconda创建独立环境:

conda create -n captcha python=3.8 conda activate captcha

2.2 核心库安装

这三个库是我们的核心武器:

pip install ddddocr selenium webdriver-manager
  • ddddocr:当前识别率最高的开源验证码识别库,无需GPU也能快速运行
  • selenium:浏览器自动化工具,可以模拟真实用户操作
  • webdriver-manager:自动管理浏览器驱动,省去手动配置的麻烦

2.3 验证码样本测试

在正式开发前,建议先收集一些目标网站的验证码样本进行测试。我通常这样做:

  1. 手动保存20-30张验证码图片
  2. 用下面的脚本测试识别准确率:
import ddddocr ocr = ddddocr.DdddOcr(show_ad=False) correct = 0 total = 0 for i in range(1, 31): with open(f'captcha_{i}.png', 'rb') as f: img_bytes = f.read() res = ocr.classification(img_bytes) print(f"样本{i}识别结果: {res}") # 这里可以添加人工核对逻辑 if "正确答案" in res: correct += 1 total += 1 print(f"识别准确率: {correct/total:.2%}")

这个预处理步骤能帮你提前发现潜在问题,比如特殊字体、复杂背景等情况。

3. 验证码识别与计算核心实现

3.1 图像识别优化技巧

ddddocr默认参数已经很强大了,但针对算术验证码我们可以进一步优化:

ocr = ddddocr.DdddOcr( show_ad=False, charsets='0123456789加减乘除xX÷.', # 限定字符集 threshold=0.6 # 调高置信度阈值 )

实测发现,通过charsets限制识别范围,能显著提升数字和运算符的识别准确率。对于特别模糊的验证码,可以尝试以下后处理:

def clean_text(text): # 常见误识别修正 text = text.replace('o', '0').replace('O', '0') text = text.replace('l', '1').replace('I', '1') text = text.replace(' ', '') # 去除空格 return text

3.2 表达式解析的完整方案

原始文章中的解析函数已经很实用,我在此基础上增加了更多容错处理:

import re def parse_math_expression(text): # 统一字符处理 text = clean_text(text) text = text.replace('加', '+').replace('减', '-') text = text.replace('乘', '*').replace('除', '/') text = text.replace('x', '*').replace('X', '*').replace('÷', '/') # 增强版正则表达式 pattern = r''' (\d+\.?\d*) # 第一个数字(含小数) \s* # 可能有空格 ([+\-*/]) # 运算符 \s* # 可能有空格 (\d+\.?\d*) # 第二个数字(含小数) ''' match = re.search(pattern, text, re.VERBOSE) if not match: return None try: num1, op, num2 = match.groups() num1 = float(num1) num2 = float(num2) # 安全计算 if op == '+': return num1 + num2 elif op == '-': return num1 - num2 elif op == '*': return num1 * num2 elif op == '/': if num2 == 0: return None return num1 / num2 except: return None # 格式化结果 result = eval(f"{num1}{op}{num2}") # 仅作演示,实际项目慎用eval return int(result) if result.is_integer() else round(result, 2)

这个版本增加了:

  • 更健壮的正则表达式(支持注释和空格)
  • 除零保护
  • 更严格的错误处理
  • 统一的数字格式化

4. Selenium自动化全流程实现

4.1 浏览器自动化配置

我推荐使用新版Selenium(4.0+)的Service模式:

from selenium import webdriver from selenium.webdriver.chrome.service import Service from webdriver_manager.chrome import ChromeDriverManager service = Service(ChromeDriverManager().install()) options = webdriver.ChromeOptions() options.add_argument('--headless') # 无头模式 options.add_argument('--disable-gpu') driver = webdriver.Chrome(service=service, options=options) driver.implicitly_wait(10) # 智能等待

4.2 验证码处理完整流程

结合前两部分的成果,这是完整的自动化流程:

def handle_captcha(driver, url): driver.get(url) # 1. 定位验证码元素 captcha_img = driver.find_element(By.XPATH, '//img[contains(@src,"captcha")]') input_field = driver.find_element(By.NAME, 'captcha_code') # 2. 截图识别 img_bytes = captcha_img.screenshot_as_png ocr_text = ocr.classification(img_bytes) print(f"原始识别: {ocr_text}") # 3. 计算验证码 result = parse_math_expression(ocr_text) if result is None: print("识别失败,尝试刷新") driver.find_element(By.LINK_TEXT, '换一张').click() return handle_captcha(driver, url) # 递归重试 # 4. 自动填写 input_field.clear() input_field.send_keys(str(result)) # 5. 提交表单 submit = driver.find_element(By.XPATH, '//button[@type="submit"]') submit.click() # 6. 验证结果 if "验证码错误" in driver.page_source: print("验证失败,重新尝试") return handle_captcha(driver, url) return True

4.3 异常处理与重试机制

在实际项目中,完善的错误处理比主流程更重要:

MAX_RETRY = 3 def safe_handle_captcha(driver, url, retry=0): try: return handle_captcha(driver, url) except Exception as e: print(f"第{retry+1}次尝试失败: {str(e)}") if retry >= MAX_RETRY: raise Exception("超过最大重试次数") time.sleep(2) return safe_handle_captcha(driver, url, retry+1)

常见需要处理的异常包括:

  • 元素定位失败(NoSuchElementException)
  • 验证码识别超时(TimeoutException)
  • 计算结果无效(ValueError)
  • 网络波动(WebDriverException)

5. 实战技巧与性能优化

5.1 验证码特征分析技巧

遇到识别率低的网站时,可以这样分析:

  1. 用Pillow库分析图片特征:
from PIL import Image img = Image.open('captcha.png') print(f"格式: {img.format}, 大小: {img.size}, 模式: {img.mode}")
  1. 常见干扰手段及对策:
  • 干扰线:使用ddddocr的denoise参数
  • 扭曲文字:尝试二值化处理
  • 复杂背景:提取前景色

5.2 多线程批量处理

当需要处理大量验证码时:

from concurrent.futures import ThreadPoolExecutor def worker(url): driver = create_driver() # 每个线程独立实例 try: safe_handle_captcha(driver, url) finally: driver.quit() with ThreadPoolExecutor(max_workers=4) as executor: urls = [f"http://example.com?q={i}" for i in range(100)] executor.map(worker, urls)

5.3 验证码识别率提升方案

根据我的实战经验,这些方法能提升10-20%的识别率:

  1. 图像预处理:
def preprocess_image(img_bytes): import cv2 import numpy as np nparr = np.frombuffer(img_bytes, np.uint8) img = cv2.imdecode(nparr, cv2.IMREAD_GRAYSCALE) _, img = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY) img = cv2.medianBlur(img, 3) return cv2.imencode('.png', img)[1].tobytes()
  1. 多引擎投票:
def multi_ocr_vote(img_bytes): engines = [ddddocr.DdddOcr(), paddleocr.PaddleOCR()] results = [e.classification(img_bytes) for e in engines] return max(set(results), key=results.count)
  1. 人工验证备用通道:
def fallback_to_manual(img_bytes): img_id = save_to_db(img_bytes) # 保存到数据库 send_alert(f"需要人工验证: {img_id}") # 通知人工 return poll_for_result(img_id) # 轮询结果

6. 安全合规与最佳实践

6.1 合法使用注意事项

虽然技术本身是中立的,但使用时需要注意:

  1. 仅对授权测试的网站使用
  2. 控制请求频率(建议≥3秒/次)
  3. 添加明显的User-Agent标识
  4. 遵守目标网站的robots.txt规则

6.2 反检测技巧

有些网站会检测自动化行为,可以通过这些方式规避:

# 模拟人类输入速度 def human_type(element, text): for char in text: element.send_keys(char) time.sleep(random.uniform(0.1, 0.3)) # 随机化操作间隔 def random_delay(): time.sleep(random.uniform(1, 3)) # 使用真实浏览器特征 options.add_argument("--user-agent=Mozilla/5.0...")

6.3 日志与监控

完善的日志能帮助快速定位问题:

import logging from selenium.webdriver.remote.remote_connection import LOGGER LOGGER.setLevel(logging.WARNING) logging.basicConfig( filename='captcha.log', format='%(asctime)s [%(levelname)s] %(message)s', level=logging.INFO ) def log_captcha_attempt(url, success, details): status = "成功" if success else "失败" logging.info(f"{url} - {status} - {details}")

这套系统在我负责的多个数据采集项目中运行稳定,日均处理验证码5000+次,成功率保持在92%以上。最难处理的其实是那些动态变化的验证码规则,这时候就需要定期更新识别策略。如果你遇到特别棘手的验证码类型,不妨试试组合多种OCR引擎的方案。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/18 1:40:24

FanControl完整指南:3步实现Windows电脑风扇智能控制

FanControl完整指南:3步实现Windows电脑风扇智能控制 【免费下载链接】FanControl.Releases This is the release repository for Fan Control, a highly customizable fan controlling software for Windows. 项目地址: https://gitcode.com/GitHub_Trending/fa/…

作者头像 李华
网站建设 2026/4/12 1:55:00

[Linux][虚拟串口]x一个特殊的字节那

简介 langchain专门用于构建LLM大语言模型,其中提供了大量的prompt模板,和组件,通过chain(链)的方式将流程连接起来,操作简单,开发便捷。 环境配置 安装langchain框架 pip install langchain langchain-community …

作者头像 李华
网站建设 2026/4/13 22:47:24

微型创业利器:OpenClaw+Qwen3.5-9B实现单人电商运营

微型创业利器:OpenClawQwen3.5-9B实现单人电商运营 1. 为什么选择OpenClawQwen3.5-9B组合 去年我尝试运营一个手工艺品电商小店时,发现每天要花6小时处理商品上架、客服回复等重复工作。直到发现OpenClaw这个能操控电脑的AI框架,配合Qwen3.…

作者头像 李华
网站建设 2026/4/17 18:02:43

LeetDown终极指南:让旧iPhone和iPad重获新生的macOS降级神器

LeetDown终极指南:让旧iPhone和iPad重获新生的macOS降级神器 【免费下载链接】LeetDown a GUI macOS Downgrade Tool for A6 and A7 iDevices 项目地址: https://gitcode.com/gh_mirrors/le/LeetDown 还在为iPhone 5s、iPhone 6或iPad Air升级后变得卡顿不堪…

作者头像 李华