python识别极验4滑块验证码实战

闲得无聊,趁着休息研究了一下极验4滑块验证码的安全性,是否有机器识别、自动化拖拽的可能性。首先看一下效果

 如何识别验证码

1、下载图片

下载图片可以参考博客《采集极验4滑块验证码图片数据》

 2、标记图片

3、标记滑动距离

 

实现代码

__author__ = "dengxinyan"

import io
import re
import time
import json
import base64
import random
import requests
import urllib
from io import BytesIO
from PIL import Image
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.format
    if 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":"nWrzPFUgFuqXQrCJJUM6",
        # 验证码类型
        "verify_idf_id":"23",
        # 样例图片
        "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):
    # 保存已经下载过的图片,防止重复
    img_url_list = []
    # 配置参数
    option = FirefoxOptions()
    if headless:
        option.add_argument('--headless')
    else:
        option.add_argument('--window-size=100,100')

    driver = webdriver.Firefox(executable_path=r'webdriver\geckodriver.exe', options=option)
    # 伪装浏览器
    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://www.geetest.com/adaptive-captcha-demo')

    # 等待【滑动拼图验证】元素出现
    WebDriverWait(driver, 20).until(lambda x: x.find_element_by_xpath('//button[contains(text(),"一点即过验证")]'))

    # 创建 ActionChains 对象
    action = ActionChains(driver)
    # 向窗口发送按键事件,例如向下滚动 1000px
    action.send_keys([Keys.DOWN, Keys.DOWN, Keys.DOWN, Keys.DOWN, Keys.DOWN, Keys.DOWN], 1000)
    action.perform()

    for i in range(5):
        # 等待【滑动拼图验证】元素出现
        WebDriverWait(driver, 20).until(lambda x: x.find_element_by_xpath('//button[contains(text(),"一点即过验证")]'))
        # 找到【滑动拼图验证】元素
        tag1 = driver.find_element_by_xpath('//button[contains(text(),"一点即过验证")]/..')
        # 点击
        tag1.click()
        time.sleep(1)

        # 等待【滑动拼图验证】元素出现
        WebDriverWait(driver, 20).until(lambda x: x.find_element_by_xpath('//button[contains(text(),"滑动拼图验证")]'))
        # 找到【滑动拼图验证】元素
        tag1 = driver.find_element_by_xpath('//button[contains(text(),"滑动拼图验证")]/..')
        # 点击
        tag1.click()
        time.sleep(1)

        # 等待【点击按钮开始验证】元素出现
        WebDriverWait(driver, 20).until(lambda x: x.find_element_by_xpath('//div[@aria-label="点击按钮开始验证"]'))
        # 找到【点击按钮开始验证】元素
        tag2 = driver.find_element_by_xpath('//div[@aria-label="点击按钮开始验证"]')
        # 点击
        tag2.click()

        # 等待【验证码大图】元素出现
        WebDriverWait(driver, 20).until(lambda x: x.find_element_by_xpath('//div[contains(@class,"geetest_bg")]'))
        while 1:
            try:
                # 找到【注册】元素
                tag7 = driver.find_element_by_xpath('//div[contains(@class,"geetest_bg")]')
                # 获取 img 标签的 src 属性
                style = tag7.get_attribute('style')
                # 提取图片链接
                img_url = re.findall('url[(]"(.+?)"[)]', style)[0]
                break
            except:
                continue

        # 请求获取图片
        response = requests.get(url=img_url)
        img = Image.open(BytesIO(response.content))
        # img = base64_PIL(base64_str)
        # 保存图片
        img.save('temp_img/{}.jpg'.format(int(time.time() * 1000)))
        img_url_list.append(img_url)

        # 验证码识别接口
        result = shibie(img)
        if result['code'] != 200:
            print(result)
            return
        move_x = int(result['data']['res_str'].replace('滑动', '').replace('px', ''))
        print('结果:', move_x)
        time.sleep(2)

        # 找到滑块 geetest_btn
        # 等待【找到滑块】元素出现
        WebDriverWait(driver, 20).until(lambda x: x.find_element_by_xpath('//div[contains(@class,"geetest_btn")]'))
        # 找到【找到滑块】元素
        tag8 = driver.find_elements_by_xpath('//div[contains(@class,"geetest_btn")]')[1]
        print(tag8)
        # 滑动滑块
        action = ActionChains(driver)
        action.click_and_hold(tag8).perform()

        # 计算实际滑动距离 = 像素距离 + 前面空白距离
        move_x = move_x - 15
        action.move_by_offset(move_x, 0)

        # n = (random.randint(3, 5))
        # move_x = move_x / n
        # for i in range(n):
        #     action.move_by_offset(move_x, 0)
        #     time.sleep(0.02)

        action.release().perform()

        # 判断是否滑动成功
        time.sleep(2)


