网络爬虫-jd滑块验证码

news2024/10/6 8:33:39

仅供研究学习使用。

目标站点 --> 京东网页登录

在这里插入图片描述


当我们输入账号密码后,点击登录,首先映入眼帘的是一个滑块,那我们先分析一下滑块吧。

在这里插入图片描述
上图是滑块的有关信息,左边的横线是请求的url,右边是参数,很显然,里面有好多参数。但经过分析,d就是滑块轨迹的加密,c跟下图获取滑块图片一起返回的,下图中challenge就是参数c,参数e可以从网页源码中获取到,而参数appId是定值,参数o就是我们的账号

在这里插入图片描述

下面我们就分析一下参数d,看它怎么加密。

这里我是通过下图调用栈,找到的,点击下图画横线的,然后格式化一下,再搜索appId就可以找到。

在这里插入图片描述
最后找到的就是下图这个,这里我已经打上断点。

在这里插入图片描述
我们再次登录,会自动断在这里。我们滑动滑块,就会停到这里

在这里插入图片描述
可以清除看到,g为一个数组,其实就是我一定滑块的轨迹,这里我们可以借鉴一个文章里面的滑块轨迹思路

import random
import matplotlib.pyplot as plt
import numpy as np



class GTrace(object):
    def __init__(self):
        self.__pos_x = []
        self.__pos_y = []
        self.__pos_z = []

    def __set_pt_time(self):
        """
        设置各节点的时间
        分析不同时间间隔中X坐标数量的占比
        统计结果: 1. 80%~90%的X坐标在15~20毫秒之间
                2. 10%~15%在20~200及以上,其中 [-a, 0, x, ...] 这里x只有一个,取值在110~200之间
                    坐标集最后3~5个坐标取值再50~400之间,最后一个坐标数值最大

        滑动总时间的取值规则: 图片宽度260,去掉滑块的宽度剩下200;
                        如果距离小于100,则耗时1300~1900之间
                        如果距离大于100,则耗时1700~2100之间
        """
        __end_pt_time = []
        __move_pt_time = []
        self.__pos_z = []

        total_move_time = self.__need_time * random.uniform(0.8, 0.9)
        start_point_time = random.uniform(110, 200)
        __start_pt_time = [0, 0, int(start_point_time)]

        sum_move_time = 0

        _tmp_total_move_time = total_move_time
        while True:
            delta_time = random.uniform(15, 20)
            if _tmp_total_move_time < delta_time:
                break

            sum_move_time += delta_time
            _tmp_total_move_time -= delta_time
            __move_pt_time.append(int(start_point_time+sum_move_time))

        last_pt_time = __move_pt_time[-1]
        __move_pt_time.append(last_pt_time+_tmp_total_move_time)

        sum_end_time = start_point_time + total_move_time
        other_point_time = self.__need_time - sum_end_time
        end_first_ptime = other_point_time / 2

        while True:
            delta_time = random.uniform(110, 200)
            if end_first_ptime - delta_time <= 0:
                break

            end_first_ptime -= delta_time
            sum_end_time += delta_time
            __end_pt_time.append(int(sum_end_time))

        __end_pt_time.append(int(sum_end_time + (other_point_time/2 + end_first_ptime)))
        self.__pos_z.extend(__start_pt_time)
        self.__pos_z.extend(__move_pt_time)
        self.__pos_z.extend(__end_pt_time)

    def __set_distance(self, _dist):
        """
        设置要生成的轨迹长度
        """
        self.__distance = _dist

        if _dist < 100:
            self.__need_time = int(random.uniform(500, 1500))
        else:
            self.__need_time = int(random.uniform(1000, 2000))

    def __get_pos_z(self):
        return self.__pos_z

    def __get_pos_y(self):
        _pos_y = [random.uniform(-40, -18), 0]
        point_count = len(self.__pos_z)
        x = np.linspace(-10, 15, point_count - len(_pos_y))
        arct_y = np.arctan(x)

        for _, val in enumerate(arct_y):
            _pos_y.append(val)

        return _pos_y

    def __get_pos_x(self, _distance):
        """
        绘制标准的数学函数图像: 以 tanh 开始 以 arctan 结尾
        根据此模型用等比时间差生成X坐标
        """
        # first_val = random.uniform(-40, -18)
        # _distance += first_val
        _pos_x = [random.uniform(-40, -18), 0]
        self.__set_distance(_distance)
        self.__set_pt_time()

        point_count = len(self.__pos_z)
        x = np.linspace(-1, 19, point_count-len(_pos_x))
        ss = np.arctan(x)
        th = np.tanh(x)

        for idx in range(0, len(th)):
            if th[idx] < ss[idx]:
                th[idx] = ss[idx]

        th += 1
        th *= (_distance / 2.5)

        i = 0
        start_idx = int(point_count/10)
        end_idx = int(point_count/50)
        delta_pt = abs(np.random.normal(scale=1.1, size=point_count-start_idx-end_idx))
        for idx in range(start_idx, point_count):
            if idx*1.3 > len(delta_pt):
                break

            th[idx] += delta_pt[i]
            i+=1

        _pos_x.extend(th)
        return _pos_x[-1], _pos_x

    def get_mouse_pos_path(self, distance):
        """
        获取滑动滑块鼠标的滑动轨迹坐标集合
        """
        result = []
        _distance, x = self.__get_pos_x(distance)
        y = self.__get_pos_y()
        z = self.__get_pos_z()
        for idx in range(len(x)):
            result.append([int(x[idx]), int(y[idx]), int(z[idx])])
        import matplotlib.pyplot as plt
        plt.plot(z,x)
        plt.show()
        return int(_distance), result

