Python逆向爬蟲入門教程: 千千音樂加密引數 sign 逆向解析

轻松学Python發表於2024-03-28

資料來源分析💥

網站連結: aHR0cHM6Ly9tdXNpYy45MXEuY29tLw==

音樂資料包分析💥

  1. 正常流程抓包分析資料, 找到音訊連結

  2. 找到歌曲對應的資料包位置



  3. 找到 sign 加密位置



看到這裡 MD5 又是 32位的 感覺是是正常的md5加密, 其實他不是的, 可以找一個MD5線上加密的測試一下, 發現好像不是, 那就只能去扣程式碼了, 這個程式碼還挺好扣的

JS程式碼💥

var commonjsGlobal = "undefined" != typeof globalThis ? globalThis : "undefined" != typeof window ? window : void 0 !== global ? global : "undefined" != typeof self ? self : {};

function createCommonjsModule(e, t) {
    return e(t = {
        exports: {}
    }, t.exports),
        t.exports
}

var md5 = createCommonjsModule((function (module) {
        !function () {
            var ERROR = "input is invalid type"
                , WINDOW = "object" == typeof window
                , root = WINDOW ? window : {};
            root.JS_MD5_NO_WINDOW && (WINDOW = !1);
            var WEB_WORKER = !WINDOW && "object" == typeof self
                ,
                NODE_JS = !root.JS_MD5_NO_NODE_JS && "object" == typeof process && process.versions && process.versions.node;
            NODE_JS ? root = commonjsGlobal : WEB_WORKER && (root = self);
            var COMMON_JS = !root.JS_MD5_NO_COMMON_JS && module.exports,
                ARRAY_BUFFER = !root.JS_MD5_NO_ARRAY_BUFFER && "undefined" != typeof ArrayBuffer,
                HEX_CHARS = "0123456789abcdef".split(""), EXTRA = [128, 32768, 8388608, -2147483648],
                SHIFT = [0, 8, 16, 24], OUTPUT_TYPES = ["hex", "array", "digest", "buffer", "arrayBuffer", "base64"],
                BASE64_ENCODE_CHAR = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".split(""),
                blocks = [], buffer8, buffer, buffer8, blocks;
            ARRAY_BUFFER && (buffer = new ArrayBuffer(68),
                buffer8 = new Uint8Array(buffer),
                blocks = new Uint32Array(buffer)),
            !root.JS_MD5_NO_NODE_JS && Array.isArray || (Array.isArray = function (e) {
                    return "[object Array]" === Object.prototype.toString.call(e)
                }
            ),
            !ARRAY_BUFFER || !root.JS_MD5_NO_ARRAY_BUFFER_IS_VIEW && ArrayBuffer.isView || (ArrayBuffer.isView = function (e) {
                    return "object" == typeof e && e.buffer && e.buffer.constructor === ArrayBuffer
                }
            );
            var createOutputMethod = function (e) {
                return function (t) {
                    return new Md5(!0).update(t)[e]()
                }
            }
                , createMethod = function () {
                var e = createOutputMethod("hex");
                NODE_JS && (e = nodeWrap(e)),
                    e.create = function () {
                        return new Md5
                    }
                    ,
                    e.update = function (t) {
                        return e.create().update(t)
                    }
                ;
                for (var t = 0; t < OUTPUT_TYPES.length; ++t) {
                    var n = OUTPUT_TYPES[t];
                    e[n] = createOutputMethod(n)
                }
                return e
            }
                , nodeWrap = function (method) {
                var crypto = eval("require('crypto')")
                    , Buffer = eval("require('buffer').Buffer")
                    , nodeMethod = function (e) {
                    if ("string" == typeof e)
                        return crypto.createHash("md5").update(e, "utf8").digest("hex");
                    if (null == e)
                        throw ERROR;
                    return e.constructor === ArrayBuffer && (e = new Uint8Array(e)),
                        Array.isArray(e) || ArrayBuffer.isView(e) || e.constructor === Buffer ? crypto.createHash("md5").update(new Buffer(e)).digest("hex") : method(e)
                };
                return nodeMethod
            };

            function Md5(e) {
                var t;
                e ? (blocks[0] = blocks[16] = blocks[1] = blocks[2] = blocks[3] = blocks[4] = blocks[5] = blocks[6] = blocks[7] = blocks[8] = blocks[9] = blocks[10] = blocks[11] = blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0,
                    this.blocks = blocks,
                    this.buffer8 = buffer8) : ARRAY_BUFFER ? (t = new ArrayBuffer(68),
                    this.buffer8 = new Uint8Array(t),
                    this.blocks = new Uint32Array(t)) : this.blocks = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                    this.h0 = this.h1 = this.h2 = this.h3 = this.start = this.bytes = this.hBytes = 0,
                    this.finalized = this.hashed = !1,
                    this.first = !0
            }

            Md5.prototype.update = function (e) {
                if (!this.finalized) {
                    var t, n = typeof e;
                    if ("string" != n) {
                        if ("object" != n)
                            throw ERROR;
                        if (null === e)
                            throw ERROR;
                        if (ARRAY_BUFFER && e.constructor === ArrayBuffer)
                            e = new Uint8Array(e);
                        else if (!(Array.isArray(e) || ARRAY_BUFFER && ArrayBuffer.isView(e)))
                            throw ERROR;
                        t = !0
                    }
                    for (var r, i, s = 0, o = e.length, a = this.blocks, u = this.buffer8; s < o;) {
                        if (this.hashed && (this.hashed = !1,
                            a[0] = a[16],
                            a[16] = a[1] = a[2] = a[3] = a[4] = a[5] = a[6] = a[7] = a[8] = a[9] = a[10] = a[11] = a[12] = a[13] = a[14] = a[15] = 0),
                            t)
                            if (ARRAY_BUFFER)
                                for (i = this.start; s < o && i < 64; ++s)
                                    u[i++] = e[s];
                            else
                                for (i = this.start; s < o && i < 64; ++s)
                                    a[i >> 2] |= e[s] << SHIFT[3 & i++];
                        else if (ARRAY_BUFFER)
                            for (i = this.start; s < o && i < 64; ++s)
                                (r = e.charCodeAt(s)) < 128 ? u[i++] = r : (r < 2048 ? u[i++] = 192 | r >> 6 : (r < 55296 || 57344 <= r ? u[i++] = 224 | r >> 12 : (r = 65536 + ((1023 & r) << 10 | 1023 & e.charCodeAt(++s)),
                                    u[i++] = 240 | r >> 18,
                                    u[i++] = 128 | r >> 12 & 63),
                                    u[i++] = 128 | r >> 6 & 63),
                                    u[i++] = 128 | 63 & r);
                        else
                            for (i = this.start; s < o && i < 64; ++s)
                                (r = e.charCodeAt(s)) < 128 ? a[i >> 2] |= r << SHIFT[3 & i++] : (r < 2048 ? a[i >> 2] |= (192 | r >> 6) << SHIFT[3 & i++] : (r < 55296 || 57344 <= r ? a[i >> 2] |= (224 | r >> 12) << SHIFT[3 & i++] : (r = 65536 + ((1023 & r) << 10 | 1023 & e.charCodeAt(++s)),
                                    a[i >> 2] |= (240 | r >> 18) << SHIFT[3 & i++],
                                    a[i >> 2] |= (128 | r >> 12 & 63) << SHIFT[3 & i++]),
                                    a[i >> 2] |= (128 | r >> 6 & 63) << SHIFT[3 & i++]),
                                    a[i >> 2] |= (128 | 63 & r) << SHIFT[3 & i++]);
                        this.lastByteIndex = i,
                            this.bytes += i - this.start,
                            64 <= i ? (this.start = i - 64,
                                this.hash(),
                                this.hashed = !0) : this.start = i
                    }
                    return 4294967295 < this.bytes && (this.hBytes += this.bytes / 4294967296 << 0,
                        this.bytes = this.bytes % 4294967296),
                        this
                }
            }
                ,
                Md5.prototype.finalize = function () {
                    var e, t;
                    this.finalized || (this.finalized = !0,
                        (e = this.blocks)[(t = this.lastByteIndex) >> 2] |= EXTRA[3 & t],
                    56 <= t && (this.hashed || this.hash(),
                        e[0] = e[16],
                        e[16] = e[1] = e[2] = e[3] = e[4] = e[5] = e[6] = e[7] = e[8] = e[9] = e[10] = e[11] = e[12] = e[13] = e[14] = e[15] = 0),
                        e[14] = this.bytes << 3,
                        e[15] = this.hBytes << 3 | this.bytes >>> 29,
                        this.hash())
                }
                ,
                Md5.prototype.hash = function () {
                    var e, t, n, r, i, s = this.blocks,
                        o = this.first ? ((o = ((e = ((e = s[0] - 680876937) << 7 | e >>> 25) - 271733879 << 0) ^ (t = ((t = (-271733879 ^ (n = ((n = (-1732584194 ^ 2004318071 & e) + s[1] - 117830708) << 12 | n >>> 20) + e << 0) & (-271733879 ^ e)) + s[2] - 1126478375) << 17 | t >>> 15) + n << 0) & (n ^ e)) + s[3] - 1316259209) << 22 | o >>> 10) + t << 0 : (e = this.h0,
                            o = this.h1,
                            t = this.h2,
                        ((o += ((e = ((e += ((n = this.h3) ^ o & (t ^ n)) + s[0] - 680876936) << 7 | e >>> 25) + o << 0) ^ (t = ((t += (o ^ (n = ((n += (t ^ e & (o ^ t)) + s[1] - 389564586) << 12 | n >>> 20) + e << 0) & (e ^ o)) + s[2] + 606105819) << 17 | t >>> 15) + n << 0) & (n ^ e)) + s[3] - 1044525330) << 22 | o >>> 10) + t << 0);
                    o = ((o += ((e = ((e += (n ^ o & (t ^ n)) + s[4] - 176418897) << 7 | e >>> 25) + o << 0) ^ (t = ((t += (o ^ (n = ((n += (t ^ e & (o ^ t)) + s[5] + 1200080426) << 12 | n >>> 20) + e << 0) & (e ^ o)) + s[6] - 1473231341) << 17 | t >>> 15) + n << 0) & (n ^ e)) + s[7] - 45705983) << 22 | o >>> 10) + t << 0,
                        o = ((o += ((e = ((e += (n ^ o & (t ^ n)) + s[8] + 1770035416) << 7 | e >>> 25) + o << 0) ^ (t = ((t += (o ^ (n = ((n += (t ^ e & (o ^ t)) + s[9] - 1958414417) << 12 | n >>> 20) + e << 0) & (e ^ o)) + s[10] - 42063) << 17 | t >>> 15) + n << 0) & (n ^ e)) + s[11] - 1990404162) << 22 | o >>> 10) + t << 0,
                        o = ((o += ((e = ((e += (n ^ o & (t ^ n)) + s[12] + 1804603682) << 7 | e >>> 25) + o << 0) ^ (t = ((t += (o ^ (n = ((n += (t ^ e & (o ^ t)) + s[13] - 40341101) << 12 | n >>> 20) + e << 0) & (e ^ o)) + s[14] - 1502002290) << 17 | t >>> 15) + n << 0) & (n ^ e)) + s[15] + 1236535329) << 22 | o >>> 10) + t << 0,
                        o = ((o += ((n = ((n += (o ^ t & ((e = ((e += (t ^ n & (o ^ t)) + s[1] - 165796510) << 5 | e >>> 27) + o << 0) ^ o)) + s[6] - 1069501632) << 9 | n >>> 23) + e << 0) ^ e & ((t = ((t += (e ^ o & (n ^ e)) + s[11] + 643717713) << 14 | t >>> 18) + n << 0) ^ n)) + s[0] - 373897302) << 20 | o >>> 12) + t << 0,
                        o = ((o += ((n = ((n += (o ^ t & ((e = ((e += (t ^ n & (o ^ t)) + s[5] - 701558691) << 5 | e >>> 27) + o << 0) ^ o)) + s[10] + 38016083) << 9 | n >>> 23) + e << 0) ^ e & ((t = ((t += (e ^ o & (n ^ e)) + s[15] - 660478335) << 14 | t >>> 18) + n << 0) ^ n)) + s[4] - 405537848) << 20 | o >>> 12) + t << 0,
                        o = ((o += ((n = ((n += (o ^ t & ((e = ((e += (t ^ n & (o ^ t)) + s[9] + 568446438) << 5 | e >>> 27) + o << 0) ^ o)) + s[14] - 1019803690) << 9 | n >>> 23) + e << 0) ^ e & ((t = ((t += (e ^ o & (n ^ e)) + s[3] - 187363961) << 14 | t >>> 18) + n << 0) ^ n)) + s[8] + 1163531501) << 20 | o >>> 12) + t << 0,
                        o = ((o += ((n = ((n += (o ^ t & ((e = ((e += (t ^ n & (o ^ t)) + s[13] - 1444681467) << 5 | e >>> 27) + o << 0) ^ o)) + s[2] - 51403784) << 9 | n >>> 23) + e << 0) ^ e & ((t = ((t += (e ^ o & (n ^ e)) + s[7] + 1735328473) << 14 | t >>> 18) + n << 0) ^ n)) + s[12] - 1926607734) << 20 | o >>> 12) + t << 0,
                        o = ((o += ((i = (n = ((n += ((r = o ^ t) ^ (e = ((e += (r ^ n) + s[5] - 378558) << 4 | e >>> 28) + o << 0)) + s[8] - 2022574463) << 11 | n >>> 21) + e << 0) ^ e) ^ (t = ((t += (i ^ o) + s[11] + 1839030562) << 16 | t >>> 16) + n << 0)) + s[14] - 35309556) << 23 | o >>> 9) + t << 0,
                        o = ((o += ((i = (n = ((n += ((r = o ^ t) ^ (e = ((e += (r ^ n) + s[1] - 1530992060) << 4 | e >>> 28) + o << 0)) + s[4] + 1272893353) << 11 | n >>> 21) + e << 0) ^ e) ^ (t = ((t += (i ^ o) + s[7] - 155497632) << 16 | t >>> 16) + n << 0)) + s[10] - 1094730640) << 23 | o >>> 9) + t << 0,
                        o = ((o += ((i = (n = ((n += ((r = o ^ t) ^ (e = ((e += (r ^ n) + s[13] + 681279174) << 4 | e >>> 28) + o << 0)) + s[0] - 358537222) << 11 | n >>> 21) + e << 0) ^ e) ^ (t = ((t += (i ^ o) + s[3] - 722521979) << 16 | t >>> 16) + n << 0)) + s[6] + 76029189) << 23 | o >>> 9) + t << 0,
                        o = ((o += ((i = (n = ((n += ((r = o ^ t) ^ (e = ((e += (r ^ n) + s[9] - 640364487) << 4 | e >>> 28) + o << 0)) + s[12] - 421815835) << 11 | n >>> 21) + e << 0) ^ e) ^ (t = ((t += (i ^ o) + s[15] + 530742520) << 16 | t >>> 16) + n << 0)) + s[2] - 995338651) << 23 | o >>> 9) + t << 0,
                        o = ((o += ((n = ((n += (o ^ ((e = ((e += (t ^ (o | ~n)) + s[0] - 198630844) << 6 | e >>> 26) + o << 0) | ~t)) + s[7] + 1126891415) << 10 | n >>> 22) + e << 0) ^ ((t = ((t += (e ^ (n | ~o)) + s[14] - 1416354905) << 15 | t >>> 17) + n << 0) | ~e)) + s[5] - 57434055) << 21 | o >>> 11) + t << 0,
                        o = ((o += ((n = ((n += (o ^ ((e = ((e += (t ^ (o | ~n)) + s[12] + 1700485571) << 6 | e >>> 26) + o << 0) | ~t)) + s[3] - 1894986606) << 10 | n >>> 22) + e << 0) ^ ((t = ((t += (e ^ (n | ~o)) + s[10] - 1051523) << 15 | t >>> 17) + n << 0) | ~e)) + s[1] - 2054922799) << 21 | o >>> 11) + t << 0,
                        o = ((o += ((n = ((n += (o ^ ((e = ((e += (t ^ (o | ~n)) + s[8] + 1873313359) << 6 | e >>> 26) + o << 0) | ~t)) + s[15] - 30611744) << 10 | n >>> 22) + e << 0) ^ ((t = ((t += (e ^ (n | ~o)) + s[6] - 1560198380) << 15 | t >>> 17) + n << 0) | ~e)) + s[13] + 1309151649) << 21 | o >>> 11) + t << 0,
                        o = ((o += ((n = ((n += (o ^ ((e = ((e += (t ^ (o | ~n)) + s[4] - 145523070) << 6 | e >>> 26) + o << 0) | ~t)) + s[11] - 1120210379) << 10 | n >>> 22) + e << 0) ^ ((t = ((t += (e ^ (n | ~o)) + s[2] + 718787259) << 15 | t >>> 17) + n << 0) | ~e)) + s[9] - 343485551) << 21 | o >>> 11) + t << 0,
                        this.first ? (this.h0 = e + 1732584193 << 0,
                            this.h1 = o - 271733879 << 0,
                            this.h2 = t - 1732584194 << 0,
                            this.h3 = n + 271733878 << 0,
                            this.first = !1) : (this.h0 = this.h0 + e << 0,
                            this.h1 = this.h1 + o << 0,
                            this.h2 = this.h2 + t << 0,
                            this.h3 = this.h3 + n << 0)
                }
                ,
                Md5.prototype.hex = function () {
                    this.finalize();
                    var e = this.h0
                        , t = this.h1
                        , n = this.h2
                        , r = this.h3;
                    return HEX_CHARS[e >> 4 & 15] + HEX_CHARS[15 & e] + HEX_CHARS[e >> 12 & 15] + HEX_CHARS[e >> 8 & 15] + HEX_CHARS[e >> 20 & 15] + HEX_CHARS[e >> 16 & 15] + HEX_CHARS[e >> 28 & 15] + HEX_CHARS[e >> 24 & 15] + HEX_CHARS[t >> 4 & 15] + HEX_CHARS[15 & t] + HEX_CHARS[t >> 12 & 15] + HEX_CHARS[t >> 8 & 15] + HEX_CHARS[t >> 20 & 15] + HEX_CHARS[t >> 16 & 15] + HEX_CHARS[t >> 28 & 15] + HEX_CHARS[t >> 24 & 15] + HEX_CHARS[n >> 4 & 15] + HEX_CHARS[15 & n] + HEX_CHARS[n >> 12 & 15] + HEX_CHARS[n >> 8 & 15] + HEX_CHARS[n >> 20 & 15] + HEX_CHARS[n >> 16 & 15] + HEX_CHARS[n >> 28 & 15] + HEX_CHARS[n >> 24 & 15] + HEX_CHARS[r >> 4 & 15] + HEX_CHARS[15 & r] + HEX_CHARS[r >> 12 & 15] + HEX_CHARS[r >> 8 & 15] + HEX_CHARS[r >> 20 & 15] + HEX_CHARS[r >> 16 & 15] + HEX_CHARS[r >> 28 & 15] + HEX_CHARS[r >> 24 & 15]
                }
                ,
                Md5.prototype.toString = Md5.prototype.hex,
                Md5.prototype.digest = function () {
                    this.finalize();
                    var e = this.h0
                        , t = this.h1
                        , n = this.h2
                        , r = this.h3;
                    return [255 & e, e >> 8 & 255, e >> 16 & 255, e >> 24 & 255, 255 & t, t >> 8 & 255, t >> 16 & 255, t >> 24 & 255, 255 & n, n >> 8 & 255, n >> 16 & 255, n >> 24 & 255, 255 & r, r >> 8 & 255, r >> 16 & 255, r >> 24 & 255]
                }
                ,
                Md5.prototype.array = Md5.prototype.digest,
                Md5.prototype.arrayBuffer = function () {
                    this.finalize();
                    var e = new ArrayBuffer(16)
                        , t = new Uint32Array(e);
                    return t[0] = this.h0,
                        t[1] = this.h1,
                        t[2] = this.h2,
                        t[3] = this.h3,
                        e
                }
                ,
                Md5.prototype.buffer = Md5.prototype.arrayBuffer,
                Md5.prototype.base64 = function () {
                    for (var e, t, n, r = "", i = this.array(), s = 0; s < 15;)
                        e = i[s++],
                            t = i[s++],
                            n = i[s++],
                            r += BASE64_ENCODE_CHAR[e >>> 2] + BASE64_ENCODE_CHAR[63 & (e << 4 | t >>> 4)] + BASE64_ENCODE_CHAR[63 & (t << 2 | n >>> 6)] + BASE64_ENCODE_CHAR[63 & n];
                    return e = i[s],
                    r + (BASE64_ENCODE_CHAR[e >>> 2] + BASE64_ENCODE_CHAR[e << 4 & 63] + "==")
                }
            ;
            var exports = createMethod();
            COMMON_JS ? module.exports = exports : root.md5 = exports
        }()
    }
))
    , secret = "0b50b02fd0d73a9c4c8c3a781c30845f";

