京东轨迹验证码识别代码

article/2025/7/13 18:56:27

 一、简介

这个是最新的京东轨迹验证码,需要用户根据轨迹画出对应的曲线。这个和传统的验证码有较大的差异,有非常大的难度。经过长时间的研究,现在终于解决了它的识别问题。

这个是识别效果,和真实轨迹基本上重合,所以轨迹识别正确率在95%左右。

在线免费测试效果:得塔云

二、识别代码

下面是识别这个轨迹验证码的样例代码

这个是通过验证码图片,然后获得识别的曲线轨迹点的代码,是识别最基础代码,不包含任何业务逻辑。大家可以根据这个基础代码,结合自己的业务逻辑进行修改。


import base64
import requests
import datetime
from io import BytesIO
from PIL import Imaget1 = datetime.datetime.now()#PIL图片保存为base64编码
def PIL_base64(img, coding='utf-8'):img_format = img.formatif img_format == None:img_format = 'JPEG'format_str = 'JPEG'if 'png' == img_format.lower():format_str = 'PNG'if 'gif' == img_format.lower():format_str = 'gif'if img.mode == "P":img = img.convert('RGB')if img.mode == "RGBA":format_str = 'PNG'img_format = 'PNG'output_buffer = BytesIO()# img.save(output_buffer, format=format_str)img.save(output_buffer, quality=100, format=format_str)byte_data = output_buffer.getvalue()base64_str = 'data:image/' + img_format.lower() + ';base64,' + base64.b64encode(byte_data).decode(coding)# base64_str = base64.b64encode(byte_data).decode(coding)return base64_str# 加载图片
img1 = Image.open(r'E:\Python\lixin_project\OpenAPI接口测试\test_img\70-1.jpg')
# 图片转base64
img1_base64 = PIL_base64(img1)# 验证码识别接口
url = "http://bq1gpmr8.xiaomy.net/openapi/verify_code_identify/"
data = {# 用户的key"key":"0AAahdF39yYIX2Qy1iAE",# 验证码类型"verify_idf_id":"70",# 样例图片"img_base64":img1_base64,
}
header = {"Content-Type": "application/json"}# 发送请求调用接口
response = requests.post(url=url, json=data, headers=header)# 获取响应数据,识别结果
print(response.text)
print("耗时:", datetime.datetime.now() - t1)

三、实战样例代码

这个是使用selenium进行实际滑动的代码。识别的轨迹和真实滑动的轨迹还是有一定差异。

1、缩放问题

原图宽度是275px,页面图片宽290px,所以缩放系数=290/275=1.05

2、偏移问题

识别的轨迹点是根据图片的轨迹位置来的,但是实际滑动,我发现在y坐标方向和x坐标方向有一定偏移。x方向需要+5px,y方向上需要+85px,才能和验证的轨迹对应上。目前不知道是不是所有用户环境都是偏移这值,所有需要大家自行测试。

3、实战滑动代码

