JS逆向学习(小白级别)-犀牛数据的获取

前言

        (所有脚本仅供学习交流使用,请勿用于商业用途和非法用途,如作他用所造成的一切后果和法律责任一概与本人无关,如有侵权请联系我删除)

案例

        今天给大家分享一个爬虫学习案例,烯*数据的最新赛道中的数据,话不多说直接上图。

        如图所示,我们想要获取最新赛道的名称,数量,最近获投,和最近更新的数据,正常打开f12观察请求参数如图所示。

参数

 我们可以发现页面用的是动态加载的,向下滑动会有一直有新数据,并且请求负载的payload和sig都进行了加密,参数v是一个定值,加密参数一般在js文件中进行的加密,那么我们如何确定加密函数的位置呢?

寻找加密函数的位置

        1. 通过搜索关键字进行查找

                常见的加密方式一般是对称加密(AES 加密)和非对称加密(RSA 加密),因此我们

可以搜索encryptdecrypt,AES,Crypto,RSA,hash,signature,jsencrypt....等常见的关键字。

                像本文的案例参数进行了加密,我们还可以自己搜索加密的参数的名称来快速进行定位。(本案例主要用第二种,第一种以后更新)

        2. 通过XHR/提取断点

                像本文中的案例可以将请求url添加提取断点,每当运行到这个url就会断点在这里,具体操作如下图所示。

 

               添加后刷新一下页面就可以发现神奇的现象。

                可以看见在右侧中有f 和 p 刚好对应的是加密的参数,我们直接加断点进行断点调试,向下运行两步具体如下。

                我们发现f和p经过了这两行代码就已经加密成功了,那么具体加密操作就是这两行代码,那么我们就开始进行愉快的补环境吧。

                 复制这两行代码到Visual Studio Code(个人喜欢用这个)中进行补环境,具体怎么配置见:node.js的环境安装

                先解决参数的加密,在控制台打印一下s.payload可以发现是一个字典如下:{ "sort":1,"start":20,"limit": 20}先按照一个常量进行处理直接写死,JSON.stringify函数是将字典变为标准的json格式可以不要,然后就可以发现有用的函数就是Object(u.d)和Object(u.c),我们打印一下看看函数如下。

                发现 Object(u.c)其实是e2和e1函数,直接拿到Visual Studio Code中运行,然后缺少什么函数就在控制台打印然后扣下来补上,_keyStr和_p都是定值可以在js代码中找到,具体如下

                到此为止参数已经获取到了,咱们回头看一下{ "sort":1,"start":20,"limit": 20}这个字典,其中sort是排序方式默认1为正序不用管,limit为每次返回的20条数据,start为0表示第一页数据,start为20为第二页数据,以此类推。

                接下来打开pycharm进行操作,需要在终端安装一下pip install PyExecJS2  ,然后在插件中搜索node.js下载,重启pycharm(我用的专业版2020的)

                 运行完发现结果也是加密的也就是那个d,具体方法和上面一样,就检验一下你们的学习能力了(偷笑)。上代码了

 破解参数代码

        


const CryptoJS = require('crypto-js');
var _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
, _p = "W5D80NFZHAYB8EUI2T649RT2MNRMVE2O";
function e2(e) {
    if (null == (e = _u_e(e)))
        return null;
    for (var t = "", n = 0; n < e.length; n++) {
        var r = _p.charCodeAt(n % _p.length);
        t += String.fromCharCode(e.charCodeAt(n) ^ r)
    }
    return t
}
function _u_e(e) {
    if (null == e)
        return null;
    e = e.replace(/\r\n/g, "\n");
    for (var t = "", n = 0; n < e.length; n++) {
        var r = e.charCodeAt(n);
        r < 128 ? t += String.fromCharCode(r) : r > 127 && r < 2048 ? (t += String.fromCharCode(r >> 6 | 192),
        t += String.fromCharCode(63 & r | 128)) : (t += String.fromCharCode(r >> 12 | 224),
        t += String.fromCharCode(r >> 6 & 63 | 128),
        t += String.fromCharCode(63 & r | 128))
    }
    return t
}
function e1(e) {
    if (null == e)
        return null;
    for (var t, n, r, o, i, a, u, c = "", l = 0; l < e.length; )
        o = (t = e.charCodeAt(l++)) >> 2,
        i = (3 & t) << 4 | (n = e.charCodeAt(l++)) >> 4,
        a = (15 & n) << 2 | (r = e.charCodeAt(l++)) >> 6,
        u = 63 & r,
        isNaN(n) ? a = u = 64 : isNaN(r) && (u = 64),
        c = c + _keyStr.charAt(o) + _keyStr.charAt(i) + _keyStr.charAt(a) + _keyStr.charAt(u);
    return c
}

