自动化的道路上,有一个所有做采集的人都会遇到的终极拦路虎——验证码。
滑块验证码、图形验证码、文字点选、旋转验证……这些都是平台为了拦截自动化而设计的防线。前面60多篇文章讲了怎么定位元素、怎么翻页、怎么处理数据,但如果流程被验证码卡住,前面的一切都白费了。
今天把验证码和OCR识别的方案讲清楚:从最简单的“人工输入”到“自动化识别”,每种方案的适用场景、成本、实现方式,以及一套完整的价格监控流程里怎么嵌入验证码处理。
先说核心:验证码处理的四个层级
| 层级 | 方案 | 成本 | 自动化程度 | 适用场景 |
|---|
| L1 | 人工手动输入 | 人力成本 | 半自动 | 低频操作、开发测试 |
| L2 | 影刀内置OCR | 免费 | 全自动 | 简单数字/字母验证码 |
| L3 | 第三方OCR API | 按次付费 | 全自动 | 复杂验证码(百度/腾讯OCR) |
| L4 | 打码平台 | 按次付费(~1分/次) | 全自动 | 各种复杂验证码 |
第一部分:影刀内置OCR识别
适用场景: 验证码是简单的数字+字母组合,背景干净,字体清晰。
影刀实操路径: 指令面板搜索“OCR”或“图像识别” → 拖入“OCR识别区域”指令。
基础用法:识别验证码图片
# ===== 方案1:识别指定区域的验证码 =====
# 1. 截图验证码区域
屏幕截图(保存路径="C:/temp/captcha_full.png")

# 2. 用OCR识别指定区域
OCR识别区域(
图片路径="C:/temp/captcha_full.png",
左上X=100, 左上Y=200,
右下X=300, 右下Y=280,

输出变量=验证码文本
)
输出日志("识别到的验证码:" + 验证码文本)
# 3. 输入验证码
输入文本("//input[@id='captcha']", 验证码文本)
点击元素("//button[@id='submit']")
识别前预处理(提升准确率)
验证码识别的准确率很大程度上取决于图片质量。以下预处理可以显著提升识别率:
# ===== Python预处理验证码图片 =====
import cv2
import numpy as np
from PIL import Image
def preprocess_captcha(image_path, output_path):
# 1. 读取图片
img = cv2.imread(image_path)
# 2. 转为灰度图
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 3. 二值化(去除背景色)