__author__ = "dengxinyan"import re
import time
import json
import random
import requests
import urllib
import random
from io import BytesIO
from PIL import Image, ImageDraw
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver import ChromeOptions
from selenium.webdriver import FirefoxOptions
from selenium.webdriver.common.action_chains import ActionChains
from Common3.Common3 import *# key
key = 'efZ7oiIRZN1aOCqfynJt'
# 是否无头模式
headless = False# 随机生成手机号
def generate_phone_number_v2():# 各运营商号段segments = {'中国移动': ['134', '135', '136', '137', '138', '139', '147', '148', '150', '151','152', '157', '158', '159', '172', '178', '182', '183', '184', '187', '188', '198'],'中国联通': ['130', '131', '132', '145', '146', '155', '156', '166', '171', '175','176', '185', '186'],'中国电信': ['133', '149', '153', '173', '174', '177', '180', '181', '189', '191', '199']}# 随机选择一个运营商operator = random.choice(list(segments.keys()))# 随机选择该运营商的一个号段prefix = random.choice(segments[operator])# 生成剩余数字suffix = ''.join([str(random.randint(0, 9)) for _ in range(11 - len(prefix))])return prefix + suffix# 识别代码
def shibie_70(img1_base64):# 验证码识别接口url = "http://bq1gpmr8.xiaomy.net/openapi/verify_code_identify/"data = {# 用户的key"key": key,# 验证码类型"verify_idf_id": "70",# 样例图片"img_base64": img1_base64,}header = {"Content-Type": "application/json"}# 发送请求调用接口response = requests.post(url=url, json=data, headers=header)# 获取响应数据,识别结果print('得塔云返回结果:', response.text)return response.json()['data']['res_str']options = FirefoxOptions()
if headless:options.add_argument('--headless')
else:options.add_argument('--window-size=100,100')
options.add_argument('--disable-blink-features=AutomationControlled')
# 禁用webdriver属性(有效)
options.set_preference("dom.webdriver.enabled", False)
options.set_preference("marionette.enabled", False)
options.set_preference('useAutomationExtension', False) #关闭自动化提示# 禁用自动控制提示
options.set_preference("browser.tabs.remote.autostart", False)
options.set_preference("browser.tabs.remote.autostart.2", False)# 模拟具有插件的浏览器环境(有效)
options.set_preference("plugin.state.flash", 2)  # 设置Flash插件状态为启用
options.set_preference("plugin.state.java", 2)  # 设置Java插件状态为启用# 模拟具有特定的WebGL Vendor值的浏览器环境(WebGL Vendor:可以使用任何一家公认的WebGL Vendor名称,例如"Google Inc."、"Mozilla"、"Apple Inc."等。)
# 好像没有效果
options.set_preference("webgl.vendor", "Mozilla")  # 将"VendorName"替换为所需的WebGL Vendor值# 模拟具有特定的权限设置的浏览器环境
options.set_preference("permissions.default.microphone", 1)  # 设置麦克风权限为允许
options.set_preference("permissions.default.camera", 1)  # 设置摄像头权限为允许
options.set_preference("permissions.default.geo", 1)  # 设置地理位置权限为允许driver = webdriver.Firefox(executable_path=r'webdriver\geckodriver.exe', options=options)# 加载防检测js
with open('webdriver\stealth.min.js') as f:js = f.read()
driver.execute_script(js)  # 执行JavaScript代码# 伪装浏览器
driver.execute_script("Object.defineProperty(navigator, 'webdriver', {get: () => false,});")
navigator_webdriver = driver.execute_script("return navigator.webdriver")
driver.execute_script("Object.defineProperty(navigator, 'plugins', {get: () => [1, 2, 3, 4, 5],});")
plugins_length = driver.execute_script("return navigator.plugins.length")# 发送请求
driver.get('https://plogin.m.jd.com/mreg/index?appid=300&returnurl=https%3A%2F%2Fmy.m.jd.com%2F&account=')# 等待【用户同意】元素出现
WebDriverWait(driver, 20).until(lambda x: x.find_element_by_xpath('//button[@class="protocol-btn agreement"]'))
# 找到【用户同意】元素
tag1 = driver.find_element_by_xpath('//button[@class="protocol-btn agreement"]')
# 点击【用户同意】
tag1.click()# 等待【用户名】元素出现
WebDriverWait(driver, 20).until(lambda x: x.find_element_by_xpath('//input[@class="acc-input mobile J_ping"]'))
# 找到【用户名】元素
tag1 = driver.find_element_by_xpath('//input[@class="acc-input mobile J_ping"]')
# 输入用户名(随机生成手机号)
tag1.send_keys(generate_phone_number_v2())# 等待【登录】元素出现
WebDriverWait(driver, 20).until(lambda x: x.find_element_by_xpath('//a[@class="btn active"]'))
# 找到【登录】元素
tag1 = driver.find_element_by_xpath('//a[@class="btn active"]')
# 点击【登录】
tag1.click()for i in range(10):# 第一次不需要刷新if i != 0:# 点击刷新WebDriverWait(driver, 20).until(lambda x: x.find_element_by_xpath('//span[@class="jcap_refresh"]'))tag1 = driver.find_element_by_xpath('//span[@class="jcap_refresh"]')tag1.click()time.sleep(3)# 判断是否出现轨迹验证码WebDriverWait(driver, 20).until(lambda x: x.find_element_by_xpath('//img[@id="cpc_img"]'))tag1 = driver.find_element_by_xpath('//img[@id="cpc_img"]')# 获取大图img1_base64 = tag1.get_attribute('src')# base64编码转PILimg = base64_PIL(img1_base64)# 等待【滑动区】元素出现WebDriverWait(driver, 20).until(lambda x: x.find_element_by_xpath('//canvas[@id="trackLine"]'))# 找到【滑动区】元素canvas = driver.find_element_by_xpath('//canvas[@id="trackLine"]')point_list = eval(shibie_70(img1_base64))print('识别的轨迹:', point_list)# 显示轨迹部分draw = ImageDraw.Draw(img)kpt_size = 4for i, point in enumerate(point_list):# 计算点的边界框(确保是正方形)half_size = kpt_size // 2x1 = point[0] - half_sizey1 = point[1] - half_sizex2 = point[0] + half_sizey2 = point[1] + half_size# 绘制实心圆形点draw.ellipse([x1, y1, x2, y2], fill=(0, 0, 255), outline=(0, 0, 255))img.show()time.sleep(5)# 处理图片缩放问题  原图宽275px,页面图片宽290px,缩放系数=290/275=1.05,还要处理偏移,x+5,y+85point_list = [(int(x[0] * 1.05 + 5), int(x[1] * 1.05 + 85)) for x in point_list]actions = ActionChains(driver)# 移动到起始点并按下鼠标左键actions.move_to_element_with_offset(canvas, point_list[0][0], point_list[0][1])actions.click_and_hold()actions.pause(1)# 添加所有中间点的移动动作for point in point_list[1:-1]:  # 跳过第一个和最后一个点print('aaaaa:', point)actions.move_to_element_with_offset(canvas, point[0], point[1])# 可以添加微小延迟使动作更自然actions.pause(0.1)# 移动到最后一个点actions.move_to_element_with_offset(canvas, point_list[-1][0], point_list[-1][1])# 暂停1秒actions.pause(1)# 释放鼠标actions.release()# 执行所有动作actions.perform()

