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 也请各位大神指点。所以我代码使用的巨量引擎(巨量引擎是字节跳动旗下的品牌)网站进行的测试

各位大神也请指出我的不足,或者有其他建议都可以给我留言,或私信我,谢谢指点。
 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/81302.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Vue】使用print.js插件实现打印预览功能,超简单

目录 一、实现效果 二、实现步骤 【1】安装插件 【2】在需要打印的页面导入 【3】在vue文件中需要打印的部分外层套一层div,给div设置id。作为打印的区域 【4】在打印按钮上添加打印事件 【5】在methods中添加点击事件 三、完整代码 一、实现效果 二、实现步…

Spring集成Seata

Seata的集成方式有: 1. Seata-All 2. Seata-Spring-Boot-Starter 3. Spring-Cloud-Starter-Seata 本案例使用Seata-All演示: 第一步:下载Seata 第二步:为了更好看到效果,我们将Seata的数据存储改为db 将seata\sc…

《合成孔径雷达成像算法与实现》Figure3.2

代码参数说明:Sf1为书中公式3.19,Sf2为时域信号快速傅里叶表达式,两种频谱表达式所做出的图可看出其区别 代码如下: clc clear all close all%参数设置 TBP 720; %时间带宽积 T 10e-6; %脉冲持续时间%参数计…

kafka:java client使用总结塈seek() VS commitSync()的区别(三)

最近一段日子接触了kafka这个消息系统,主要为了我的开源中间件项目simplemq增加kafka支持(基于kafka-client【java】),如今总算完成,本文是对这个过程中对kafka消息系统的使用总结 线程安全 关于线程安全&#xff0c…

java中javamail发送带附件的邮件实现方法

java中javamail发送带附件的邮件实现方法 本文实例讲述了java中javamail发送带附件的邮件实现方法。分享给大家供大家参考。具体分析如下: JavaMail,顾名思义,提供给开发者处理电子邮件相关的编程接口。它是Sun发布的用来处理email的API。它…

Python连接Hive实例教程

一 Python连接hive环境实例 经在网络查询相关的教程,发现有好多的例子,发现连接底层用的的驱动基本都是pyhive和pyhs2两种第三方库的来连接的 hive,下面将简介windows 10 python 3.10 连接hive的驱动程序方式,开发工具:pycharm …

找工作的才是大爷?面试了一个工作4年的测试工程师,一问连自动化基础都不清楚,还反过来怼我....

我们公司也开始大量招人了,我这次是公司招聘的面试官之一,主要负责一些技术上的考核,这段时间还真让我碰到了不少奇葩求职者 昨天公司的HR小席刚跟我吐槽:这几个星期没有哪天不加班的!各种招聘网站上的消息源源不断&a…

MyCat管理及监控——zookeeper及MyCat-web安装

1.MyCat管理 2.MyCat-eye 3.zookeeper安装 第一步:解压 第二部: 切换目录,创建data文件夹 第三步:修改zookeeper配置文件 这样zookeeper安装及配置就完成了 4.MyCat-web安装 注意mycat-web要与zookeeper关联,…

FL Studio低版本怎么免费升级:FL Studio升级要钱吗?

为了更好的服务国内FL Studio用户,FL Studio 官网提供了跨版本升级的服务,用户可以通过缴纳一定的费用,将自己已购买的入门版或其他非完整版的版本,升级为更高的版本,解锁更多的插件,而无需重新购买整套版本…

深入浅出对话系统——闲聊对话系统进阶

引言 本文主要关注生成式闲聊对话系统的进阶技术。 基于Transformer的对话生成模型 本节主要介绍GPT系列文章,这是由OpenAI团队推出的,现在大火的ChatGPT也是它们推出的。 GPT : Improving Language Understanding by Generative Pre-Traini ng 在自…

每次执行@Test方法前都执行一次DB初始化(SpringBoot Test + JUnit5环境)