if __name__ == '__main__':
    run(headless=False)

极验4滑块验证码识别我也封装成了API接口,可以提供给大家免费调用:得塔云

总结

1、和极验3相比,极验4大图反爬能力变弱了。因为极验3图片链接很快就会失效。

2、和极验3相比,极验4图片的解析难度变小了。因为极验3的图片是打乱的,还需要拼图。

3、极验4滑动过程也没有验证滑动轨迹

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Kotlin~Observer观察者模式

概念 定义一对多的依赖关系,让多个观察者同时监听一个主题对象。 角色介绍 Subject:主题,也称被观察者,它是具有状态的对象维护着一个观察者列表。提供添加、删除和通知观察者的方法。ConcreteSubject:具体主题&…

如何在armv6 armv7 armv8(aarch64)嵌入式板子上面安装nginx服务器,支持H265码流

如何在armv6 armv6 armv8 aarch64 嵌入式板子上面安装nginx服务器支持推送H265的视频流 开始吧 一,准备工作二,configure时遇到的出错问题1、checking for C compiler … found but is not working2,error: can not detect int size3&#xf…

【C++ 程序设计】第 1~9 章:常见知识点汇总

目录 一、C 语言简介 二、面向对象的基本概念 三、类和对象进阶 四、运算符重载 五、类的继承与派生 六、多态与虚函数 七、输入/输出流 八、文件操作 九、函数模板与类模板 一、C 语言简介 知识点名称内容C语言的发展简史★★1. C 语言是 C 语言的前身 &…

Flink写入数据到Doris