实际的滑动成功率可能需要大家研究研究。可能会涉及到很多因素影响成功率,比如滑动的速度,鼠标的按下、抬起的速度都可能会识别成机器人导致不过的情况。

想了解更多验证码识别请访问:得塔云


http://www.hkcw.cn/article/XjIClTTURp.shtml

相关文章

【Godot】如何导出 Release 版本的安卓项目

在使用 Godot 引擎开发安卓游戏或应用时,发布到应用市场(如 Google Play、华为应用市场等)通常需要生成一个 Release 版本的 .apk 包,而非 Debug 版本。本文将详细介绍如何将 Godot 项目导出为 Release 版本的安卓项目&#xff0c…

哈喽,我是钓鱼的肝

我嘛,一个五年级的小猴子,哦不,小孩子,给大家看看我长什么样子 呃,放错了 别想了,等你关注我再说 我写博客的缘由就是想让大家一起见证我的进步,二是把我的学习成果让更多人看见,三…

【Linux】网络--网络层--IP协议

个人主页~ 网络--网络层--IP协议 一、基本概念二、IP报头格式三、网络划分四、私有IP和公网IP五、路由路由表 六、与数据链路层之间的协议 一、基本概念 IP 协议是用于在互联网上进行数据传输的一种网络层协议,它为不同网络中的设备提供了一种统一的方式来交换数据…

MCP (模型上下文协议):AI界的“USB-C”标准,开启大模型应用新纪元

今天我们来聊聊一个可能深刻改变 AI 应用开发模式的新技术——MCP (Model Context Protocol,模型上下文协议)。这是由 Anthropic 公司(旗下拥有知名大模型 Claude)提出的一项旨在统一大模型与外部世界交互方式的“万能接口”。不妨把它想象成…

Python数学可视化——显函数、隐函数及复杂曲线的交互式绘图技术

Python数学可视化——显函数、隐函数及复杂曲线的交互式绘图技术 一、引言 在科学计算和数据分析中,函数与方程的可视化是理解数学关系和物理现象的重要工具。本文基于Python的Tkinter和Matplotlib库,实现一个功能完善的函数与方程可视化工具&#xff…

SpringBoot(六)--- AOP、ThreadLocal

目录 前言 一、AOP基础 1.入门程序 2. AOP核心概念 3. 底层原理 二、AOP进阶 1.通知类型 抽取切入点 2. 切入点表达式 2.1 execution 2.2 annoation 2.3 连接点详解 三、ThreadLocal 前言 AOP(面向切面编程),面向切面编程实际就…

贪心算法应用:在线租赁问题详解

贪心算法应用:在线租赁问题详解 贪心算法是一种在每一步选择中都采取当前状态下最优的选择,从而希望导致结果是全局最优的算法策略。在线租赁问题(Greedy Algorithm for Online Rentals)是一个经典的贪心算法应用场景,下面我将从多个维度全面…

BA-SAM: 用于 Segment Anything 模型的可扩展偏置模式注意力掩码

概要 在本文中,我们解决了 Segment Anything Model (SAM) 的图像分辨率变化挑战。SAM 以其零样本泛化性而闻名,当面对具有不同图像大小的数据集时,性能会下降。以前的方法倾向于将图像大小调整为固定大小或采用结构修改…

centos8修改IP地址和Hostname

