声明

  • 仅供技术讨论,不用于任何盈利或者商业目的
  • 如有侵权,请发送邮件到博主邮箱,将在收到邮件的第一时间删除相关内容

分析过程

首先下一个 analysis 的 XHR断点,在断下的位置向上查找:

找到函数名,再次以函数名搜索:

直到找到一个请求拦截器,然后进入这个拦截器,查查看拦截器的具体操作:

提一下拦截器,拦截器的话主要是在请求之前由前端对请求的再次操作:

继续看拦截器的代码,似乎是加密的代码:

下断点,继续运行,看一下调试的信息,可以发现生成 analysis 代码就是这里:

所以只需要把这里的代码单独拿出来,就行了,然后把这段代码的几个关键参数找出来,内置到 JS 代码里面,通过外部调用就可以生成 analysis 参数。

主要的关键参数是下图中指定的参数:

以及用到的几个函数,只需要通过这个方法查看一下稍微修改代码就行了,以前几次网站代码的修改都是在这几个地方动手脚

以下是 JS 用的代码:

l = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "+", "/"]
function n_(t) {
    var n;
    n = f(t.toString(), "binary");
    return u(n)
}
function a(t) {
    return l[t >> 18 & 63] + l[t >> 12 & 63] + l[t >> 6 & 63] + l[63 & t]
}
function s(t, e, n) {
    for (var r, i = [], o = e; o < n; o += 3)
        r = (t[o] << 16 & 16711680) + (t[o + 1] << 8 & 65280) + (255 & t[o + 2]),
            i.push(a(r));
    return i.join("")
}
function u(t) {
    for (var e, n = t.length, r = n % 3, i = "", o = [], a = 16383, u = 0, c = n - r; u < c; u += a)
        o.push(s(t, u, u + a > c ? c : u + a));
    return 1 === r ? (e = t[n - 1],
        i += l[e >> 2],
        i += l[e << 4 & 63],
        i += "==") : 2 === r && (e = (t[n - 2] << 8) + t[n - 1],
        i += l[e >> 10],
        i += l[e >> 4 & 63],
        i += l[e << 2 & 63],
        i += "="),
        o.push(i),
        o.join("")
}
function K(t, e, n, r) {
    for (var i = 0; i < r && !(i + n >= e.length || i >= t.length); ++i)
        e[i + n] = t[i];
    return i
}
function W(t) {
    for (var e = [], n = 0; n < t.length; ++n)
        e.push(255 & t.charCodeAt(n));
    return e
}
function t_(t, e, n, r) {
    return K(W(e), t, 0, r)
}
function f(e, n) {
    var r = e.length;
    t = new Uint8Array(r);
    var i = t_(t, e, n, r);
    return t
}
function v_(n) {
    return n_(encodeURIComponent(n)["replace"](/%([0-9A-F]{2})/g, function (a, n) {
        return String["fromCharCode"]("0x" + n)
    }))
}
function k_(a, n) {
    //n || (n = s()),
    a = a["split"]("");
    for (var t = a["length"], e = n["length"], r = "charCodeAt", i = 0; i < t; i++)
        //a[i] = m_(a[i][r](0) ^ n[(i + 10) % e][r](0));
        a[i] = String["fromCharCode"](a[i][r](0) ^ n[(i + 10) % e][r](0));
    return a["join"]("")
}
function getAnalysis (synct, url, p_str) {
    var g = new Date() - 1000 * synct;
    var e = new Date() - g - 1515125653845;
    var S = 1;
    var palist = [];
     for (var key in p_str) {
        palist.push(p_str[key])
    }
    var mm = palist["sort"]()["join"]("");
    m_0 = v_(mm);
    m_1 = m_0 + "@#" + url.replace("https://api.xxxxx.cn", "");
    m_2 = m_1 + "@#" + e;
    m_3 = m_2 + "@#" + S;
    var b = "00000008d78d46a";
    return v_(k_(m_3, b))
}

以下是python代码实现:

# -*- coding: utf-8 -*-
__version_ = 'python 3.7'
__author__ = 'Json·G'
__date__ = '2020/7/6 15:50'


import requests
import datetime
import execjs

