本文目录导读:

- ⚠️ 重要法律与道德提醒
- 方案一:OCR识别简单文字验证码(Tesseract)
- 方案二:机器学习识别(CNN+验证码生成)
- 方案三:使用第三方API服务(推荐简易方案)
- 方案四:对抗复杂验证码(reCAPTCHA等)
- 性能优化建议
- 最佳实践流程
- 示例完整实现:中文验证码识别
- 资源推荐
编写验证码自动识别脚本涉及多个技术领域,且需要根据验证码的复杂程度选择不同方案,以下是一个系统性的技术指南,包含从简单到进阶的实现方法。
⚠️ 重要法律与道德提醒
- 仅限学习与研究:仅用于教育、自动化测试或合法爬虫场景
- 禁止破解网站:未经授权绕过验证码可能违反《计算机信息系统安全保护条例》
- 遵守robots.txt:尊重网站的爬虫规则
- 不影响服务质量:请勿高频请求导致服务器压力
OCR识别简单文字验证码(Tesseract)
适用场景
- 清晰无干扰的纯数字/字母
- 背景简单无扭曲
实现步骤
环境准备
pip install pillow pytesseract # Ubuntu安装Tesseract引擎 sudo apt install tesseract-ocr # macOS brew install tesseract # Windows下载安装包:https://github.com/UB-Mannheim/tesseract/wiki
基础脚本
from PIL import Image
import pytesseract
import requests
from io import BytesIO
def download_captcha(url):
response = requests.get(url)
return Image.open(BytesIO(response.content))
def preprocess_image(image):
# 转为灰度
gray = image.convert('L')
# 二值化(阈值调整)
threshold = 128
binary = gray.point(lambda p: 255 if p > threshold else 0)
# 去除噪点(可选)
binary = binary.filter(ImageFilter.MedianFilter(size=3))
return binary
def recognize_captcha(image_path_or_url):
if image_path_or_url.startswith('http'):
img = download_captcha(image_path_or_url)
else:
img = Image.open(image_path_or_url)
processed = preprocess_image(img)
# 配置Tesseract参数
custom_config = r'--oem 3 --psm 8 -c tessedit_char_whitelist=0123456789'
text = pytesseract.image_to_string(processed, config=custom_config)
return text.strip()
# 使用示例
result = recognize_captcha('captcha.jpg')
print(f"识别结果: {result}")
常用预处理技巧
- 调整对比度:
ImageEnhance.Contrast(img).enhance(2) - 去噪:
img.filter(ImageFilter.MedianFilter(size=3)) - 形态学操作:OpenCV的
cv2.erode/cv2.dilate
机器学习识别(CNN+验证码生成)
适用场景
- 中等复杂度验证码
- 有颜色干扰、轻微扭曲
- 需要高准确率
训练数据准备
from captcha.image import ImageCaptcha
import random
def generate_captcha_data(count=10000):
captcha = ImageCaptcha(width=160, height=60)
characters = '0123456789abcdefghijklmnopqrstuvwxyz'
for i in range(count):
text = ''.join(random.choices(characters, k=4))
captcha.write(text, f'data/{text}_{i}.png')
简单CNN模型(Keras)
import tensorflow as tf
from tensorflow.keras import layers, models
def build_model():
model = models.Sequential([
layers.Conv2D(32, (3,3), activation='relu', input_shape=(60,160,3)),
layers.MaxPooling2D((2,2)),
layers.Conv2D(64, (3,3), activation='relu'),
layers.MaxPooling2D((2,2)),
layers.Flatten(),
layers.Dense(128, activation='relu'),
layers.Dropout(0.25),
# 输出层:假设4位验证码,每个位置36种可能
layers.Dense(4 * 36, activation='softmax'),
layers.Reshape((4, 36))
])
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
return model
def train_model():
# 假设X_train, y_train已准备好
model = build_model()
history = model.fit(X_train, y_train, epochs=20,
validation_split=0.2, batch_size=32)
model.save('captcha_model.h5')
预测脚本
def predict_captcha(model, image_path):
img = tf.keras.preprocessing.image.load_img(
image_path, target_size=(60, 160))
img_array = tf.keras.preprocessing.image.img_to_array(img)
img_array = tf.expand_dims(img_array, 0)
predictions = model.predict(img_array)
# 解码预测结果
chars = '0123456789abcdefghijklmnopqrstuvwxyz'
result = ''
for pos in range(4):
idx = tf.argmax(predictions[0][pos]).numpy()
result += chars[idx]
return result
使用第三方API服务(推荐简易方案)
主流服务
- 2captcha:约$2/1000次,识别成功率90%+
- Anti-Captcha:支持reCAPTCHA等复杂验证码
- DeathByCaptcha:提供多种验证码类型
使用示例(2captcha)
import requests
import time
class CaptchaSolver:
def __init__(self, api_key):
self.api_key = api_key
self.base_url = 'https://2captcha.com'
def solve_normal(self, image_path):
# 上传图片
with open(image_path, 'rb') as f:
response = requests.post(
f'{self.base_url}/in.php',
files={'file': f},
data={'key': self.api_key, 'method': 'post'}
)
if response.text[:3] != 'OK|':
raise Exception('Upload failed')
captcha_id = response.text[3:]
# 等待结果
for _ in range(30): # 最多等30秒
time.sleep(2)
response = requests.get(
f'{self.base_url}/res.php',
params={'key': self.api_key, 'action': 'get', 'id': captcha_id}
)
if response.text == 'CAPCHA_NOT_READY':
continue
elif response.text[:3] == 'OK|':
return response.text[3:]
else:
break
return None
对抗复杂验证码(reCAPTCHA等)
技术挑战
- 行为分析:鼠标轨迹、点击时间
- 图像识别:选择包含xx的图片
- 音频识别(可选)
解决方案工具
-
Selenium + 2captcha:自动化浏览器操作
from selenium import webdriver from selenium.webdriver.common.by import By driver = webdriver.Chrome() driver.get('https://example.com') # 等待验证码元素出现 captcha_element = driver.find_element(By.CSS_SELECTOR, '.captcha') # 截图并发送到第三方服务 -
playwright + stealth:隐藏自动化特征
pip install playwright-stealth
-
使用浏览器扩展:某些项目模拟真实浏览器指纹
性能优化建议
| 方案 | 准确率 | 速度 | 成本 | 适用复杂度 |
|---|---|---|---|---|
| Tesseract | 30-70% | 快 | 免费 | 简单文字 |
| CNN训练 | 80-95% | 中 | 需要数据 | 中等 |
| 第三方API | 90%+ | 慢 | 复杂 | |
| 模拟行为 | 不定 | 很慢 | 人工成本 | reCAPTCHA |
最佳实践流程
-
分析验证码类型:
- 打开网站查看验证码样式
- 检查是否支持无障碍/音频验证
-
尝试简易方案:
- 先试试Tesseract OCR
- 若准确率<60%,考虑训练模型
-
平衡成本与效率:
- 小规模:训练CNN模型
- 商业规模:购买API服务
-
异常处理:
- 设置重试机制(2-3次)
- 记录识别失败的样本
- 定期更新模型训练
-
法律合规:
- 确认网站服务条款
- 限制请求频率
- 保留使用记录
示例完整实现:中文验证码识别
# 使用PaddleOCR识别中文验证码
from paddleocr import PaddleOCR
ocr = PaddleOCR(use_angle_cls=True, lang='ch')
def recognize_chinese_captcha(image_path):
result = ocr.ocr(image_path, cls=True)
if result and result[0]:
text = result[0][0][1][0]
# 过滤非中文字符
import re
text = re.findall(r'[\u4e00-\u9fa5]+', text)
return ''.join(text) if text else None
return None
资源推荐
- 验证码生成库:
captcha(Python)、svg-captcha(JS) - 在线训练平台:Google Colab(免费GPU)
- 数据集:Kaggle验证码数据集
- 论文阅读:《CAPTCHA Recognition Using Deep Learning》
最后请记住:自动识别验证码是合法与灰色地带的边缘技术,请始终以学习和技术研究为目的,避免用于任何非法或不道德的用途,建议先获取网站所有者的明确许可。