修改ip地址 vim /etc/sysconfig/network-scripts/ifcfg-ens33 BOOTPROTO:设置为 static 表示使用静态 IP 地址。 IPADDR:设置新的 IP 地址。 NETMASK:设置子网掩码。 GATEWAY:设置默认网关(可选,但通常需要…

Python Day40 学习(复习学习日志Day5-7)

重新对信贷数据集进行了填补空缺值的操作 自己写的时候,还是出现了问题: 首先是忘记了要定义一下data, 通过data pd.read_csv(data.csv)可以将读取到的数据保存到变量data中,方便后续进行数据分析。 其次,是漏掉了 c data.col…

QML 粒子系统之Affector

目录 基本示例AffectorAge - 改变特定年龄粒子的属性Attractor - 吸引粒子到指定点Friction - 施加摩擦力Gravity - 模拟重力Wander - 随机游走效果Turbulence - 添加湍流效果 下载链接 接上篇QML 粒子系统 (雪花飘落、爆炸粒子效果),本文继续研究粒子系统中的附属效…

Mac 同时录制系统声音和麦克风声音(OBS + BlackHole 免费版)

🎬 一、你将实现的目标 ✅ 用 OBS 免费录制屏幕时,能同时录到: 🖥 系统播放的声音(比如视频、PPT音效、背景音乐) 🎙 你的麦克风说话声音(讲解或旁白) 🧰…

Pytorch知识点2

Pytorch知识点 1、官方教程2、张量🧱 0、数组概念🧱 1. 创建张量📐 2. 张量形状与维度🔢 3. 张量数据类型➗ 4. 张量的数学与逻辑操作🔄 5. 张量的就地操作📦 6. 复制张量🚀 7. 将张量移动到加速…

使用pandas实现合并具有共同列的两个EXCEL表

表1&#xff1a; 表2&#xff1a; 表1和表2&#xff0c;有共同的列“名称”&#xff0c;而且&#xff0c;表1的内容&#xff08;行数&#xff09;<表2的行数。 目的&#xff0c;根据“名称”列的对应内容&#xff0c;将表2列中的“所处行业”填写到表1相应的位置。 实现代…

【农资进销存专用软件】佳易王农资进出库管理系统:赋能农业企业高效数字化管理

一、软件概述与核心优势 &#xff08;一&#xff09;试用版获取方式 资源下载路径&#xff1a;进入博主头像主页第一篇文章末尾&#xff0c;点击卡片按钮&#xff1b;或访问左上角博客主页&#xff0c;通过右侧按钮获取详细资料。 说明&#xff1a;下载文件为压缩包&#xff…

深入理解AMBA总线(七)AHB设计要点和AHB2APB同步桥设计前言

** 深入理解AMBA总线&#xff08;七&#xff09;AHB设计要点和AHB2APB同步桥设计前言 ** 前面的几篇文章介绍了AHB-lite协议。主要内容其实就是文档的介绍加上我自己的一些理解&#xff0c;希望对大家有帮助。今天这篇文章将带来AHB设计需要注意的一些事项&#xff0c;然后带…

消除F/1噪声

目录 简介 如何测量及规定1/f噪声&#xff1f; 1/f噪声对电路有何影响&#xff1f; 如何消除或降低1/f噪声&#xff1f; 简介 本文阐释1/f噪声是什么&#xff0c;以及在精密测量应用中如何降低或消除该噪声。1/f噪声无法被滤除&#xff0c;在精密测量应用中它可能是妨碍实…

洛谷-P3912素数个数题解

P3912 素数个数 题目描述 求 1 , 2 , ⋯ , N 1,2,\cdots,N 1,2,⋯,N 中素数的个数。 输入格式 一行一个整数 N N N。 输出格式 一行一个整数&#xff0c;表示素数的个数。 输入输出样例 #1 输入 #1 10输出 #1 4说明/提示 对于 40 % 40\% 40% 的数据&#xff0c; …

【环境搭建】Java、Python、Nodejs等开发环境搭建

1. 前言 趁着 618 活动&#xff0c;我新换了一台电脑。开发的同学都知道&#xff0c;重新在新电脑搭建开发环境是一件相对繁琐的事&#xff0c;这篇文章我将介绍如何搭建Java&#xff08;jdk、maven等&#xff09;、Python&#xff08;uv、conda等&#xff09;、Nodejs、Docke…

【机器学习基础】机器学习入门核心算法:层次聚类算法(AGNES算法和 DIANA算法)

机器学习入门核心算法&#xff1a;层次聚类算法&#xff08;AGNES算法和 DIANA算法&#xff09; 一、算法逻辑二、算法原理与数学推导1. 距离度量2. 簇间距离计算&#xff08;连接标准&#xff09;3. 算法伪代码&#xff08;凝聚式&#xff09; 三、模型评估1. 内部评估指标2. …