在进行自动化登录时,验证码是最常见的反自动化机制,常见验证码包括:
- 图形验证码(输入字符)
- 滑动验证码(拼图、滑块)
- 点选验证码(点击猫、点击倒立字等)
本文重点探讨图形验证码与滑动验证码的处理策略。
🎯 目标问题
“我用 Selenium 登录网站时,总是被验证码拦住了,该怎么办?”
答案是:Selenium 本身无法绕过验证码,但你可以配合识别工具、服务、策略来解决。
📌 一、图形验证码处理思路
🧠 方案一:打码平台(推荐)
调用打码平台(如若快、云打码、超级鹰、TT识图)提供的 API 识别验证码图片。
# 示例伪代码
captcha_element = driver.find_element(By.ID, "captcha-img")
captcha_base64 = captcha_element.screenshot_as_base64
# 将 base64 传给打码平台识别
result = request.post("https://打码平台接口", data={"image": captcha_base64})
code = result['code']
driver.find_element(By.ID, "captcha-input").send_keys(code)
📌 优点:不需模型训练
📌 缺点:需要花钱,有失败率
🧠 方案二:自己训练模型识别验证码
适合验证码样式固定的自有系统,可使用:
- OCR(Tesseract、PaddleOCR)
- CNN 模型(如 TensorFlow/Keras)
需先用 Selenium 抓取几百张验证码图片,配上标签,训练模型。
适合长期稳定场景,不适合网站验证码样式随机或有强加噪。
📌 二、滑动验证码处理思路
例如腾讯、极验、字节系常见的滑块拼图验证码。
🧠 思路核心:
- 获取背景图 + 缺口图
- 分析两图差异,计算滑块应该滑动的距离
- 模拟人类滑动轨迹拖动滑块
✅ 示例:获取滑块位置差值
# 使用 PIL 比较两张图片,识别缺口位置
def get_offset(bg_path, gap_path):
from PIL import Image, ImageChops
bg = Image.open(bg_path).convert("L")
gap = Image.open(gap_path).convert("L")
diff = ImageChops.difference(bg, gap)
for x in range(diff.width):
for y in range(diff.height):
if diff.getpixel((x, y)) > 50:
return x
✅ 示例:模拟拖动滑块
from selenium.webdriver import ActionChains
slider = driver.find_element(By.ID, "slider")
ActionChains(driver).click_and_hold(slider).perform()
# 构造轨迹(真实情况应包含加速/减速/抖动)
track = [2, 4, 5, 8, 4, 3, 2]
for x in track:
ActionChains(driver).move_by_offset(xoffset=x, yoffset=0).perform()
time.sleep(0.02)
ActionChains(driver).release().perform()
📌 注意:简单匀速拖动大概率被识别为机器人,建议加入轨迹生成算法。
🧨 实战建议
类型 | 建议方案 |
---|---|
图形验证码 | 打码平台 / OCR识别 / 训练模型 |
滑动验证码 | 图片识别差值 + 模拟滑动轨迹 |
点选验证码 | AI识图 / 图像分割 + 点击定位 |
🧼 小结
- Selenium 无法直接绕过验证码,但可配合图像处理、第三方平台实现
- 滑动验证码需“图像差异识别 + 模拟真实轨迹”
- 尽量采用人工识别或打码服务,自己写模型需投入较大成本
📌 延伸阅读建议:
- PaddleOCR
- 极验验证码破解方案
- 滑动轨迹生成:贝塞尔曲线、人类行为模拟