Loading... ## 声明 - 仅供技术讨论,不用于任何盈利或者商业目的 - 如有侵权,请发送邮件到博主邮箱,将在收到邮件的第一时间删除相关内容 ## 分析过程 首先下一个 analysis 的 XHR断点,在断下的位置向上查找:  找到函数名,再次以函数名搜索:  直到找到一个请求拦截器,然后进入这个拦截器,查查看拦截器的具体操作:  提一下拦截器,拦截器的话主要是在请求之前由前端对请求的再次操作:  继续看拦截器的代码,似乎是加密的代码:  下断点,继续运行,看一下调试的信息,可以发现生成 analysis 代码就是这里:  所以只需要把这里的代码单独拿出来,就行了,然后把这段代码的几个关键参数找出来,内置到 JS 代码里面,通过外部调用就可以生成 analysis 参数。 主要的关键参数是下图中指定的参数:  以及用到的几个函数,只需要通过这个方法查看一下稍微修改代码就行了,以前几次网站代码的修改都是在这几个地方动手脚 以下是 JS 用的代码: ```javascript 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代码实现: ```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() ``` <hr class="content-copyright" style="margin-top:50px" /><blockquote class="content-copyright" style="font-style:normal"><p class="content-copyright">版权属于:JsOnGmAX</p><p class="content-copyright">本文链接:<a class="content-copyright" href="https://jsong.cn/archives/298.html" target="_blank" >https://jsong.cn/archives/298.html</a></p><p class="content-copyright">博客内容遵循 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 协议 如有侵权 请联系本人删除</p></blockquote> 最后修改:2020 年 07 月 30 日 11 : 15 AM © 允许规范转载 赞赏 如果觉得我的文章对你有用,请随意赞赏 ×Close 赞赏作者 扫一扫支付 支付宝支付 微信支付