js_xxxxx = """
l = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "+", "/"]
function n_(t) {
    var n;
    n = f(t.toString(), "binary");
    return u(n)
}
function a(t) {
    return l[t >> 18 & 63] + l[t >> 12 & 63] + l[t >> 6 & 63] + l[63 & t]
}
function s(t, e, n) {
    for (var r, i = [], o = e; o < n; o += 3)
        r = (t[o] << 16 & 16711680) + (t[o + 1] << 8 & 65280) + (255 & t[o + 2]),
            i.push(a(r));
    return i.join("")
}
function u(t) {
    for (var e, n = t.length, r = n % 3, i = "", o = [], a = 16383, u = 0, c = n - r; u < c; u += a)
        o.push(s(t, u, u + a > c ? c : u + a));
    return 1 === r ? (e = t[n - 1],
        i += l[e >> 2],
        i += l[e << 4 & 63],
        i += "==") : 2 === r && (e = (t[n - 2] << 8) + t[n - 1],
        i += l[e >> 10],
        i += l[e >> 4 & 63],
        i += l[e << 2 & 63],
        i += "="),
        o.push(i),
        o.join("")
}
function K(t, e, n, r) {
    for (var i = 0; i < r && !(i + n >= e.length || i >= t.length); ++i)
        e[i + n] = t[i];
    return i
}
function W(t) {
    for (var e = [], n = 0; n < t.length; ++n)
        e.push(255 & t.charCodeAt(n));
    return e
}
function t_(t, e, n, r) {
    return K(W(e), t, 0, r)
}
function f(e, n) {
    var r = e.length;
    t = new Uint8Array(r);
    var i = t_(t, e, n, r);
    return t
}
function v_(n) {
    return n_(encodeURIComponent(n)["replace"](/%([0-9A-F]{2})/g, function (a, n) {
        return String["fromCharCode"]("0x" + n)
    }))
}
function k_(a, n) {
    //n || (n = s()),
    a = a["split"]("");
    for (var t = a["length"], e = n["length"], r = "charCodeAt", i = 0; i < t; i++)
        //a[i] = m_(a[i][r](0) ^ n[(i + 10) % e][r](0));
        a[i] = String["fromCharCode"](a[i][r](0) ^ n[(i + 10) % e][r](0));
    return a["join"]("")
}
function getAnalysis (synct, url, p_str) {
    var g = new Date() - 1000 * synct;
    var e = new Date() - g - 1515125653845;
    var S = 1;
    var palist = [];
     for (var key in p_str) {
        palist.push(p_str[key])
    }
    var mm = palist["sort"]()["join"]("");
    m_0 = v_(mm);
    m_1 = m_0 + "@#" + url.replace("https://api.xxxxx.cn", "");
    m_2 = m_1 + "@#" + e;
    m_3 = m_2 + "@#" + S;
    var b = "00000008d78d46a";
    return v_(k_(m_3, b))
}
"""


def handle(params, url_start):
    headers = {
        "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3",
        "Accept-Encoding": "gzip, deflate, br",
        "Accept-Language": "zh-CN,zh;q=0.9",
        "Cache-Control": "max-age=0",
        "Connection": "keep-alive",
        "Host": "www.xxxxx.cn",
        "If-Modified-Since": "Mon, 09 Dec 2019 11:03:14 GMT",
        "If-None-Match": 'W/"5dee29f2 - be2"',
        "Referer": "https://www.xxxxx.cn/",
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36"
    }
    resp = requests.get('https://www.xxxxx.cn/rank', headers=headers)
    t = resp.cookies.get_dict()
    synct = t.get('synct')

    def getanaly(synct, url, params):
        ctx = execjs.compile(js_xxxxx)
        new_pwd = ctx.call("getAnalysis", synct, url, params)
        return new_pwd

    analysis = getanaly(synct, url_start, params)
    headers_sub = {
        "Accept": "application/json, text/plain, */*",
        "Accept-Encoding": "gzip, deflate, br",
        "Accept-Language": "zh-CN,zh;q=0.9",
        "Connection": "keep-alive",
        "Host": "api.xxxxx.cn",
        "Origin": "https://www.xxxxx.cn",
        "Sec-Fetch-Mode": "cors",
        "Sec-Fetch-Site": "same-site",
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36"
    }

    params['analysis'] = analysis
    url = url_start + '?'
    res = requests.get(url=url, headers=headers_sub, params=params)
    return res.json()


url_start = "https://api.xxxxx.cn/rank/index"
time_now = datetime.datetime.now().strftime('%Y-%m-%d')
params = {
    "brand": "free",
    "country": "cn",
    "genre": "5000",
    "device": "iphone",
    "date": str(time_now),
    "is_rank_index": 1
}
params["page"] = 1
json_return = handle(params, url_start)
page = json_return["maxPage"]
for i in range(int(page) - 1):
    params = {
        "brand": "free",
        "country": "cn",
        "genre": "5000",
        "device": "iphone",
        "date": str(time_now),
        "is_rank_index": 1
    }
    params["page"] = i + 2
    json_return = handle(params, url_start)
    print(json_return)
    quit()
最后修改:2020 年 07 月 30 日 11 : 15 AM