function sig(e) {
    return CryptoJS.MD5(e + _p).toString().toUpperCase()
}

function xxxx(hu){
    var f = e1(e2(JSON.stringify(hu)))
    var p = sig(f);

    return [f,p]
    

}
hu = {
    "sort": 2,
    "start": 20,
    "limit": 20
}
console.log(xxxx(hu));


结果加密代码




function _u_d(e) {
    for (var t = "", n = 0, r = 0, o = 0, i = 0; n < e.length; )
        (r = e.charCodeAt(n)) < 128 ? (t += String.fromCharCode(r),
        n++) : r > 191 && r < 224 ? (o = e.charCodeAt(n + 1),
        t += String.fromCharCode((31 & r) << 6 | 63 & o),
        n += 2) : (o = e.charCodeAt(n + 1),
        i = e.charCodeAt(n + 2),
        t += String.fromCharCode((15 & r) << 12 | (63 & o) << 6 | 63 & i),
        n += 3);
    return t
}
function d1(e) {
    var t, n, r, o, i, a, u = "", c = 0;
    for (e = e.replace(/[^A-Za-z0-9\+\/\=]/g, ""); c < e.length; )
        t = _keyStr.indexOf(e.charAt(c++)) << 2 | (o = _keyStr.indexOf(e.charAt(c++))) >> 4,
        n = (15 & o) << 4 | (i = _keyStr.indexOf(e.charAt(c++))) >> 2,
        r = (3 & i) << 6 | (a = _keyStr.indexOf(e.charAt(c++))),
        u += String.fromCharCode(t),
        64 != i && (u += String.fromCharCode(n)),
        64 != a && (u += String.fromCharCode(r));
    return u
}
function d2(e) {
    for (var t = "", n = 0; n < e.length; n++) {
        var r = _p.charCodeAt(n % _p.length);
        t += String.fromCharCode(e.charCodeAt(n) ^ r)
    }
    return t = _u_d(t)
}
const CryptoJS = require('crypto-js');
var _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
, _p = "W5D80NFZHAYB8EUI2T649RT2MNRMVE2O";
function hanshu(s){

    var d = d1(s)
    , y = d2(d)
    , m = JSON.parse(y);

    return m

}
s = '请求到的那一大堆字符串'
console.log(hanshu(s));

python代码

import requests
import json
import execjs

hu = {
    "sort": 1,
    "start": 20,
    "limit": 40
}
with open("烯牛数据.js", "r", encoding="utf-8") as f:
    js_code = f.read()
    js_evn = execjs.compile(js_code)
    result = js_evn.call('xxxx', hu)  # execjs.compile用于执行更复杂的js代码
    print(result)



headers = {
    "accept": "application/json",
    "accept-language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6",
    "cache-control": "no-cache",
    "content-type": "application/json",
    "origin": "https://www.xiniudata.com",
    "pragma": "no-cache",
    "priority": "u=1, i",
    "referer": "https://www.xiniudata.com/industry/newest?from=data",
    "sec-ch-ua": "\"Not)A;Brand\";v=\"99\", \"Microsoft Edge\";v=\"127\", \"Chromium\";v=\"127\"",
    "sec-ch-ua-mobile": "?0",
    "sec-ch-ua-platform": "\"Windows\"",
    "sec-fetch-dest": "empty",
    "sec-fetch-mode": "cors",
    "sec-fetch-site": "same-origin",
    "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36 Edg/127.0.0.0"
}

url = "https://www.xiniudata.com/api2/service/x_service/person_industry_list/list_industries_by_sort"
data = {
    "payload": result[0],
    "sig": result[1],
    "v": 1
}
data = json.dumps(data)
response = requests.post(url, headers=headers, data=data)

json_str = json.loads(response.text)
s = json_str['d']

with open("烯牛数据2.js", "r", encoding="utf-8") as f:
    js_code1 = f.read()
    js_evn1 = execjs.compile(js_code1)
    result1 = js_evn1.call('hanshu', s)  # execjs.compile用于执行更复杂的js代码
    print(result1)

说明

         有问题留言,我每天上班必回的哦,给个结果图

  • 10
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值