在电商数据采集场景中,验证码是网站反爬体系的重要屏障。常见的图文验证码与滑动验证码,分别通过 “文字识别障碍” 和 “行为真实性验证” 拦截机器爬虫。本文将拆解两种验证码的核心逻辑,结合 Python 工具库提供可落地的破解方案,同时探讨反反爬的关键技巧。

一、图文验证码:从 “干扰识别” 到 “精准提取”

图文验证码通过在文字中叠加噪点、干扰线、扭曲变形等元素,阻碍机器直接识别。破解核心是先预处理图像去除干扰,再通过 OCR 技术提取文字

1. 核心原理与破解流程

电商网站的图文验证码多为 “固定背景 + 随机文字 + 动态干扰” 结构,破解需 3 步:

  1. 图像预处理:去噪(删除孤立噪点)、二值化(将图像转为黑白对比)、去干扰线(消除横纵线条);
  2. 文字定位:分割验证码中的单个字符(若为多字符组合);
  3. OCR 识别:通过光学字符识别技术将图像文字转为文本。

2. 适配 Python 库

库名称

功能用途

安装命令

Pillow(PIL)

基础图像处理(裁剪、二值化)

pip install pillow

OpenCV-python

高级图像预处理(去噪、边缘检测)

pip install opencv-python

pytesseract

OCR 识别(基于 Tesseract 引擎)

pip install pytesseract

matplotlib

图像可视化(调试用)

pip install matplotlib

注意:pytesseract需依赖 Tesseract 引擎,需单独安装(Windows:载安装包并配置环境变量;Linux:sudo apt-get install tesseract-ocr)。

3. 实操代码示例

以某电商网站的 4 位数字图文验证码为例,实现破解:

import cv2
import pytesseract
from PIL import Image
import matplotlib.pyplot as plt

# 1. 加载验证码图像
img = cv2.imread("ecommerce_captcha.png")
# 转为灰度图(简化处理)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# 2. 图像预处理:去噪+二值化
# 高斯模糊去噪
blurred = cv2.GaussianBlur(gray, (3, 3), 0)
# 二值化(阈值127,高于设为255白,低于设为0黑)
_, thresh = cv2.threshold(blurred, 127, 255, cv2.THRESH_BINARY_INV)

# 3. 去除干扰线(形态学操作)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (2, 2))
# 开运算(先腐蚀再膨胀,消除细线条)
processed_img = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel)

# 4. OCR识别
# 转为PIL图像(pytesseract适配格式)
pil_img = Image.fromarray(processed_img)
# 限定识别范围为数字(提高准确率)
result = pytesseract.image_to_string(pil_img, config="--psm 10 --oem 3 -c tessedit_char_whitelist=0123456789")

# 5. 输出结果
print("图文验证码识别结果:", result.strip())
# 可视化处理前后对比
plt.subplot(1,2,1)
plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
plt.title("原始图像")
plt.subplot(1,2,2)
plt.imshow(processed_img, cmap="gray")
plt.title("预处理后图像")
plt.show()

4. 优化技巧

  • 若识别准确率低(如汉字、扭曲文字),可使用深度学习模型(如 CNN)训练自定义识别器,推荐库:keras、tensorflow;
  • 对倾斜文字,可通过cv2.getRotationMatrix2D()旋转校正;
  • 批量处理时,缓存预处理参数(如阈值、卷积核大小),减少重复调试。

二、滑动验证码:从 “轨迹模拟” 到 “行为伪装”

滑动验证码要求用户拖动滑块拼合残缺图像,核心反爬逻辑是检测滑块位置准确性 + 滑动轨迹是否符合人类行为(如匀速滑动、瞬间跳转易被判定为机器)。破解关键是精准计算缺口位置 + 模拟自然滑动轨迹

1. 核心原理与破解流程

电商滑动验证码多为 “背景图 + 缺口滑块” 结构,破解需 4 步:

  1. 获取图像:下载完整背景图和带缺口的背景图(或单独的滑块图);
  2. 计算缺口位置:通过图像比对找到缺口在背景图中的坐标;
  3. 生成自然轨迹:模拟人类 “先加速后减速” 的滑动节奏,避免匀速;
  4. 模拟滑动操作:通过浏览器自动化工具拖动滑块。

2. 适配 Python 库

库名称

功能用途

安装命令

requests

发送 HTTP 请求获取验证码图像

pip install requests

OpenCV-python

图像比对(计算缺口位置)

pip install opencv-python

Selenium

浏览器自动化(模拟滑动)

pip install selenium

webdriver-manager

自动管理浏览器驱动(无需手动配置)

pip install webdriver-manager

numpy

数值计算(轨迹生成)

pip install numpy

3. 实操代码示例

以某电商网站滑动验证码为例,基于 Selenium 实现破解:

import requests
import cv2
import numpy as np
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
from webdriver_manager.chrome import ChromeDriverManager
import time

# 1. 配置浏览器(无头模式可选,减少可视化干扰)
driver = webdriver.Chrome(ChromeDriverManager().install())
driver.get("https://example-ecommerce.com/login")  # 电商登录页(含滑动验证码)
time.sleep(2)  # 等待页面加载

