当前位置:首页 > Python > 正文

Python处理12306验证码完全教程 - 自动化破解技术详解

Python处理12306验证码完全教程

使用Selenium和OpenCV破解滑动与点选验证码的完整指南

12306验证码破解技术概述

12306网站使用复杂的验证码系统来防止自动化程序,主要包括两种类型:滑动验证码点选验证码。本教程将教你如何使用Python处理这两种验证码。

滑动验证码

需要将滑块拖动到缺口位置,难点在于识别缺口位置和模拟人类拖动行为。

点选验证码

需要按顺序点击图片中的文字或物体,难点在于文字识别和位置定位。

重要提示:本教程仅用于学习目的,请勿用于非法抢票或攻击12306系统。

环境准备

在开始之前,确保安装以下Python库:

  • Selenium - 浏览器自动化工具
  • OpenCV - 图像处理库
  • Pillow - 图像处理
  • NumPy - 数值计算
  • Requests - HTTP请求库

使用以下命令安装:

pip install selenium opencv-python pillow numpy requests

处理滑动验证码

滑动验证码破解分为四个步骤:获取图片、识别缺口、计算距离、模拟拖动。

步骤1:获取验证码图片

from selenium import webdriver
from selenium.webdriver.common.by import By
import time
import requests
from PIL import Image

driver = webdriver.Chrome()
driver.get('https://kyfw.12306.cn/otn/resources/login.html')

# 切换到账号登录
driver.find_element(By.CLASS_NAME, 'login-hd-account').click()
time.sleep(1)

# 点击触发验证码
driver.find_element(By.ID, 'J-userName').send_keys('your_username')
driver.find_element(By.ID, 'J-password').send_keys('your_password')
driver.find_element(By.ID, 'J-login').click()
time.sleep(2)

# 获取验证码图片
captcha = driver.find_element(By.ID, 'J-loginImg')
captcha.screenshot('captcha.png')

步骤2:识别缺口位置

import cv2
import numpy as np

def detect_gap(bg_path, tp_path):
    # 读取背景图片和缺口图片
    bg_img = cv2.imread(bg_path)
    tp_img = cv2.imread(tp_path)
    
    # 边缘检测
    bg_edge = cv2.Canny(bg_img, 100, 200)
    tp_edge = cv2.Canny(tp_img, 100, 200)
    
    # 匹配模板
    result = cv2.matchTemplate(bg_edge, tp_edge, cv2.TM_CCOEFF_NORMED)
    min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
    
    return max_loc[0]  # 返回缺口x坐标

# 使用示例
gap_x = detect_gap('captcha_bg.png', 'captcha_slider.png')
print(f"缺口位置在: {gap_x}px")

步骤3:模拟人类拖动

from selenium.webdriver import ActionChains

def simulate_drag(driver, slider, distance):
    # 创建动作链
    actions = ActionChains(driver)
    
    # 点击并按住滑块
    actions.click_and_hold(slider).perform()
    
    # 模拟人类拖动行为(先快后慢)
    total_tracks = []
    current = 0
    mid = distance * 4 / 5
    t = 0.2
    while current < distance:
        if current < mid:
            # 快速移动阶段
            a = 2
        else:
            # 慢速移动阶段
            a = -3
        
        v0 = 1
        move = v0 * t + 0.5 * a * t * t
        current += move
        
        # 添加随机偏移
        if current < distance:
            total_tracks.append(round(move))
    
    # 添加最后的微调
    total_tracks.append(round(distance - sum(total_tracks)))
    
    # 执行拖动操作
    for track in total_tracks:
        actions.move_by_offset(track, 0).perform()
        time.sleep(0.02)
    
    # 释放滑块
    actions.release().perform()

# 使用示例
slider = driver.find_element(By.ID, 'nc_1_n1z')
simulate_drag(driver, slider, gap_x)

处理点选验证码

点选验证码需要识别图片中的文字并点击对应位置。

步骤1:获取验证码图片和提示文字

# 获取提示文字
prompt_text = driver.find_element(By.CLASS_NAME, 'code-tip').text
print(f"提示文字: {prompt_text}")

# 获取验证码图片
captcha = driver.find_element(By.ID, 'J-loginImg')
captcha.screenshot('click_captcha.png')

步骤2:使用OCR识别文字位置

import pytesseract
from PIL import Image

def recognize_text(image_path):
    # 预处理图像
    img = Image.open(image_path)
    img = img.convert('L')  # 灰度转换
    img = img.point(lambda x: 0 if x < 128 else 255)  # 二值化
    
    # 使用OCR识别文字
    text = pytesseract.image_to_string(img, lang='chi_sim')
    return text.strip()

# 使用示例
captcha_text = recognize_text('click_captcha.png')
print(f"识别的文字: {captcha_text}")

步骤3:点击对应位置

def click_positions(driver, positions):
    # 获取验证码元素位置
    captcha = driver.find_element(By.ID, 'J-loginImg')
    x = captcha.location['x']
    y = captcha.location['y']
    
    # 点击每个位置
    actions = ActionChains(driver)
    for pos in positions:
        # 计算相对位置
        target_x = x + pos[0]
        target_y = y + pos[1]
        
        # 移动并点击
        actions.move_by_offset(target_x, target_y).click().perform()
        time.sleep(0.5)
    
    # 提交验证
    driver.find_element(By.ID, 'J-login').click()

# 使用示例
# positions = [(50, 30), (120, 80)]  # 根据识别结果确定的位置
# click_positions(driver, positions)

常见问题与解决方案

Q: 验证码识别率低怎么办?

A: 尝试以下方法:

  • 使用更高质量的OCR服务(如百度AI、腾讯AI)
  • 增加图像预处理步骤(去噪、锐化、二值化)
  • 使用深度学习模型训练专用识别器

Q: 被12306封IP怎么办?

A: 采取以下措施:

  • 使用代理IP池轮换IP地址
  • 降低请求频率,模拟人类操作间隔
  • 使用不同的User-Agent

Q: 如何提高模拟拖动的成功率?

A: 优化拖动行为:

  • 添加随机停顿和偏移量
  • 模拟加速度变化(先快后慢)
  • 添加垂直方向的随机抖动
  • 最后添加微调动作

总结

处理12306验证码需要结合图像处理、OCR识别和模拟人类行为技术。本教程提供了完整的解决方案,但需要注意12306会不断更新验证码机制,实际应用中需要持续调整策略。

滑动验证码

成功率: 70-85%

点选验证码

成功率: 60-75%

再次声明:本教程仅用于学习目的,请勿用于非法用途。

发表评论