Python 爬虫验证码识别教程

1. 验证码技术概述

随着网络安全意识的提升,各类网站采用了越来越复杂的反爬虫措施,其中验证码是最常见的防护手段之一。验证码技术经历了以下演进:

  1. 传统图形验证码:数字/字母组合
  2. 复杂图形验证码:加入干扰线、扭曲变形
  3. 中文验证码:使用汉字字符
  4. 行为验证码:如 12306 的点选验证
  5. 智能验证码:滑动拼图、文字点选等交互式验证

2. 图形验证码识别技术

2.1 OCR 技术简介

OCR(Optical Character Recognition,光学字符识别)是一种将图像中的文字转换为可编辑文本的技术。现代 OCR 技术已发展到:

  • 传统 OCR:Tesseract 等开源引擎
  • 深度学习 OCR:CRNN、Transformer 等模型
  • 商业 OCR API:百度 OCR、腾讯 OCR 等

2.2 环境准备(2024 年推荐)

# 基础库
pip install selenium pillow numpy opencv-python

# OCR 引擎选择(2024年推荐)
pip install pytesseract  # Tesseract 的 Python 封装
# 或者
pip install paddleocr  # 百度飞桨OCR

# 深度学习相关
pip install torch torchvision

注意:使用 Tesseract 需要先安装引擎本体,各系统安装方式:

  • Windows:choco install tesseract
  • Mac:brew install tesseract
  • Linux:sudo apt install tesseract-ocr

3. 验证码识别实战

3.1 简单验证码识别

import pytesseract
from PIL import Image

# 直接识别
def simple_ocr(image_path):
    image = Image.open(image_path)
    text = pytesseract.image_to_string(image)
    return text.strip()

print(simple_ocr('captcha.png'))

3.2 验证码预处理技术(2024 更新)

现代验证码识别通常需要以下预处理步骤:

import cv2
import numpy as np

def preprocess_image(image_path):
    # 读取图像
    img = cv2.imread(image_path)
    
    # 灰度化
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    
    # 二值化(2024年推荐自适应阈值)
    thresh = cv2.adaptiveThreshold(
        gray, 255, 
        cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
        cv2.THRESH_BINARY_INV, 11, 2
    )
    
    # 去噪(中值滤波)
    denoised = cv2.medianBlur(thresh, 3)
    
    # 形态学操作(可选)
    kernel = np.ones((2,2), np.uint8)
    processed = cv2.morphologyEx(denoised, cv2.MORPH_CLOSE, kernel)
    
    return processed

# 使用处理后的图像识别
processed_img = preprocess_image('captcha2.png')
text = pytesseract.image_to_string(processed_img)
print(text)

3.3 深度学习OCR方案(2024推荐)

from paddleocr import PaddleOCR

# 初始化PaddleOCR(首次使用会自动下载模型)
ocr = PaddleOCR(use_angle_cls=True, lang="en")

def paddle_ocr(image_path):
    result = ocr.ocr(image_path, cls=True)
    return result[0][0][1][0] if result else ""

print(paddle_ocr('captcha.png'))

4. 自动化登录实战(2024 Selenium 4示例)

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time

def auto_login():
    # 初始化浏览器(2024推荐使用Service对象)
    service = webdriver.ChromeService()
    driver = webdriver.Chrome(service=service)
    
    try:
        driver.get("https://captcha7.scrape.center/")
        
        # 输入用户名密码
        driver.find_element(By.NAME, "username").send_keys("admin")
        driver.find_element(By.NAME, "password").send_keys("admin")
        
        # 获取验证码图片
        captcha = driver.find_element(By.CSS_SELECTOR, ".captcha img")
        captcha.screenshot("current_captcha.png")
        
        # 识别验证码
        code = paddle_ocr("current_captcha.png")
        
        # 输入验证码
        driver.find_element(By.NAME, "captcha").send_keys(code)
        
        # 提交登录
        driver.find_element(By.CSS_SELECTOR, "button[type='submit']").click()
        
        # 等待登录成功
        WebDriverWait(driver, 10).until(
            EC.text_to_be_present_in_element(
                (By.TAG_NAME, "h2"), "登录成功"
            )
        )
        print("登录成功!")
        
    finally:
        driver.quit()

auto_login()

5. 验证码识别进阶方案(2024)

5.1 商业OCR API

import requests

def baidu_ocr(image_path):
    # 需要先申请百度OCR API(https://cloud.baidu.com/product/ocr)
    api_key = "YOUR_API_KEY"
    secret_key = "YOUR_SECRET_KEY"
    
    # 获取access token
    auth_url = f"https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id={api_key}&client_secret={secret_key}"
    auth_resp = requests.get(auth_url).json()
    access_token = auth_resp["access_token"]
    
    # 调用OCR接口
    ocr_url = f"https://aip.baidubce.com/rest/2.0/ocr/v1/general_basic?access_token={access_token}"
    with open(image_path, 'rb') as f:
        img = f.read()
    resp = requests.post(ocr_url, data={"image": img})
    return resp.json()["words_result"][0]["words"]

5.2 深度学习自定义模型

对于特别复杂的验证码,可以训练专用模型:

import torch
from torchvision import transforms
from PIL import Image

# 假设已训练好模型
model = torch.load('captcha_model.pth')
model.eval()

def predict_captcha(image_path):
    # 图像预处理
    transform = transforms.Compose([
        transforms.Grayscale(),
        transforms.Resize((60, 160)),
        transforms.ToTensor(),
    ])
    image = transform(Image.open(image_path)).unsqueeze(0)
    
    # 预测
    with torch.no_grad():
        output = model(image)
    return decode_output(output)  # 需要实现解码函数

6. 反反爬策略(2024更新)

  1. 请求频率控制:添加随机延迟

    import random
    time.sleep(random.uniform(1, 3))
  2. IP轮换:使用代理池

    options = webdriver.ChromeOptions()
    options.add_argument('--proxy-server=http://proxy_ip:port')
  3. 浏览器指纹伪装

    options.add_argument("user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) ...")

7. 总结与展望

2024年验证码识别技术趋势:

  1. 多模态识别:结合图像、文本、行为等多维度信息
  2. 小样本学习:解决标注数据不足的问题
  3. 对抗生成:使用GAN生成训练数据
  4. 端到端方案:从输入到输出的整体优化

参考资料