# 2. 获取验证码图像(背景图+滑块图,需按实际网站DOM结构调整XPATH)
def get_captcha_img(driver, xpath):
    """根据XPATH获取图像并转为OpenCV格式"""
    img_element = driver.find_element("xpath", xpath)
    # 获取图像URL并下载
    img_url = img_element.get_attribute("src")
    img_response = requests.get(img_url)
    with open("temp_img.png", "wb") as f:
        f.write(img_response.content)
    # 转为OpenCV图像
    return cv2.imread("temp_img.png", 0)  # 0表示灰度图

# 下载背景图(完整图)和缺口图(带缺口的背景图)
bg_img = get_captcha_img(driver, '//div[@class="bg-img"]/img')
gap_img = get_captcha_img(driver, '//div[@class="gap-img"]/img')

# 3. 计算缺口位置(模板匹配:用缺口图匹配背景图中的缺口)
def find_gap_pos(bg_img, gap_img):
    """返回缺口在背景图中的x坐标"""
    # 模板匹配(TM_CCOEFF_NORMED方法:匹配度越高,值越接近1)
    result = cv2.matchTemplate(bg_img, gap_img, cv2.TM_CCOEFF_NORMED)
    # 找到匹配度最高的位置
    min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
    # 缺口宽度的一半(滑块需移动到缺口中心)
    gap_width = gap_img.shape[1] // 2
    return max_loc[0] + gap_width

gap_x = find_gap_pos(bg_img, gap_img)
print("缺口位置x坐标:", gap_x)

# 4. 生成自然滑动轨迹(先加速后减速)
def generate_trace(distance):
    """根据滑动距离生成轨迹(x坐标列表)"""
    trace = []
    current_x = 0
    # 总时间(人类滑动约0.5-1秒)
    total_time = 0.8
    # 时间间隔(每0.01秒记录一次位置)
    interval = 0.01
    # 加速度阶段(前60%距离)
    accelerate_distance = distance * 0.6
    while current_x < distance:
        if current_x < accelerate_distance:
            # 加速度a=2,速度v=v0+at
            speed = current_x / (total_time * 0.6)
        else:
            # 减速阶段(加速度为负)
            speed = (distance - current_x) / (total_time * 0.4)
        # 每次移动的距离
        move_x = speed * interval
        current_x += move_x
        trace.append(round(current_x))
    # 确保最终位置准确(避免误差)
    if trace[-1] != distance:
        trace[-1] = distance
    return trace

# 滑块初始位置x坐标(需按实际网站调整,如滑块初始在x=20处)
start_x = 20
distance = gap_x - start_x
trace = generate_trace(distance)

# 5. 模拟滑动操作
# 找到滑块元素(按实际DOM结构调整XPATH)
slider = driver.find_element("xpath", '//div[@class="slider"]')
# 按下滑块
ActionChains(driver).click_and_hold(slider).perform()
time.sleep(0.1)
# 按轨迹滑动
for x in trace:
    ActionChains(driver).move_by_offset(x - start_x - sum(trace[:trace.index(x)]), 0).perform()
    time.sleep(0.01)
# 松开滑块
ActionChains(driver).release().perform()

# 6. 验证结果(观察页面是否跳转,或是否提示验证成功)
time.sleep(2)
if "登录成功" in driver.page_source:
    print("滑动验证码破解成功!")
else:
    print("滑动验证码破解失败,需调整轨迹或缺口计算逻辑。")

driver.quit()

4. 反反爬关键技巧

  • 轨迹优化:加入随机小抖动(如 y 轴微小偏移 ±1),避免轨迹过于平滑;
  • 时间控制:滑动总时间随机在 0.5-1.2 秒之间,避免固定时长;
  • 浏览器环境伪装:通过selenium.webdriver.ChromeOptions()设置真实 User-Agent、禁用自动化检测(如--disable-blink-features=AutomationControlled);
  • IP 轮换:若多次失败,使用代理 IP(推荐库:requests-proxies),避免 IP 被封禁。

三、合规与风险提示

  1. 法律边界:根据《网络安全法》《数据安全法》,未经网站允许的爬虫可能涉嫌违法,破解验证码前需确认网站robots.txt协议,或获取合法授权;
  2. 反爬对抗动态性:电商网站会持续升级验证码(如加入点选验证码、短信验证码),需定期更新破解逻辑;
  3. 技术伦理:避免过度爬取导致网站服务器负载过高,建议控制请求频率(如每 10 秒一次)。

四、总结与进阶方向

本文通过 “预处理 + OCR” 破解图文验证码,“图像比对 + 轨迹模拟” 破解滑动验证码,提供了基础且可落地的方案。进阶学习可关注:

  • 复杂验证码:使用深度学习(如 YOLOv8)识别点选验证码、汉字扭曲验证码;
  • 无浏览器爬取:通过Playwright(比 Selenium 更轻量)或Pyppeteer实现滑动;
  • 验证码识别 API:若自研成本高,可接入第三方 API(如阿里云 OCR、腾讯云验证码识别),降低开发难度。

反爬与破解的对抗本质是 “攻防迭代”,技术人员需在合规前提下,持续优化方案以适应网站反爬策略的更新。

更多推荐