我们把数组copy下来,本地画一下图,然后看看是怎样的轨迹。

在这里插入图片描述
基本上都是这样的一个轨迹。我们用那个文章的代码跑一下,然后生成跟g一样的数组,本地生成的数组替换滑块的,看看能不能过,经过我的尝试,是可以的,至于那个移动长度,其实数组的第一个(从第0个开始)的第0个参数,被最后一个数组的第0个减去,然后就是移动距离。


[
    [
        "808",
        "211",
        1626942564294
    ],
    [
        "856",
        "240",
        1626942564294
    ],
    [
        "857",
        "240",
        1626942564406
    ],
    [
        "859",
        "240",
        1626942564413
    ],
    [
        "860",
        "240",
        1626942564421
    ],
    [
        "861",
        "240",
        1626942564437
    ],
    [
        "864",
        "240",
        1626942564445
    ],
    [
        "865",
        "240",
        1626942564453
    ],
    [
        "866",
        "240",
        1626942564461
    ],
    [
        "867",
        "240",
        1626942564469
     ]
]

在这里插入图片描述

通过上图可以看出,g发生了改变,没错,就是我们本地生成的数组。我们接着让它运行,看一下结果。

在这里插入图片描述
下面我们就要看它的加密了,

在这里插入图片描述
在这里插入图片描述

function string10to64(d) {
    var c = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-~".split("")
        , b = c.length
        , e = +d
        , a = [];
    do {
        mod = e % b;
        e = (e - mod) / b;
        a.unshift(c[mod])
    } while (e);
    return a.join("")
}

function prefixInteger(a, b) {
        return (Array(b).join(0) + a).slice(-b)
    }

function pretreatment(d, c, b) {
    var e = string10to64(Math.abs(d));
    var a = "";
    if (!b) {
        a += (d > 0 ? "1" : "0")
    }
    a += prefixInteger(e, c);
    return a
}


function getCoordinate(c) {
    var b = new Array();
    for (var e = 0; e < c.length; e++) {
        if (e == 0) {
            b.push(pretreatment(c[e][0] < 262143 ? c[e][0] : 262143, 3, true));
            b.push(pretreatment(c[e][1] < 16777215 ? c[e][1] : 16777215, 4, true));
            b.push(pretreatment(c[e][2] < 4398046511103 ? c[e][2] : 4398046511103, 7, true))
        } else {
            var a = c[e][0] - c[e - 1][0];
            var f = c[e][1] - c[e - 1][1];
            var d = c[e][2] - c[e - 1][2];
            b.push(pretreatment(a < 4095 ? a : 4095, 2, false));
            b.push(pretreatment(f < 4095 ? f : 4095, 2, false));
            b.push(pretreatment(d < 16777215 ? d : 16777215, 4, true))
        }
    }
    return b.join("")
}

function slide(array) {
    g = array
    return getCoordinate(g)

}