function createSign(e) {
    if ("[object Object]" !== Object.prototype.toString.call(e))
        throw new Error("The parameter of query must be a Object.");
    var t = Math.floor(Date.now() / 1e3);
    Object.assign(e, {
        timestamp: t
    });
    var n = Object.keys(e);
    n.sort();
    for (var r = "", i = 0; i < n.length; i++) {
        var s = n[i];
        r += (0 == i ? "" : "&") + s + "=" + e[s]
    }
    return {
        sign: md5(r += secret),
        timestamp: t,
        md5: md5
    }
}

e = {
    "TSID": "T10049736422",
    "appid": 16073360
}
console.log(createSign(e))

Python實現程式碼💥

import pprint
import requests
import execjs
import time
date_time = int(time.time())
f = open('demo.js', encoding='utf-8').read()
js_code = execjs.compile(f)
link_e = {
    "word": "許嵩",
    "type": 1,
    "pageNo": 3,
    "pageSize": 20,
    "appid": 16073360,
    "timestamp": date_time
}
link_sign = js_code.call('createSign', link_e)
print(link_sign)
link = f'https://music.91q.com/v1/search?sign={link_sign["sign"]}&word=%E8%AE%B8%E5%B5%A9&type=1&pageNo=3&pageSize=20&appid=16073360&timestamp={date_time}'
headers = {
    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36'
}
response = requests.get(url=link, headers=headers)
for index in response.json()['data']['typeTrack']:
    TSID = index['TSID']
    e = {
        "TSID": TSID,
        "appid": 16073360,
        "timestamp": date_time
    }
    sign = js_code.call('createSign', e)['sign']
    url = f'https://music.91q.com/v1/song/tracklink?sign={sign}&appid=16073360&TSID={TSID}&timestamp={date_time}'
    json_data = requests.get(url=url, headers=headers).json()
    pprint.pprint(json_data)
    break
# 文章程式碼不理解,我還錄製了影片進行詳細講解,都放在這個扣裙了 708525271

 


歌曲列表獲取音樂ID同樣也有一個sign加密引數, 加密方式是一樣的, 改一下傳入的引數就可以了

相關文章