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…...

Python3 高级教程 | Python3 正则表达式(一)
目录 一、Python3 正则表达式 (一)re.match函数 (二)re.search方法 (三)re.match与re.search的区别 二、检索和替换 (一)repl 参数是一个函数 (二)comp…...

奥威BI系统:零编程建模、开发报表,提升决策速度
奥威BI是一款非常实用的、易用、高效的商业智能工具,可以帮助企业快速获取数据、分析数据、展示数据。值得特别注意的一点是奥威BI系统支持零编程建模、开发报表,是一款人人都能用的大数据分析系统,有助于全面提升企业的数据分析挖掘效率&…...

海康威视摄像头二次开发_云台控制_视频画面实时预览(基于Qt实现)
一、项目背景 需求:需要在公司的产品里集成海康威视摄像头的SDK,用于控制海康威视的摄像头。 拍照抓图、视频录制、云台控制、视频实时预览等等功能。 开发环境: windows-X64(系统) + Qt5.12.6(Qt版本) + MSVC2017_X64(使用的编译器) 海康威视提供了设备网络SDK,设备网…...

单片机外部晶振故障后自动切换内部晶振——以STM32为例
单片机外部晶振故障后自动切换内部晶振——以STM32为例 作者日期版本说明Dog Tao2023.08.02V1.0发布初始版本 文章目录 单片机外部晶振故障后自动切换内部晶振——以STM32为例背景外部晶振与内部振荡器STM32F103时钟系统STM32F407时钟系统 代码实现系统时钟设置流程时钟源检测…...

Matlab实现决策树算法(附上多个完整仿真源码)
决策树是一种常见的机器学习算法,它可以用于分类和回归问题。在本文中,我们将介绍如何使用Matlab实现决策树算法。 文章目录 1. 数据预处理2. 构建决策树模型3. 测试模型4. 可视化决策树5. 总结6. 完整仿真源码下载 1. 数据预处理 在使用决策树算法之前…...

java中异步socket类的实现和源代码
java中异步socket类的实现和源代码 我们知道,java中socket类一般操作都是同步进行,常常在read的时候socket就会阻塞直到有数据可读或socket连接断开的时候才返回,虽然可以设置超时返回,但是这样比较低效,需要做一个循环来不停扫描…...

ElasticSearch7.6入门学习笔记
在学习ElasticSearch之前,先简单了解一下Lucene: Doug Cutting开发 是apache软件基金会4 jakarta项目组的一个子项目 是一个开放源代码的全文检索引擎工具包不是一个完整的全文检索引擎,而是一个全文检索引擎的架构,提供了完整的…...

《面试1v1》ElasticSearch架构设计
🍅 作者简介:王哥,CSDN2022博客总榜Top100🏆、博客专家💪 🍅 技术交流:定期更新Java硬核干货,不定期送书活动 🍅 王哥多年工作总结:Java学习路线总结…...

tomcat和nginx的日志记录请求时间
当系统卡顿时候,我们需要分析时间花费在哪个缓解。项目的后端接口可以记录一些时间,此外,在我们的tomcat容器和nginx网关上也可以记录一些有关请求用户,请求时间,响应时间的数据,可以提供更多的信息以便于排…...

数据结构——红黑树基础(博文笔记)
数据结构在查找这一章里介绍过这些数据结构:BST,AVL,RBT,B和B。 除去RBT,其他的数据结构之前的学过,都是在BST的基础上进行微小的限制。 1.比如AVL是要求任意节点的左右子树深度之差绝对值不大于1,由此引出…...