最终成品代码图:

在这里插入图片描述

ps: 京东这个滑块的加密不难,难点主要在于轨迹这块,控制时长,坐标识别,都是比较关键的点。


Ending

如有权益问题可以发私信联系我删除

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

敏捷测试自动化

目录 前言&#xff1a; 敏捷宣言 敏捷软件开发VS传统方法 敏捷云服务 对什么进行自动化&#xff1f; 测试自动化的技巧 关于敏捷测试和自动化测试的关键信息 前言&#xff1a; 敏捷测试自动化是在敏捷开发环境中使用自动化工具和技术来支持测试活动的一种方法。它旨在提…

SQL使用(一):如何使用SQL语句去查询第二高的值

今天刷MYSQL题的时候刷到这样一个题&#xff1a; 编写一个 SQL 查询&#xff0c;获取 Employee 表中第二高的薪水&#xff08;Salary&#xff09; 。------------| Id | Salary |------------| 1 | 100 || 2 | 200 || 3 | 300 |------------例如上述 Employee 表&a…

时间序列预测 | Matlab自回归差分移动平均模型ARIMA时间序列预测,可实现多步预测,对未来的数据实现预测

文章目录 效果一览文章概述部分源码参考资料效果一览 文章概述 时间序列预测 | Matlab自回归差分移动平均模型ARIMA时间序列预测,可实现多步预测,对未来的数据实现预测 评价指标包括:MAE、RMSE和R2等,代码质量极高,方便学习和替换数据。要求2018版本及以上。 部分源码 %% …

C语言比较容易出错的printf语句/cout语句

请问以下代码的输出结果是什么&#xff1f; int main() {int n 2;//cout << n << n << n--;printf("%d %d %d", n, n, n--);system("pause");return 0; } 结果&#xff1a; 很奇怪&#xff1f; 为什么会这样&#xff1f; 原来自己之…

MOVEit再现新漏洞,多个版本受影响

今年6月&#xff0c;文件共享工具MOVEit Transfer曾曝出SQL 注入漏洞&#xff0c;能让远程攻击者访问其数据库并执行任意代码。最近&#xff0c;MOVEit Transfer 母公司Progress Software又披露了三个新漏洞。 这三个漏洞分别是 CVE-2023-36932、CVE-2023-36933 和 CVE-2023-36…

【ACL 2023】具有高效推理速度的中文领域文图生成扩散模型和工具链

近日&#xff0c;阿里云机器学习平台PAI与华南理工大学合作&#xff08;阿里云与华南理工大学联合培养项目&#xff09;在自然语言处理顶级会议ACL2023上发表了具有高效推理速度的中文领域文图生成扩散模型和工具链Rapid Diffusion。它是面向中文特定领域的文图生成模型&#x…

了解MQL4,轻松自定义外汇交易收益曲线

外汇交易是现代社会中增长最快的交易形式之一&#xff0c;而MQL4编程语言是一种针对外汇交易的编程语言。熟练使用MQL4编程语言可以帮助交易者轻松自定义外汇交易收益曲线。本文将介绍什么是MQL4&#xff0c;以及如何使用MQL4来自定义外汇交易收益曲线。 一、什么是MQL4 MQL4…

MyBatis 中的 SQL 映射文件如何配置参数映射,如何使用

MyBatis 中的 SQL 映射文件如何配置参数映射&#xff0c;如何使用 MyBatis 是一种开源的 Java 持久化框架&#xff0c;它可以自动将数据库中的数据映射到 Java 对象中&#xff0c;并且使得 Java 对象可以非常方便地存储到数据库中。在 MyBatis 中&#xff0c;SQL 映射文件是一…

Tomcat之安装与项目部署

Tomcat是一个免费、开源的javaWeb轻量级应用服务器 优于是使用Java开发的&#xff0c;需要运行在java虚拟机中&#xff0c;所以必须安装jdk&#xff0c;以提供运行环境。 Tomcat可以看做一个http服务器&#xff0c;通过组件Connector接收http请求并解析&#xff0c;然后把结果…

Xmake v2.8.1 发布,大量细节特性改进