文章目录 1.Doris建表2.Doris依赖3.Bean实体类4.Doris业务写入逻辑5.测试写入类6.发送数据 1.Doris建表 Doris中建表 CREATE TABLE IF NOT EXISTS demo.user (id INT NOT NULL,name VARCHAR(255),age INT ) DISTRIBUTED BY HASH(id) PROPERTIES ("replication_num&qu…

顺丰基于 Flink CDC + Hudi 推进实时业务落地

摘要:本文整理自大数据研发高级工程师唐尚文,在 Flink Forward Asia 2022 数据集成专场的分享。本篇内容主要分为三个部分: 应用场景 实践与优化 未来规划 点击查看原文视频 & 演讲PPT 一、应用场景 1.1 顺丰集团业务概览 顺丰除了大家…

宝塔的Redis绑定IP

宝塔安装Redis 软件商店搜索Redis 连接宝塔面板的redis服务器失败的解决办法 检查Linux是否放行6379端口修改Redis绑定IP检查阿里云/腾讯云的防火墙策略是否放行6379端口 1.bind 127.0.0.1 修改为 bind 0.0.0.0 127.0.0.1 表示只允许本地访问,无法远程连接 0.0.0.0 表…

51单片机--AT24C02数据存储

文章目录 存储器的介绍AT24C02I2C总线I2C时序结构AT24C02数据帧AT24C02数据存储实例 存储器的介绍 存储器是计算机系统中的一种重要设备,用于存储程序和数据,它可以通过电子、磁性介质等技术来记录和保持数据。在这里,主要介绍的是随机存储器…

TableGPT: Towards Unifying Tables, Nature Language and Commands into One GPT

论文标题:TableGPT: Towards Unifying Tables, Nature Language and Commands into One GPT 论文地址:https://github.com/ZJU-M3/TableGPT-techreport/blob/main/TableGPT_tech_report.pdf 发表机构:浙江大学 发表时间:2023 本文…

BeanFactory容器的构建和使用示例

BeanFactory容器的实现流程: BeanFactory是Spring框架中的一部分,它提供了IoC(控制反转)的实现机制。下面是BeanFactory的IoC实现过程: 定义Bean定义:首先,我们需要在配置文件中定义Bean的定义…

详解分类指标Precision,Recall,F1-Score

文章目录 1. Precision(精度)2. Recall(召回率)3. F1-Score4. Accuracy(准确率)5. P-R 曲线6. TPR、FPR6.1 TPR(真正率)6.2 FPR(假正率) 7. ROC曲线8. AUC曲线…

vscode使用g++编译.c文件或.cpp文件

vscode是一个跨平台、轻量级、插件非常丰厚的IDE,这里介绍在vscode里使用g来编译.cpp文件。g也叫GCC, 在Window中,是使用MinGW方式实现g的,它分为32位和64位2个版本,其中,MinGW-64是64位的,MinGW-32是32位的…

linux学成之路(基础篇)(二十)rsync服务器

目录 前言 一、概述 监听端口 二、特点 快捷 安全 三、数据的同步方式 四、rsync传输方式 本地传输 远程传输 守护进程 五、命令 作为远程命令 作为rsync服务 选项 六、配置文件 全局配置 模块配置 守护进程传输 七、rsyncinotfy实时同步 一、服务端 二、…

力扣奇遇记 [第一章]

文章目录 😦第一题:拿下LeetCode1769. 移动所有球到每个盒子所需的最小操作数学习内容:LeetCode1769. 移动所有球到每个盒子所需的最小操作数🙈思路分析:💖代码产出: 😦第二题&#…

优雅的设计测试用例

⭐️前言⭐️ 入职以后接触到了公司的具体业务,提升了设计测试用例的能力,于是沉淀出这篇文档与大家分享。 🍉欢迎点赞 👍 收藏 ⭐留言评论 📝私信必回哟😁 🍉博主将持续更新学习记录收获&…

【C语言】表达式求值相关问题汇总—>隐式类型转换(整型提升)、算数转换与操作符优先级汇总(收藏查阅)

👀樊梓慕:个人主页 🎥个人专栏:《C语言》《数据结构》《蓝桥杯试题》 🌝每一个不曾起舞的日子,都是对生命的辜负。 目录 前言: 一、隐式类型转换 (一)整型提升的意义…

后端(四):博客系统项目

咱们在这里实现的是后端项目,前端代码就提一提,不全做重点介绍,在开始讲解这个博客系统项目之前,我们先看看这个项目的前端界面: 登录界面: 个人主页: 博客详情页: 写博客页&#x…

再见 Spring Boot 1.X ,Spring Boot 2.X 走向舞台中心

2019年8月6日,Spring 官方在其博客宣布,Spring Boot 1.x 停止维护,Spring Boot 1.x 生命周期正式结束。 其实早在2018年7月30号,Spring 官方就已经在博客进行过预告,Spring Boot 1.X 将维护到2019年8月1日。 1.5.x 将会…

【Java】重写compareTo()方法给对象数组排序

我们先给一个数组排序,我们肯定用的是Arrays.sort()方法: public class test2 {public static void main(String[] args) {int[] arr{3,5,4,6,9,8,1};System.out.println(Arrays.toString(arr));System.out.println("---------");Arrays.sort…

【C语言初阶】指针的运算or数组与指针的关系你了解吗?

🎬 鸽芷咕:个人主页 🔥 个人专栏:《快速入门C语言》《C语言初阶篇》 ⛺️生活的理想,就是为了理想的生活! 文章目录 📋 前言💬 指针运算💭 指针-整数💭 指针-指针💭 指针…

【Java基础教程】(四十二)多线程篇 · 上:多进程与多线程、并发与并行的关系,多线程的实现方式、线程流转状态、常用操作方法解析~

Java基础教程之多线程 上 🔹本节学习目标1️⃣ 线程与进程🔍关于多进程、多线程、并发与并行之间的概念关系? 2️⃣ 多线程实现2.1 继承 Thread 类2.2 实现 Runnable 接口2.3 多线程两种实现方式的区别2.4 利用 Callable 接口实现多线程2.5 …