_, binary = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
# 4. 降噪(去除孤立噪点)
kernel = np.ones((1, 1), np.uint8)
denoised = cv2.morphologyEx(binary, cv2.MORPH_OPEN, kernel)
# 5. 保存预处理后的图片
cv2.imwrite(output_path, denoised)
return output_path
# 在影刀中调用
执行Python代码(
输入: 原图路径="C:/temp/captcha_raw.png",
输出: 处理后路径="C:/temp/captcha_processed.png"
)
容易踩的坑:
- 内置OCR只支持简单的数字和英文字母
- 中文字符、扭曲字体、带干扰线的验证码识别率很低
- 验证码区域截图要尽可能紧贴验证码边界,减少背景干扰
第二部分:第三方OCR API(百度OCR、腾讯OCR)
适用场景: 内置OCR无法识别,但预算有限,且验证码不太复杂。
成本: 百度OCR每月有免费额度(500-1000次/月),超出后按次计费。
百度OCR接入示例
# ===== 百度OCR识别验证码 =====
import requests
import base64
import json
# 1. 获取百度OCR Access Token
def get_baidu_token(api_key, secret_key):
url = "https://aip.baidubce.com/oauth/2.0/token"
params = {
"grant_type": "client_credentials",
"client_id": api_key,
"client_secret": secret_key
}
response = requests.post(url, params=params)
return response.json()["access_token"]
# 2. 识别验证码图片
def ocr_captcha(image_path, token):
# 读取图片并转base64
with open(image_path, 'rb') as f:
img_base64 = base64.b64encode(f.read()).decode()
url = "https://aip.baidubce.com/rest/2.0/ocr/v1/general_basic"
params = {"access_token": token}
data = {"image": img_base64}
response = requests.post(url, params=params, data=data)
result = response.json()
if "words_result" in result:
return result["words_result"][0]["words"]
else:
return None
# 影刀中调用
token = get_baidu_token(api_key, secret_key)
captcha_text = ocr_captcha("C:/temp/captcha.png", token)
第三部分:打码平台(终极方案)
适用场景: 各种复杂验证码(汉字点选、滑块、旋转验证等),自动化的终极方案。
成本: 约1-10分钱/次(按验证码复杂度)
打码平台接入示例(以超级鹰为例)
# ===== 超级鹰打码平台接入 =====
import requests
import json
import base64
class Chaojiying:
def __init__(self, username, password, soft_id):
self.username = username
self.password = password
self.soft_id = soft_id
self.base_url = "http://upload.chaojiying.net/Upload/Processing.php"
def decode_captcha(self, image_path, codetype=1902):
"""
codetype:
1902: 4位英文数字
9101: 普通坐标
9004: 汉字点选
"""
with open(image_path, 'rb') as f:
img_base64 = base64.b64encode(f.read()).decode()
data = {
"user": self.username,
"pass": self.password,
"softid": self.soft_id,
"codetype": codetype,
"file_base64": img_base64
}
response = requests.post(self.base_url, data=data)
return response.json()
# 使用
cjy = Chaojiying("username", "password", "soft_id")
result = cjy.decode_captcha("C:/temp/captcha.png", codetype=1902)
if result["err_no"] == 0:
captcha_text = result["pic_str"]
输出日志("打码成功:" + captcha_text)
else:
输出日志("打码失败:" + result["err_str"])
打码平台选型建议
| 平台 | 优势 | 劣势 |
|---|---|---|
| 超级鹰 | 支持类型多、中文验证码强 | 需要预充值 |
| 图鉴 | 识别速度快 | 价格略高 |
| 云码 | 价格便宜 | 准确率稍低 |
| 打码兔 | 人工打码(准确率高) | 速度慢(人工) |
第四部分:验证码自动处理完整流程
把以上所有方案整合成一个完整的验证码处理子流程:
# ============================================
# 子流程:Handle_Captcha
# 职责:自动处理验证码,支持降级策略
# 输入:验证码图片区域坐标、验证码输入框XPath、提交按钮XPath
# 输出:是否成功
# ============================================
设置变量(处理成功 = False)
设置变量(最大尝试次数 = 3)
按次数循环(最大尝试次数):
尝试次数 = 循环索引 + 1
输出日志("第" + 尝试次数 + "次验证码处理")
# ----- 1. 截图验证码 -----
屏幕截图(保存路径="C:/temp/captcha_full.png")
# ----- 2. 裁剪验证码区域(用Python)-----
执行Python代码(
代码=裁剪图片(输入路径, 输出路径, 坐标),
输入: 输入路径="C:/temp/captcha_full.png",
输出: 输出路径="C:/temp/captcha_cropped.png"
)
# ----- 3. 尝试OCR识别(三种方案降级)-----
Try:
# 方案1:影刀内置OCR
调用子流程(OCR_内置, 输入: 图片路径, 输出: 验证码文本)
Catch:
输出日志("内置OCR失败,尝试百度OCR")
Try:
调用子流程(OCR_百度, 输入: 图片路径, 输出: 验证码文本)
Catch:
输出日志("百度OCR失败,尝试打码平台")
Try:
调用子流程(OCR_打码平台, 输入: 图片路径, 输出: 验证码文本)
Catch:
输出日志("所有OCR方案均失败,等待人工输入")
# 最后备用:人工输入
验证码文本 = 输入对话框("请输入验证码", "手动输入验证码")
EndTry
EndTry
EndTry
# ----- 4. 输入验证码 -----
输入文本(验证码输入框XPath, 验证码文本)
等待(0.5秒)
# ----- 5. 点击提交 -----
点击元素(提交按钮XPath)
等待(2秒)
# ----- 6. 判断是否成功 -----
如果 判断元素存在("//*[contains(text(),'验证失败') or contains(text(),'验证码错误')]") == False:
输出日志("验证码处理成功")
处理成功 = True
跳出循环
否则:
输出日志("验证码错误,刷新重试")
# 刷新验证码
点击元素("//*[contains(text(),'换一张') or contains(@class,'refresh')]")
等待(1秒)
结束If
结束循环
如果 处理成功 == False:
输出日志("【错误】验证码处理" + 最大尝试次数 + "次均失败")
抛出异常("验证码处理失败")
结束If
返回结果(处理成功)
第五部分:验证码识别率优化技巧
| 优化方向 | 具体做法 | 效果 |
|---|---|---|
| 截图精度 | 用网页截图全屏截图再裁剪,比屏幕截图更清晰 | 提升10-20% |
| 图片预处理 | 二值化+降噪+灰度化 | 提升20-30% |
| 选择合适OCR | 数字用内置OCR,中文用百度,复杂用打码平台 | 提升30%+ |
| 多帧平均 | 连续截3张图选最清晰的 | 提升5-10% |
| 区域缩放 | 将验证码区域放大1.5-2倍 | 提升15% |
# ===== 多帧截图取最清晰 =====
# 有些验证码图片是动态生成的,每秒刷新一次
设置变量(最佳图片 = "")
按次数循环(3):
屏幕截图(保存路径="C:/temp/captcha_" + 循环索引 + ".png")
等待(0.3秒)
结束循环
# 用Python比较三张图片的清晰度(边缘检测)
执行Python代码(
代码="""
import cv2
import os
def get_sharpness(image_path):
img = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)
return cv2.Laplacian(img, cv2.CV_64F).var()
best_path = max([f'C:/temp/captcha_{i}.png' for i in range(3)], key=get_sharpness)
""",
输出: best_path=最佳图片
)
输出日志("选择最清晰的截图:" + 最佳图片)
各平台验证码应对策略
| 平台 | 验证码类型 | 推荐方案 |
|---|---|---|
| 淘宝 | 滑块验证码 | 打码平台(滑块识别) |
| 拼多多 | 滑块验证码 | 打码平台 |
| 小红书 | 点击验证(含文字的图片) | 打码平台(文字点选) |
| 抖音 | 滑块+旋转验证码 | 打码平台 |
| 企业后台 | 数字/字母验证码 | 百度OCR |
| 普通网站 | 简单数字验证码 | 影刀内置OCR |
常见问题速查
| 问题 | 原因 | 解决方法 |
|---|---|---|
| OCR识别率低 | 验证码有干扰线/扭曲 | 用打码平台代替OCR |
| 打码平台返回错误 | 账号余额不足 | 检查余额,充值 |
| 验证码刷新不了 | 刷新按钮定位失败 | 用JS刷新或F5刷新页面 |
| 人工输入太慢 | 流程等待 | 升级为自动打码 |
| 滑动验证码识别失败 | 缺口位置识别不准 | 用专门滑块识别的打码接口 |
推荐资源
- 百度OCR开放平台(有免费额度)
- 超级鹰打码平台文档
- 图鉴打码平台官网
- 影刀官方《验证码处理》课程
#影刀RPA #RPA自动化 #OCR #验证码 #打码平台
作者:林焱
本文为《影刀RPA学习手册》系列文章之一,内容源于实操经验的整理与分享。
