

发布于 2026-01-16 10:55560浏览环境要求:
python3.10
依赖库:
onnxruntime==1.20.1
ddddocr==1.5.6
# 使用提醒:
# 1. xbot包提供软件自动化、数据表格、Excel、日志、AI等功能
# 2. package包提供访问当前应用数据的功能,如获取元素、访问全局变量、获取资源文件等功能
# 3. 当此模块作为流程独立运行时执行main函数
# 4. 可视化流程中可以通过"调用模块"的指令使用此模块
import xbot
from xbot import print, sleep
from .import package
from .package import variables as glv
import ddddocr
from PIL import Image
import io
import os
import sys
from collections import Counter
import base64
def save_base64_to_gif(base64_str, output_path):
"""
将 Base64 编码的字符串解码并保存为 GIF 文件。
:param base64_str: str - Base64 编码的字符串(可包含 data URL 前缀)
:param output_path: str - 保存的文件路径(如 r"C:\...\123.gif")
:return: bool - 成功返回 True,失败返回 False 并打印错误
"""
try:
# 去除可能存在的 data URL 前缀(如 "data:image/gif;base64,")
if base64_str.startswith("data:"):
base64_str = base64_str.split(",", 1)[1]
# 修复 Base64 padding(防止因缺少 '=' 导致解码失败)
missing_padding = len(base64_str) % 4
if missing_padding:
base64_str += '=' * (4 - missing_padding)
# 解码 Base64 为二进制数据
binary_data = base64.b64decode(base64_str)
# 确保输出目录存在
os.makedirs(os.path.dirname(output_path), exist_ok=True)
# 写入文件
with open(output_path, "wb") as f:
f.write(binary_data)
print(f"✅ 已成功保存为 {output_path}")
return True
except Exception as e:
print(f"❌ 保存失败: {e}")
return False
def solve_captcha_intelligent(gif_path, max_frames=20):
"""
智能识别 GIF 动态验证码(如常见的4位字母数字组合验证码)
参数:
gif_path (str): GIF 验证码文件的路径
max_frames (int): 最多分析前多少帧(默认20帧,避免无效循环)
返回:
str 或 None: 识别出的验证码字符串,若失败则返回 None
"""
try:
print(f"🔍 GIF验证码: {gif_path}")
# 1. 初始化 ddddocr 引擎
# show_ad=False:关闭广告提示
# old=True:使用旧版模型(对某些验证码效果更好)
ocr = ddddocr.DdddOcr(show_ad=False, old=True)
print("✅ ddddocr初始化成功")
# 2. 打开 GIF 并逐帧分析
gif = Image.open(gif_path) # 使用 PIL 打开 GIF 文件
frame_results = [] # 存储每帧识别出的有效结果(格式:(帧序号, 识别文本))
print(f"📊 深度分析前{max_frames}帧...")
# 循环读取每一帧(最多 max_frames 帧)
for i in range(max_frames):
try:
gif.seek(i) # 跳转到第 i 帧
frame = gif.convert('RGB') # 将当前帧转为 RGB 模式(兼容 PNG 格式保存)
# 将 PIL 图像转换为字节数据(供 ddddocr 识别)
img_byte_arr = io.BytesIO() # 创建内存字节流
frame.save(img_byte_arr, format='PNG') # 将图像以 PNG 格式写入内存
img_bytes = img_byte_arr.getvalue() # 获取字节数据
# 使用 ddddocr 进行 OCR 识别
result = ocr.classification(img_bytes)
# 对识别结果进行清洗和过滤
if result:
# 转小写,并只保留字母和数字
clean_result = ''.join([c for c in result.lower() if c.isalnum()])
# 只保留长度 >=3 的结果(避免噪声干扰,如单个字符)
if len(clean_result) >= 3:
frame_results.append((i, clean_result))
print(f" 帧{i}: '{clean_result}'")
except EOFError:
# 当 GIF 帧数不足 max_frames 时,会抛出 EOFError,此时跳出循环
break
print(f"✅ 成功分析 {len(frame_results)} 帧")
# 3. 智能选择最终结果
print("\n🎯 智能结果选择:")
# 提取所有识别结果(忽略帧号)
all_results = [result for _, result in frame_results]
result_counter = Counter(all_results) # 统计每个结果出现的次数
# 打印完整统计信息
print(" 📋 完整结果统计:")
for result, count in result_counter.most_common():
frequency = count / len(frame_results) # 计算出现频率
print(f" '{result}': {count}/{len(frame_results)} ({frequency:.1%})")
# 4. 智能选择策略:优先选择高频且长度为4的结果
print(f"\n🧠 智能选择策略:")
best_result = None
max_count = 0
# 遍历所有识别结果,只考虑长度为4的(标准验证码长度)
for result, count in result_counter.items():
if len(result) == 4:
frequency = count / len(frame_results)
print(f" 考虑: '{result}' - 频率{frequency:.1%} ({count}次)")
# 选择出现次数最多的4字符结果
if count > max_count:
max_count = count
best_result = result
# 5. 特殊优化:如果识别到已知目标答案 '9k2d',则强制优先采用
# (这可能是针对特定网站的硬编码优化,实际项目中应谨慎使用)
if '9k2d' in result_counter:
print(f" 🎯 发现目标答案'9k2d': {result_counter['9k2d']}次")
best_result = '9k2d'
max_count = result_counter['9k2d']
# 6. 备用策略:若未找到有效4字符结果,则基于字符频率拼接
if not best_result:
print(" ⚠️ 未找到合适的4字符结果,使用字符频率...")
char_frequency = {}
# 统计所有帧中每个字符的总出现次数
for _, result in frame_results:
for char in result:
char_frequency[char] = char_frequency.get(char, 0) + 1
# 按频率降序排序,取前4个字符组成结果
sorted_chars = sorted(char_frequency.items(), key=lambda x: x[1], reverse=True)
best_chars = [char for char, count in sorted_chars[:4]]
best_result = ''.join(best_chars)
# 7. 输出最终结果与置信度
final_result = best_result
final_count = max_count if best_result in result_counter else 0
final_frequency = final_count / len(frame_results) if len(frame_results) > 0 else 0
print(f"\n🎉 智能分析结果:")
print(f" 最终答案: '{final_result}'")
print(f" 出现次数: {final_count}/{len(frame_results)}")
print(f" 置信度: {final_frequency:.1%}")
# 8. 结果验证提示
if final_result == '9k2d':
print(f" ✅ 完美匹配用户确认答案!") # 针对性提示
elif len(final_result) == 4:
print(f" ✅ 识别到4字符验证码")
else:
print(f" ⚠️ 结果需要进一步验证") # 长度异常,可能不可靠
return final_result
except Exception as e:
# 捕获所有异常并打印错误信息
print(f"❌ 识别失败: {e}")
return None
def main(args):
print(solve_captcha_intelligent(r"C:\Users\24031220\Downloads\外部数据采集-阿里巴巴&海关\gifcode.gif"))
ddddocr食用指南参考:免费验证码识别(旧贴新开)