引言 在执行单元测试时,可以使用诸如H2内存数据库替代线上的Mysql数据库等,如此在执行单元测试时就能尽可能模拟真实环境的SQL执行,同时也无需依赖线上数据库,增加了测试用例执行环境的可移植性。而使用H2数据库时,通…

两个多选框(select)之间值的左右上下移动

<!DOCTYPE html> <html> <head><meta charset"utf-8"><title>两个多选框(select)之间值的左右上下移动</title> </head> <script src"https://cdn.bootcss.com/jquery/3.3.1/jquery.js"></script>&…

看重ARM?苹果、三星、英伟达等知名企业纷纷表示加大投资

根据日经亚洲的报道&#xff0c;芯片设计公司Arm计划进行首次公开募股并在纳斯达克上市。苹果、三星电子、英伟达、英特尔等知名企业计划在Arm美股上市后投资该公司。 据悉&#xff0c;Arm将于9月份上市&#xff0c;预计估值将达到至少600亿美元&#xff08;约合4314亿元人民币…

Spring Boot多级缓存实现方案

1.背景 缓存&#xff0c;就是让数据更接近使用者&#xff0c;让访问速度加快&#xff0c;从而提升系统性能。工作机制大概是先从缓存中加载数据&#xff0c;如果没有&#xff0c;再从慢速设备(eg:数据库)中加载数据并同步到缓存中。 所谓多级缓存&#xff0c;是指在整个系统架…

Jmeter录制HTTPS脚本

Jmeter录制HTTPS脚本 文章目录 添加“HTTP代理服务器”设置浏览器代理证书导入存在问题 添加“HTTP代理服务器” 设置浏览器代理 保持端口一致 证书导入 点击一下启动让jmeter自动生成证书&#xff0c;放在bin目录下&#xff1a; 打开jmeter的SSL管理器选择刚刚生成的证书&…

Linux root用户执行修改密码命令,提示 Permission denied

问题 linux系统中&#xff08;ubuntu20&#xff09;&#xff0c;root用户下执行passwd命令&#xff0c;提示 passwd: Permission denied &#xff0c;如下图&#xff1a; 排查 1.执行 ll /usr/bin/passwd &#xff0c;查看文件权限是否正确&#xff0c;正常情况是 -rwsr-xr…

20230807通过ffmpeg将DTS编码的AUDIO音频转换为AAC编码

20230807通过ffmpeg将DTS编码的AUDIO音频转换为AAC编码 2023/8/7 20:04 ffmpeg dts 转AAC 缘起&#xff1a;由于网上找的电影没有中文字幕&#xff0c;有内置的英文字幕&#xff0c;但是还是通过剪映/RP2023识别一份英文字幕备用&#xff01; I:\Downloads\2005[红眼航班]Red E…

一、MySql前置知识

文章目录 一、什么是数据库&#xff08;一&#xff09;存储数据用文件就可以了&#xff0c;为什么还要弄个数据库?&#xff08;二&#xff09;数据库存储介质&#xff1a;&#xff08;三&#xff09;主流数据库 二、数据库基本操作&#xff08;一&#xff09;连接服务器&#…

基于Spring Boot的医院预约挂号网站设计与实现(Java+spring boot+MySQL)

获取源码或者论文请私信博主 演示视频&#xff1a; 基于Spring Boot的医院预约挂号网站设计与实现&#xff08;Javaspring bootMySQL&#xff09; 使用技术&#xff1a; 前端&#xff1a;html css javascript jQuery ajax thymeleaf 微信小程序 后端&#xff1a;Java spring…

Linux 远程登录

Linux 远程登录 Linux 一般作为服务器使用&#xff0c;而服务器一般放在机房&#xff0c;你不可能在机房操作你的 Linux 服务器。 这时我们就需要远程登录到Linux服务器来管理维护系统。 Linux 系统中是通过 ssh 服务实现的远程登录功能&#xff0c;默认 ssh 服务端口号为 2…