Xmake 是一个基于 Lua 的轻量级跨平台构建工具。 它非常的轻量&#xff0c;没有任何依赖&#xff0c;因为它内置了 Lua 运行时。 它使用 xmake.lua 维护项目构建&#xff0c;相比 makefile/CMakeLists.txt&#xff0c;配置语法更加简洁直观&#xff0c;对新手非常友好&#x…

hbuilderX 的使用

1 创建nui-app 点击左上角的文件点击新建-》项目&#xff0c;将信息填写完整点击确定 2 uni-modules 插件管理 通过 uni-app 插件市场 实现 uni-modules的插件安装&#xff0c;在插件市场搜索对应的插件名称&#xff0c;点击进去&#xff0c;点使用Hbuild’erX导入插件。详细…

Java 动态规划 64. 最小路径和

代码展示&#xff1a; dp[i][j]Math.min(dp[i-1][j],dp[i][j-1])grid[i-1][j-1]; 该题可以通过动态规划解决&#xff0c;动态规划的题根据以下的5大步骤便可轻松解决 1.状态表示 题目要求我们计算从起点到最后一个位置的最小路径和&#xff0c;我们可以创建一个dp表&#xff0c…

算法笔记: 相似性度量

1 欧氏距离 1.1 标准化欧氏距离 先将数据标准化 &#xff08;减去的均值两两抵消&#xff09; 2 曼哈顿距离 又称为城市街区距离 3 切比雪夫距离 等价形式 4 闵可夫斯基距离 minkowski 当p1时&#xff0c;就是曼哈顿距离 当p2时&#xff0c;就是欧氏距离 当p→∞时&#xf…

WSL安装与使用(Ubuntu22.04)

文章目录 概要WSL介绍WSL安装安装环境安装方式一&#xff1a;命令行安装(不推荐&#xff0c;可能出现奇怪的问题)安装方式二&#xff1a;通过控制面板安装 WSL 安装Ubuntu22.04&#xff08;通过Microsoft Store&#xff09;Ubuntu更换镜像源进入Ubuntu更换镜像源 Ubuntu安装Doc…

Spark-用IDEA编写wordcount demo

配置 Spark版本&#xff1a;3.2.0 Scala版本&#xff1a;2.12.12 JDK&#xff1a;1.8 Maven&#xff1a;3.6.3 pom文件 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi&quo…

小红书笔记为什么没有流量,归纳总结

我们都知道小红书是一个内容分享类平台。小红书笔记是平台的主要内容形式。但有时候&#xff0c;我们撰写了一篇笔记&#xff0c;却无法搜索到&#xff0c;今天为大家分享下小红书笔记为什么没有流量&#xff0c;归纳总结&#xff01; 一、小红书笔记不被收录的原因 当我们精心…

Java 递归和非递归方式实现二叉树的前、中、后序遍历

文章目录 Node结点定义前序遍历递归方式实现非递归方式实现图文解读 最终结果 中序遍历递归方式实现非递归方式实现图文解读 最终结果 后序遍历递归方式实现非递归方式实现图文解读 最终结果 结语 Node结点定义 private static class Node {public int value;public Node left;…

Vue子组件向父组件传递消息

父子组件之间的通信&#xff1a;props与emit 通常提到props&#xff0c;都会想到的是父组件给子组件传值&#xff1b;提到emit为子组件向父组件发送消息&#xff0c;但其实&#xff0c;props也可以使子组件向父组件传递消息 方式为在父组件中通过为子组件绑定属性&#xff0c…

Docker之centos7环境离线安装

一、docker简介 Docker是一个开源的应用容器引擎&#xff0c;可以让开发者将应用及其依赖打包在一个虚拟的容器中&#xff0c;方便地部署、移植、升级和管理。Docker可以运行在Linux、Windows和MacOS等操作系统上&#xff0c;并且可以在不同的平台之间进行交互和迁移。Docker的…

ES 性能调优,这可能是全网最详细的 Elasticsearch 性能调优指南

文章目录 1、通用优化策略1.1 通用最小化法则1.2 职责单一原则1.3 其他 2、写性能调优2.1 基本原则2.2 优化手段2.2.1 增加 flush 时间间隔&#xff0c;2.2.2 增加refresh_interval的参数值2.2.3 增加Buffer大小&#xff0c;2.2.4 关闭副本2.2.5 禁用swap2.2.6 使用多个工作线程…