Python识别抖音Tiktok、巨量引擎滑块验证码识别
由于最近比较忙,所以本周搞了一个相对简单的验证码,就是抖音Tiktok的滑块验证码,这也是接到客户的一个需求。这种验证码通常在电脑端登录抖音、巨量引擎的的时候出现。
首先看一下最终的效果:

验证码识别过程
1、利用爬虫采集图像
由于是识别滑块缺口位置,分析了一下,大图已经包含了滑块缺口的位置信息,所以这里只需要采集大图就够了。不需要小图进行比对,这样可以简单一点。
(1)采集大图

2、人工标记
为了保障识别的精度,这里需要进行大量的人工标记,最好将误差控制在1-2像素以内,这样训练出来的识别模型效果才好。

3、训练模型

4、测试验证
我们将训练好的模型用100张图片来进行测试,发现全部都能正确识别位置,所以正确率接近100%。因为100张测试图片比较少,所以保守估计正确率应该在99%左右。
如果再想提升正确率,可以再增加训练的数据量,就需要再投入大量人力,这个投入与提升产出比需要自己权衡。
5、实战测试
这里我就直接上代码,就是文章开通动图的演示效果。我也将模型封装成了免费的接口给感兴趣的小伙伴调用:得塔云
__author__ = "dengxinyan"import io
import time
import json
import requests
import urllib
import random
import base64
from io import BytesIO
from PIL import Image, ImageDraw, ImageFont
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.keys import Keys
from selenium.webdriver import ChromeOptions
from selenium.webdriver import FirefoxOptions# 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)return base64_str# 验证码识别接口
def shibie(img):url = "http://www.detayun.cn/openapi/verify_code_identify/"data = {# 用户的key"key":"nWrzPFUgFuqXQrCJJUME",# 验证码类型"verify_idf_id":"6",# 样例图片"img_base64":PIL_base64(img),"img_byte": None,# 中文点选,空间语义类型验证码的文本描述(这里缺省为空字符串)"words":""}header = {"Content-Type": "application/json"}# 发送请求调用接口response = requests.post(url=url, json=data, headers=header)print(response.text)return response.json()def run(headless=False):# 配置参数options = FirefoxOptions()if headless:options.add_argument('--headless')else:options.add_argument('--window-size=100,100')options.add_argument('--disable-blink-features=AutomationControlled')options.add_argument('--disable-dev-shm-usage')options.set_preference('general.useragent.override', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36')driver = webdriver.Firefox(executable_path=r'F:\验证码项目\小红书旋转验证码\webdriver\geckodriver.exe', options=options)# 伪装浏览器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://business.oceanengine.com/login?appKey=51')# 等待【请输入邮箱】元素出现WebDriverWait(driver, 20).until(lambda x: x.find_element_by_xpath('//input[@placeholder="请输入邮箱"]'))# 找到【请输入邮箱】元素tag1 = driver.find_element_by_xpath('//input[@placeholder="请输入邮箱"]')# 点击【请输入邮箱】元素tag1.click()# 输入邮箱tag1.send_keys('123451111@qq.com')# 等待【密码】元素出现WebDriverWait(driver, 20).until(lambda x: x.find_element_by_xpath('//input[@placeholder="密码"]'))# 找到【密码】元素tag2 = driver.find_element_by_xpath('//input[@placeholder="密码"]')# 点击【密码】元素tag2.click()# 输入密码tag2.send_keys('13611112222')# 等待【用户协议】元素出现WebDriverWait(driver, 20).until(lambda x: x.find_element_by_xpath('//div[@class="account-center-agreement-check"]'))# 找到【用户协议】元素tag3 = driver.find_element_by_xpath('//div[@class="account-center-agreement-check"]')# 点击【用户协议】元素tag3.click()# 等待【登录】元素出现WebDriverWait(driver, 20).until(lambda x: x.find_element_by_xpath('//button[@class="ace-ui-btn account-center-action-button active ace-ui-btn-primary"]'))# 找到【登录】元素tag4 = driver.find_element_by_xpath('//button[@class="ace-ui-btn account-center-action-button active ace-ui-btn-primary"]')# 点击【登录】元素tag4.click()# 可能一次不成功,需要多次滑动for i in range(5):# 等待【验证码大图】元素出现WebDriverWait(driver, 20).until(lambda x: x.find_element_by_xpath('//img[@id="captcha-verify-image"]'))# 找到【验证码大图】元素tag5 = driver.find_element_by_xpath('//img[@id="captcha-verify-image"]')# 获取图像链接img_url = tag5.get_attribute('src')print(img_url)header = {"Host": "p9-catpcha.byteimg.com","User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:72.0) Gecko/20100101 Firefox/72.0","Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8","Accept-Language": "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2","Accept-Encoding": "gzip, deflate, br","Connection": "keep-alive","Upgrade-Insecure-Requests": "1",}# 下载图片response = requests.get(url=img_url)img = Image.open(BytesIO(response.content))y = shibie(img)# 获得滑动像素距离y = int(str(y['data']['res_str']).replace('滑动','').replace('px',''))# 等待【滑块】元素出现WebDriverWait(driver, 20).until(lambda x: x.find_element_by_xpath('//div[@class="secsdk-captcha-drag-icon sc-kEYyzF fiQtnm"]'))# 找到【滑块】元素tag6 = driver.find_element_by_xpath('//div[@class="secsdk-captcha-drag-icon sc-kEYyzF fiQtnm"]')# 滑动滑块action = ActionChains(driver)action.click_and_hold(tag6).perform()time.sleep(1)# 计算实际滑动距离 = 像素距离 * 滑动系数move_x = y * 0.61# 滑动1:直接滑动action.move_by_offset(move_x + 20, 5)time.sleep(0.5)action.move_by_offset(-10, -15)time.sleep(0.5)action.move_by_offset(-10, 10)# 滑动2:分段滑动# n = (random.randint(5, 8))# move_x = move_x / n# for i in range(n):# action.move_by_offset(move_x, 5)# time.sleep(0.5)time.sleep(1)# 释放鼠标action.release().perform()time.sleep(2)# 判断是否滑动成功try:# 等待【错误提示】元素出现WebDriverWait(driver, 5).until(lambda x: x.find_element_by_xpath('//div[@class="sc-htoDjs jwiskW"]'))# 等待【刷新】元素出现WebDriverWait(driver, 20).until(lambda x: x.find_element_by_xpath('//span[@class="secsdk_captcha_refresh--text sc-bwzfXH gBXrMn"]'))# 找到【刷新】元素tag7 = driver.find_element_by_xpath('//span[@class="secsdk_captcha_refresh--text sc-bwzfXH gBXrMn"]')# 点击【刷新】元素tag7.click()time.sleep(1)except:breakif __name__ == '__main__':run(headless=False)
6、总结分析
(1)抖音图片标注工作比较复杂,我统计了一下背景图的种类超过800中,所以给标注、识别增加了一定难度
(2)抖音的滑动轨迹检测比较厉害,直接滑动到位完全无法通过,分段轨迹也很难通过。所以我首先滑过,再返回对齐,这样就能完美一次通过验证(最前面动图就是这样的效果)
(3)抖音页面有很强的反爬措施,检测我使用 selenium 始终无法通过验证,始终不会条验证码。这一点如何防检测 selenium 也请各位大神指点。所以我代码使用的巨量引擎(巨量引擎是字节跳动旗下的品牌)网站进行的测试
各位大神也请指出我的不足,或者有其他建议都可以给我留言,或私信我,谢谢指点。
相关文章:
Python识别抖音Tiktok、巨量引擎滑块验证码识别
由于最近比较忙,所以本周搞了一个相对简单的验证码,就是抖音Tiktok的滑块验证码,这也是接到客户的一个需求。这种验证码通常在电脑端登录抖音、巨量引擎的的时候出现。 首先看一下最终的效果: 验证码识别过程 1、利用爬虫采集图…...
EvilBox One靶场笔记
EvilBox: One靶场笔记 信息收集 先fscan找主机192.168.1.102 namp扫端口 开放80,22端口 然后扫目录 └─$ gobuster dir -r -u http://192.168.1.102/ -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -x php,txt,bak,html在扫secret目录,找…...
shell脚本中的export无效
写了一段shell脚本: #!/bin/bash source Tools/simulation/gazebo-classic/setup_gazebo.bash $(pwd) $(pwd)/build/px4_sitl_default export ROS_PACKAGE_PATH$ROS_PACKAGE_PATH:$(pwd) export ROS_PACKAGE_PATH$ROS_PACKAGE_PATH:$(pwd)/Tools/simulation/gazebo…...
前沿分享-鱼形机器人
可能并不太前沿了,是21年底的新闻了,但是看见了就顺便发一下吧。 大概就是,通过在pH响应型水凝胶中编码不同的膨胀速率而构建了一种环境适应型变形微机器人,让微型机器人直接向癌细胞输送药物从而减轻药物带来副作用。 技术原理是,…...
摄像机终端IP地址白名单配置流程
海康摄像头配置白名单流程 1.登录海康摄像机前端 2.进入配置-系统-安全管理-IP地址过滤 3.IP地址过滤方式选择“允许” 4.点击添加按钮输入对应的IP地址或者IP网段 5.最后勾选启用IP地址过滤,然后保存 大华摄像头配置白名单流程 1.登录大华摄像机前端 2.进入设…...
Glibc—查看版本
方式1:直接查看ldd版本 ldd --versionldd (Buildroot) 2.30 Copyright (C) 2019 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICU…...
C++物理引擎Box2D的下载,编译,VS2013配置环境
文章目录 网站和下载地址编译工具:编译box2dhelloworld测试网站和下载地址 https://box2d.org/ 下载地址 https://hub.nuaa.cf/erincatto/box2d/tags 编译工具: 1.VS2013 2.cmake 下载地址 https://cmake.org/ 编译box2d 下载box2d源码2.4.0,解压。在box2d-2.4.0目录下…...
STL容器详解——map容器
一、map容器介绍 作为关联式容器的一种,map 容器存储的都是 pair 对象,也就是用 pair 类模板创建的键值对。其中,各个键值对的键和值可以是任意数据类型,包括 C 基本数据类型(int、double 等)、使用结构体…...
VR全景在建筑工程行业能起到哪些作用?
在建筑工程领域,数字化技术为行业的发展起到巨大的推动作用,虽然建筑施工行业主要是依赖于工人劳动力和施工设备,但是VR全景在该行业中方方面面都能应用,从设计建模到项目交付,帮助建筑师以及项目方更好的理解每个环节…...
P1257 平面上的最接近点对
题目 思路 详见加强加强版 代码 #include<bits/stdc.h> using namespace std; #define int long long const int maxn4e510; pair<int,int> a[maxn]; int n; double d1e16; pair<int,int> vl[maxn],vr[maxn]; void read() { cin>>n;for(int i1;i<…...
8月1日上课内容 第一章web基础与http协议
dns与域名 网络是基于tcp/ip协议进行通信和连接的 应用层--传输层---网络层----数据链路层-----物理层 ip地址,我们每一台主机都有一个唯一的地址标识(固定的ip地址),区分用户和计算机通信。 ip地址:32位二进制数组成的,不方便记忆 192.168.…...
Gson 添加数据默认值问题记录
问题:在用Gson add(key(string类型),value(必须是JsonElement子类))时发现,value 传了 "" 空字符串(非null),默认解析后返回null&#…...
利用Arthas+APM监控进行Java性能深度定位
大家可能都用过APM监控,包括开源的Skywalking、商用的卓豪(ZOHO)ManageEngine APM应用性能监控、以及云监控产品如听云(Server监控),这些APM监控产品大大方便了我们实时监控应用性能,并实现性能…...
【BASH】回顾与知识点梳理(十一)
【BASH】回顾与知识点梳理 十一 十一. 八至十章知识点总结及练习11.1 总结11.2 练习情境模拟题一:透过 grep 搜寻特殊字符串,并配合数据流重导向来处理大量的文件搜寻问题。情境模拟题二:使用管线命令配合正规表示法建立新指令与新变量。 该系…...
vue2-diff算法
1、diff算法是什么? diff算法是一种通过同层的树节点进行比较的高效算法。 其有两个特点: 比较只会在同层级进行,不会跨层级进行。 在diff比较的过程中,循环从两边向中间比较。 diff算法在很多场景中都有应用,在vue中&…...
SpringBoot使用redis作为缓存的实例
目录 什么是缓存? 缓存的作用? 缓存的成本? 实际项目中的应用 代码展示 什么是缓存? 缓存就是数据交换的缓冲区(称作Cache [ kʃ ] ),是存贮数据的临时地方,一般读写性能较高。 缓…...
vue3使用vue3-seamless-scroll插件
1、局部引入 import vueSeamlessScroll from "vue-seamless-scroll"; 2、注册 components: { vueSeamlessScroll, }, 3、使用 <vue3-seamless-scroll :list"list1" class"scroll" step"0.2"><div class"item"…...
QT开发学习相关笔记
QT中配置文件读取 QT中使用的config文件为:xxx.ini文件,基本格式如下: 使用 QSetting(QT自带类)中的相关接口实现设置配置文件数据,或者读取数据。 读取配置文件路径设置如下,其中 iniPath为设置路径 ne…...
拆分PDBQT文件并将其转换为PDB格式
拆分PDBQT文件转为PDB格式 1. vina_split拆分PDBQT文件 假设你用AutoDock Vina做了对接,那么所有预测的结合构象都被放入一个多构象 PDBQT 文件中,如果需要拆分后进行可视化分析,那么Vina官方自带了vina_split来进行拆分。下面是vina_split…...
Reinforcement Learning with Code 【Code 4. DQN】
Reinforcement Learning with Code 【Code 4. DQN】 This note records how the author begin to learn RL. Both theoretical understanding and code practice are presented. Many material are referenced such as ZhaoShiyu’s Mathematical Foundation of Reinforcement…...
docker详细操作--未完待续
docker介绍 docker官网: Docker:加速容器应用程序开发 harbor官网:Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台,用于将应用程序及其依赖项(如库、运行时环…...
pam_env.so模块配置解析
在PAM(Pluggable Authentication Modules)配置中, /etc/pam.d/su 文件相关配置含义如下: 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块,负责验证用户身份&am…...
C# 类和继承(抽象类)
抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...
【python异步多线程】异步多线程爬虫代码示例
claude生成的python多线程、异步代码示例,模拟20个网页的爬取,每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程:允许程序同时执行多个任务,提高IO密集型任务(如网络请求)的效率…...
Unsafe Fileupload篇补充-木马的详细教程与木马分享(中国蚁剑方式)
在之前的皮卡丘靶场第九期Unsafe Fileupload篇中我们学习了木马的原理并且学了一个简单的木马文件 本期内容是为了更好的为大家解释木马(服务器方面的)的原理,连接,以及各种木马及连接工具的分享 文件木马:https://w…...
Java毕业设计:WML信息查询与后端信息发布系统开发
JAVAWML信息查询与后端信息发布系统实现 一、系统概述 本系统基于Java和WML(无线标记语言)技术开发,实现了移动设备上的信息查询与后端信息发布功能。系统采用B/S架构,服务器端使用Java Servlet处理请求,数据库采用MySQL存储信息࿰…...
uniapp 开发ios, xcode 提交app store connect 和 testflight内测
uniapp 中配置 配置manifest 文档:manifest.json 应用配置 | uni-app官网 hbuilderx中本地打包 下载IOS最新SDK 开发环境 | uni小程序SDK hbulderx 版本号:4.66 对应的sdk版本 4.66 两者必须一致 本地打包的资源导入到SDK 导入资源 | uni小程序SDK …...
人工智能--安全大模型训练计划:基于Fine-tuning + LLM Agent
安全大模型训练计划:基于Fine-tuning LLM Agent 1. 构建高质量安全数据集 目标:为安全大模型创建高质量、去偏、符合伦理的训练数据集,涵盖安全相关任务(如有害内容检测、隐私保护、道德推理等)。 1.1 数据收集 描…...
【把数组变成一棵树】有序数组秒变平衡BST,原来可以这么优雅!
【把数组变成一棵树】有序数组秒变平衡BST,原来可以这么优雅! 🌱 前言:一棵树的浪漫,从数组开始说起 程序员的世界里,数组是最常见的基本结构之一,几乎每种语言、每种算法都少不了它。可你有没有想过,一组看似“线性排列”的有序数组,竟然可以**“长”成一棵平衡的二…...
麒麟系统使用-进行.NET开发
文章目录 前言一、搭建dotnet环境1.获取相关资源2.配置dotnet 二、使用dotnet三、其他说明总结 前言 麒麟系统的内核是基于linux的,如果需要进行.NET开发,则需要安装特定的应用。由于NET Framework 是仅适用于 Windows 版本的 .NET,所以要进…...
