js逆向实战(1)-- 某☁️音乐下载

news2025/1/8 0:40:32

下载某云音乐源文件.mp4格式

首先随便点进一首歌,如图所示获取该音乐id,然后点击播放键,打开F12进行查询XHR

由此可知,实际请求网址是

https://music.163.com/weapi/song/enhance/player/url/v1?csrf_token=「你的token」

url需带上token,请求参数有两个:params、encSecKey

返回json里的id就是该音乐id,url就是本次的目标音乐源文件链接

继续查看启动器,查看该路由的调用堆栈信息,找到关键位置打断点,不会找断点的就每个堆栈全部点进去设置断点,然后看哪一个断点结束后url已完成请求的就是关键位置,从下图的文件中可知,核心文件是core_xxxxx.js,可以直接下载到本地方便查看代码。(堆栈执行顺序是由下至上)

第一步,已成功定位到请求路由,e7d.data里已经带有(params、encSecKey),后续就直接会请求了,那么就继续向上一个堆栈找此函数的参数(x7q,e7d)中的e7d是从哪里传的。

PS:请注意,一定要找到我们要找的核心url是否由此断点发出的,由于一些方法会被反复调用,参数值是不一定的。

第二步,上图已封装好了e7d,且参数params、encSecKey已出现,是由window.asrsea产生的,继续查找window.asrsea是哪个方法。

window.asrsea(JSON.stringify(i7b), bsc2x(["流泪", "强"]), bsc2x(RU7N.md), bsc2x(["爱心", "女孩", "惊恐", "大笑"]));

鼠标悬浮该方法后定位至这里,核心就是这个function d,接受4个参数,分别对应上面的4个值。

其中第一个参数i7b是以下参数构成

music_id = XXXXXX
song_data = {
    "ids": f"[{music_id}]",
    "level": "standard",
    "encodeType": "aac",
    "csrf_token": csrf_token
}

第三个参数md是一个固定列表,第二、第四个参数也是一个短列表值。

核心方法已找到,就是function d(),剩下的工作就是把d方法里需要涉及到的所有function全部找出来,比如function b、c,然后继续从b、c里继续递归找方法,这一步工作比较繁琐需要耐心。直至自己用js能把function d给跑通就算成功。

通过js里的方法可知,里面算法还涉及到了加密,需要用到crypto-js库,上网百度搜一下直接下载该库的代码保存本地。

以下是js文件代码:


    var CryptoJS = require('./package/crypto-js.js');

    var bd7W = {};
    var maxDigits,
    ZERO_ARRAY,
    bigZero,
    bigOne,
    dpl10,
    lr10,
    hexatrigesimalToChar,
    hexToChar,
    highBitMasks,
    lowBitMasks,
    biRadixBase = 2,
    biRadixBits = 16,
    bitsPerDigit = biRadixBits,
    biRadix = 65536,
    biHalfRadix = biRadix >>> 1,
    biRadixSquared = biRadix * biRadix,
    maxDigitVal = biRadix - 1,
    maxInteger = 9999999999999998;
    setMaxDigits(20),
    dpl10 = 15,
    lr10 = biFromNumber(1e15),
    hexatrigesimalToChar = new Array("0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "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"),
    hexToChar = new Array("0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"),
    highBitMasks = new Array(0, 32768, 49152, 57344, 61440, 63488, 64512, 65024, 65280, 65408, 65472, 65504, 65520, 65528, 65532, 65534, 65535),
    lowBitMasks = new Array(0, 1, 3, 7, 15, 31, 63, 127, 255, 511, 1023, 2047, 4095, 8191, 16383, 32767, 65535);



    function encryptedString(a, b) {

    for (var f, g, h, i, j, k, l, c = new Array, d = b.length, e = 0; d > e;)
        c[e] = b.charCodeAt(e),
        e++;
    for (; 0 != c.length % a.chunkSize;)
        c[e++] = 0;
    for (f = c.length, g = "", e = 0; f > e; e += a.chunkSize) {
        for (j = new BigInt, h = 0, i = e; i < e + a.chunkSize; ++h)
            j.digits[h] = c[i++],
            j.digits[h] += c[i++] << 8;
        k = a.barrett.powMod(j, a.e),
        l = 16 == a.radix ? biToHex(k) : biToString(k, a.radix),
        g += l + " "
    }
    return g.substring(0, g.length - 1)
}
    function biSubtract(a, b) {
    var c,
        d,
        e,
        f;
    if (a.isNeg != b.isNeg)
        b.isNeg = !b.isNeg,
        c = biAdd(a, b),
        b.isNeg = !b.isNeg;
    else {
        for (c = new BigInt, e = 0, f = 0; f < a.digits.length; ++f)
            d = a.digits[f] - b.digits[f] + e,
            c.digits[f] = 65535 & d,
            c.digits[f] < 0 && (c.digits[f] += biRadix),
            e = 0 - Number(0 > d);
        if (-1 == e) {
            for (e = 0, f = 0; f < a.digits.length; ++f)
                d = 0 - c.digits[f] + e,
                c.digits[f] = 65535 & d,
                c.digits[f] < 0 && (c.digits[f] += biRadix),
                e = 0 - Number(0 > d);
            c.isNeg = !a.isNeg
        } else
            c.isNeg = a.isNeg
    }
    return c
}
    function biCompare(a, b) {
        if (a.isNeg != b.isNeg)
            return 1 - 2 * Number(a.isNeg);
        for (var c = a.digits.length - 1; c >= 0; --c)
            if (a.digits[c] != b.digits[c])
                return a.isNeg ? 1 - 2 * Number(a.digits[c] > b.digits[c]) : 1 - 2 * Number(a.digits[c] < b.digits[c]);
        return 0
    }
    function biMultiplyByRadixPower(a, b) {
        var c = new BigInt;
        return arrayCopy(a.digits, 0, c.digits, b, c.digits.length - b), c
    }
    function arrayCopy(a, b, c, d, e) {
        var g,
            h,
            f = Math.min(b + e, a.length);
        for (g = b, h = d; f > g; ++g, ++h)
            c[h] = a[g]
    }

    function biShiftLeft(a, b) {
        var e,
            f,
            g,
            h,
            c = Math.floor(b / bitsPerDigit),
            d = new BigInt;
        for (arrayCopy(a.digits, 0, d.digits, c, d.digits.length - c), e = b % bitsPerDigit, f = bitsPerDigit - e, g = d.digits.length - 1, h = g - 1; g > 0; --g, --h)
            d.digits[g] = d.digits[g] << e & maxDigitVal | (d.digits[h] & highBitMasks[e]) >>> f;
        return d.digits[0] = d.digits[g] << e & maxDigitVal, d.isNeg = a.isNeg, d
    }
    function biFromNumber(a) {
        var c,
            b = new BigInt;
        for (b.isNeg = 0 > a, a = Math.abs(a), c = 0; a > 0;)
            b.digits[c++] = a & maxDigitVal,
            a >>= biRadixBits;
        return b
    }

    function biNumBits(a) {
        var e,
            b = biHighIndex(a),
            c = a.digits[b],
            d = (b + 1) * bitsPerDigit;
        for (e = d; e > d - bitsPerDigit && 0 == (32768 & c); --e)
            c <<= 1;
        return e
    }

    function biDivideModulo(a, b) {
        var f,
            g,
            h,
            i,
            j,
            k,
            l,
            m,
            n,
            o,
            p,
            q,
            r,
            s,
            c = biNumBits(a),
            d = biNumBits(b),
            e = b.isNeg;
        if (d > c)
            return a.isNeg ? (f = biCopy(bigOne), f.isNeg = !b.isNeg, a.isNeg = !1, b.isNeg = !1, g = biSubtract(b, a), a.isNeg = !0, b.isNeg = e) : (f = new BigInt, g = biCopy(a)), new Array(f, g);
        for (f = new BigInt, g = a, h = Math.ceil(d / bitsPerDigit) - 1, i = 0; b.digits[h] < biHalfRadix;)
            b = biShiftLeft(b, 1),
            ++i,
            ++d,
            h = Math.ceil(d / bitsPerDigit) - 1;
        for (g = biShiftLeft(g, i), c += i, j = Math.ceil(c / bitsPerDigit) - 1, k = biMultiplyByRadixPower(b, j - h); -1 != biCompare(g, k);)
            ++f.digits[j - h],
            g = biSubtract(g, k);
        for (l = j; l > h; --l) {
            for (m = l >= g.digits.length ? 0 : g.digits[l], n = l - 1 >= g.digits.length ? 0 : g.digits[l - 1], o = l - 2 >= g.digits.length ? 0 : g.digits[l - 2], p = h >= b.digits.length ? 0 : b.digits[h], q = h - 1 >= b.digits.length ? 0 : b.digits[h - 1], f.digits[l - h - 1] = m == p ? maxDigitVal : Math.floor((m * biRadix + n) / p), r = f.digits[l - h - 1] * (p * biRadix + q), s = m * biRadixSquared + (n * biRadix + o); r > s;)
                --f.digits[l - h - 1],
                r = f.digits[l - h - 1] * (p * biRadix | q),
                s = m * biRadix * biRadix + (n * biRadix + o);
            k = biMultiplyByRadixPower(b, l - h - 1),
            g = biSubtract(g, biMultiplyDigit(k, f.digits[l - h - 1])),
            g.isNeg && (g = biAdd(g, k), --f.digits[l - h - 1])
        }
        return g = biShiftRight(g, i), f.isNeg = a.isNeg != e, a.isNeg && (f = e ? biAdd(f, bigOne) : biSubtract(f, bigOne), b = biShiftRight(b, i), g = biSubtract(b, g)), 0 == g.digits[0] && 0 == biHighIndex(g) && (g.isNeg = !1), new Array(f, g)
    }
    function BarrettMu_modulo(a) {
        var i,
            b = biDivideByRadixPower(a, this.k - 1),
            c = biMultiply(b, this.mu),
            d = biDivideByRadixPower(c, this.k + 1),
            e = biModuloByRadixPower(a, this.k + 1),
            f = biMultiply(d, this.modulus),
            g = biModuloByRadixPower(f, this.k + 1),
            h = biSubtract(e, g);
        for (h.isNeg && (h = biAdd(h, this.bkplus1)), i = biCompare(h, this.modulus) >= 0; i;)
            h = biSubtract(h, this.modulus),
            i = biCompare(h, this.modulus) >= 0;
        return h
    }
    function BarrettMu_multiplyMod(a, b) {
        var c = biMultiply(a, b);
        return this.modulo(c)
    }
    function biDivideByRadixPower(a, b) {
        var c = new BigInt;
        return arrayCopy(a.digits, b, c.digits, 0, c.digits.length - b), c
    }
    function reverseStr(a) {
        var c,
            b = "";
        for (c = a.length - 1; c > -1; --c)
            b += a.charAt(c);
        return b
    }
    function digitToHex(a) {
        var b = 15,
            c = "";
        for (i = 0; 4 > i; ++i)
            c += hexToChar[a & b],
            a >>>= 4;
        return reverseStr(c)
    }
    function biToHex(a) {
        var d,
            b = "";
        for (biHighIndex(a), d = biHighIndex(a); d > -1; --d)
            b += digitToHex(a.digits[d]);
        return b
    }
    function biModuloByRadixPower(a, b) {
        var c = new BigInt;
        return arrayCopy(a.digits, 0, c.digits, 0, b), c
    }
    function biCompare(a, b) {
        if (a.isNeg != b.isNeg)
            return 1 - 2 * Number(a.isNeg);
        for (var c = a.digits.length - 1; c >= 0; --c)
            if (a.digits[c] != b.digits[c])
                return a.isNeg ? 1 - 2 * Number(a.digits[c] > b.digits[c]) : 1 - 2 * Number(a.digits[c] < b.digits[c]);
        return 0
    }
    function biMultiply(a, b) {
        var d,
            h,
            i,
            k,
            c = new BigInt,
            e = biHighIndex(a),
            f = biHighIndex(b);
        for (k = 0; f >= k; ++k) {
            for (d = 0, i = k, j = 0; e >= j; ++j, ++i)
                h = c.digits[i] + a.digits[j] * b.digits[k] + d,
                c.digits[i] = h & maxDigitVal,
                d = h >>> biRadixBits;
            c.digits[k + e + 1] = d
        }
        return c.isNeg = a.isNeg != b.isNeg, c
    }
    function BarrettMu_powMod(a, b) {
        var d,
            e,
            c = new BigInt;
        for (c.digits[0] = 1, d = a, e = b;;) {
            if (0 != (1 & e.digits[0]) && (c = this.multiplyMod(c, d)), e = biShiftRight(e, 1), 0 == e.digits[0] && 0 == biHighIndex(e))
                break;
            d = this.multiplyMod(d, d)
        }
        return c
    }
    function biShiftRight(a, b) {
        var e,
            f,
            g,
            h,
            c = Math.floor(b / bitsPerDigit),
            d = new BigInt;
        for (arrayCopy(a.digits, c, d.digits, 0, a.digits.length - c), e = b % bitsPerDigit, f = bitsPerDigit - e, g = 0, h = g + 1; g < d.digits.length - 1; ++g, ++h)
            d.digits[g] = d.digits[g] >>> e | (d.digits[h] & lowBitMasks[e]) << f;
        return d.digits[d.digits.length - 1] >>>= e, d.isNeg = a.isNeg, d
    }
    function biMultiplyDigit(a, b) {
        var c,
            d,
            e,
            f;
        for (result = new BigInt, c = biHighIndex(a), d = 0, f = 0; c >= f; ++f)
            e = result.digits[f] + a.digits[f] * b + d,
            result.digits[f] = e & maxDigitVal,
            d = e >>> biRadixBits;
        return result.digits[1 + c] = d, result
    }
    function biDivide(a, b) {
        return biDivideModulo(a, b)[0]
    }
    function biCopy(a) {
        var b = new BigInt(!0);
        return b.digits = a.digits.slice(0), b.isNeg = a.isNeg, b
    }
    function BarrettMu(a) {
        this.modulus = biCopy(a),
        this.k = biHighIndex(this.modulus) + 1;
        var b = new BigInt;
        b.digits[2 * this.k] = 1,
        this.mu = biDivide(b, this.modulus),
        this.bkplus1 = new BigInt,
        this.bkplus1.digits[this.k + 1] = 1,
        this.modulo = BarrettMu_modulo,
        this.multiplyMod = BarrettMu_multiplyMod,
        this.powMod = BarrettMu_powMod
    }

    function BigInt(a) {
        this.digits = "boolean" == typeof a && 1 == a ? null : ZERO_ARRAY.slice(0),
        this.isNeg = !1
    }
    function charToHex(a) {
        var h,
            b = 48,
            c = b + 9,
            d = 97,
            e = d + 25,
            f = 65,
            g = 90;
        return h = a >= b && c >= a ? a - b : a >= f && g >= a ? 10 + a - f : a >= d && e >= a ? 10 + a - d : 0
    }
    function hexToDigit(a) {
    var d,
        b = 0,
        c = Math.min(a.length, 4);
    for (d = 0; c > d; ++d)
        b <<= 4,
        b |= charToHex(a.charCodeAt(d));
    return b
}
    function biFromHex(a) {
        var d,
            e,
            b = new BigInt,
            c = a.length;
        for (d = c, e = 0; d > 0; d -= 4, ++e)
            b.digits[e] = hexToDigit(a.substr(Math.max(d - 4, 0), Math.min(d, 4)));
        return b
    }

    function RSAKeyPair(a, b, c) {
        this.e = biFromHex(a),
        this.d = biFromHex(b),
        this.m = biFromHex(c),
        this.chunkSize = 2 * biHighIndex(this.m),
        this.radix = 16,
        this.barrett = new BarrettMu(this.m)
    }

    function biHighIndex(a) {
        for (var b = a.digits.length - 1; b > 0 && 0 == a.digits[b];)
            --b;
        return b
    }

    function setMaxDigits(a) {
        maxDigits = a,
        ZERO_ARRAY = new Array(maxDigits);
        for (var b = 0; b < ZERO_ARRAY.length; b++)

            ZERO_ARRAY[b] = 0;
        bigZero = new BigInt,
        bigOne = new BigInt,
        bigOne.digits[0] = 1
    }

    var Hb6V = function(i7b, u7n) {
        try {
            u7n = u7n.toLowerCase();
            if (i7b === null)
                return u7n == "null";
            if (i7b === undefined)
                return u7n == "undefined";
            return bd7W.toString.call(i7b).toLowerCase() == "[object " + u7n + "]"
        } catch (e) {
            console.log(e)
            return !1
        }
    };


     var md = ["色", "流感", "这边", "弱", "嘴唇", "亲", "开心", "呲牙", "憨笑", "猫", "皱眉", "幽灵", "蛋糕", "发怒", "大哭", "兔子", "星星", "钟情", "牵手", "公鸡", "爱意", "禁止", "狗", "亲亲", "叉", "礼物", "晕", "呆", "生病", "钻石", "拜", "怒", "示爱", "汗", "小鸡", "痛苦", "撇嘴", "惶恐", "口罩", "吐舌", "心碎", "生气", "可爱", "鬼脸", "跳舞", "男孩", "奸笑", "猪", "圈", "便便", "外星", "圣诞"]
     var emj =  {
        "色": "00e0b",
        "流感": "509f6",
        "这边": "259df",
        "弱": "8642d",
        "嘴唇": "bc356",
        "亲": "62901",
        "开心": "477df",
        "呲牙": "22677",
        "憨笑": "ec152",
        "猫": "b5ff6",
        "皱眉": "8ace6",
        "幽灵": "15bb7",
        "蛋糕": "b7251",
        "发怒": "52b3a",
        "大哭": "b17a8",
        "兔子": "76aea",
        "星星": "8a5aa",
        "钟情": "76d2e",
        "牵手": "41762",
        "公鸡": "9ec4e",
        "爱意": "e341f",
        "禁止": "56135",
        "狗": "fccf6",
        "亲亲": "95280",
        "叉": "104e0",
        "礼物": "312ec",
        "晕": "bda92",
        "呆": "557c9",
        "生病": "38701",
        "钻石": "14af6",
        "拜": "c9d05",
        "怒": "c4f7f",
        "示爱": "0c368",
        "汗": "5b7a4",
        "小鸡": "6bee2",
        "痛苦": "55932",
        "撇嘴": "575cc",
        "惶恐": "e10b4",
        "口罩": "24d81",
        "吐舌": "3cfe4",
        "心碎": "875d3",
        "生气": "e8204",
        "可爱": "7b97d",
        "鬼脸": "def52",
        "跳舞": "741d5",
        "男孩": "46b8e",
        "奸笑": "289dc",
        "猪": "6935b",
        "圈": "3ece0",
        "便便": "462db",
        "外星": "0a22b",
        "圣诞": "8e7",
        "流泪": "01000",
        "强": "1",
        "爱心": "0CoJU",
        "女孩": "m6Qyw",
        "惊恐": "8W8ju",
        "大笑": "d"
    }




    var gO9F =  function(i7b) {

        return Hb6V(i7b, "function")
    }
    var bh7a =  function(k7d, cH8z, O7H) {

        if (!k7d || !k7d.length || !gO9F(cH8z))

            return this;

        if (!!k7d.forEach) {
            k7d.forEach(cH8z, O7H);
            return this
        }

        for (var i = 0, l = k7d.length; i < l; i++)
            cH8z.call(O7H, k7d[i], i, k7d);
        return this
    }


    var bsc2x = function(cya8S) {

        var m7f = [];
        bh7a(cya8S, function(cxZ8R) {
            m7f.push(emj[cxZ8R])
        });

        return m7f.join("")
    };

    function a(a) {
        var d,
            e,
            b = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789",
            c = "";
        for (d = 0; a > d; d += 1)
            e = Math.random() * b.length,
            e = Math.floor(e),
            c += b.charAt(e);
        return c
    }
    function b(a, b) {

        var c = CryptoJS.enc.Utf8.parse(b),
            d = CryptoJS.enc.Utf8.parse("0102030405060708"),
            e = CryptoJS.enc.Utf8.parse(a),
            f = CryptoJS.AES.encrypt(e, c, {
                iv: d,
                mode: CryptoJS.mode.CBC
            });

        return f.toString()
    }
    function c(a, b, c) {
        var d,
            e;

        return setMaxDigits(131), d = new RSAKeyPair(b, "", c), e = encryptedString(d, a)
    }

    function decrypt(d, e, f, g) {
        var h = {}
          , i = a(16);
        return h.encText = b(d, g),
        h.encText = b(h.encText, i),
        h.encSecKey = c(i, e, f),
        h
    }

    function e(a, b, d, e) {
        var f = {};
        return f.encText = c(a + e, b, d), f
    }

    function get_efg(){
            var r = {}
            r.e = bsc2x(["流泪", "强"])
            r.f = bsc2x(md)
            r.g = bsc2x(["爱心", "女孩", "惊恐", "大笑"])
           return r
    }

以下是python部分代码,由于要用到js,需要用到execjs库,自行百度pip install。

import traceback
import json
import requests
import execjs

with open("wangyiyun.js") as f:
    jscode = f.read()
js = execjs.compile(jscode)


csrf_token = "your_token"
url = f"https://music.163.com/weapi/song/enhance/player/url/v1?csrf_token={csrf_token}"

headers = {
    "Accept": "*/*",
    "Host": "music.163.com",
    "Accept-Language": "zh-CN,zh-Hans;q=0.9",
    "Content-Type": "application/x-www-form-urlencoded",
    "Accept-Encoding": "gzip, deflate, br",
    "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.2 Safari/605.1.15",
    "Referer": "https://music.163.com/",
    "Connection": "keep-alive",
    "Cookie": "ntes_kaola_ad=1; JSESSIONID-WYYY=NNam6ZvnitTQAIxhjcnkVGOJe1CSrnqIOsBnuOzx405%2FJAUSng5IDkYIFo00Xb%2BoUldg8unn3ikRohd8TEg%2F5A9IF0d3vIrPq0ggue%2BD%2FCFTwZBaj%2FfbHOgwt15v2R4uXH8%2FJuMri%2F3zPb%2Bl7TH%2B4XFVYq9BghtkAelO6p5uAC4QQxNh%3A1735613258319; _iuqxldmzr_=32; playerid=96541318; WEVNSM=1.0.0; WM_TID=%2FnYekZpayJFEEEVQRRfHMEPNaHmTqyHZ; MUSIC_U=006C5AF78BF74B16F27E5B57A85731911569EB8ABB9380E9315B54803127FFDF3C459640CCB0E2BDE8425D2EE33764BC1DB30AA186B850E1CED2B79EF2436E56F8786A63776BFC2243956C5AC987B3A85797BC545993FB84F14E3C4C66EF506A087542A5DE0B218EEA044FDCED41F7037A2EA93679113D60D72EAD7603A7B74BAF1EA4753BF65B585F5130F58CC7711D5EB79F559AD803761591C3D9AB83F967DDFA019B5C6C58BB126197139D1D4BB311DED63FECC8F6651349C211AEE6BB2A772FFCB717C731082DE27A19C5F24FB6A3311D4B585E8FA92DF7D35A41F4FCCA7129B921D0ABA174034FCDB36CAE4BB69011E30F7A7A657B1D74C7DCE0CCEB7B01E6F34CE848E3627CAF9D536C3255A80CF5B8064216064E40C7AD67CDF74EC118D8F2D4B6D4A0031A2969ABF5BB2FC4CFDE6E679AA4CB5609C96901D706E9500E94B86D80E4A6A3065227ED8690F5686FF885DC3BB6F1DA7467CEB7D4D42A10B4; __csrf=ca6ddf56d40cc8a27f331f202fe4b326; gdxidpyhxdE=4xfjyEeg4lc3N%5Ch2d%5Cmuya67isI3pZMPzyE5piBKE4MbnmjX8cO%2BUPnScJ7ZVrK8%2FyENi%2FPm%2FUJ%5C7Jt7%2Fu%5CxVq0KD8x%2Bs2uyBrRX6bcW9sjSWg%5Cw%2F7KNEkKk%5C6Mn6dM0bzaQBt%2F06wgBdKtOe3TuWkbDmcE6EvqXOdSnvvjBjs44kdz0%3A1735610638700; __snaker__id=1FPbd4ulJdEVbVUp; ntes_utid=tid._.m%252BLT1NjmAjZAUkFUAAaSMBOdaWzOWutc._.0; sDeviceId=YD-YPiVIvIe3u5EAxABBUfFxyhoxuMxXPie; WNMCID=scyqtk.1735609723331.01.0; WM_NI=AvJ1%2BaTN%2Bars6kp4BqZR6lew0ErnCxDEjplQcna1dpw2o38u%2BYsJZfwf7oZZx3RYpR1b0M2XDa5vbBs0LlSAcWKBQpCU5WBUbXnW%2BM%2BjOjngWravnIJ5CDCtziN4QsN0MW8%3D; WM_NIKE=9ca17ae2e6ffcda170e2e6eea6fb4089be9ab8f74483eb8ab3c55f928f8e83d769869482b1c73985abb6a5e72af0fea7c3b92a83aa86d2aa6b9892e582f179f6b5c0d5c17b9a8efa8de87df49bbe8fc274889ba691ef5ba1b2afd2e77cb5eea1d4bb7fe987bdabd96eb5baf990d952bced9ebaf35af3be00aeb15488bffb97e14ab1f0848dd24ba18985a3d47c818bfbb8c15fa288a2b8aa47e9b6818bed6d95aeaf97ed438aeb8da5c280bab782d5d4798ef083b8bb37e2a3; _ntes_nnid=0abb01037659f4b4a2020921c96bcfd4,1735609718336; _ntes_nuid=0abb01037659f4b4a2020921c96bcfd4; NMTID=00Ob7X1eXe08UIQIk_Bl7cELz7aKHkAAAGQCjtDIA",
}

# 音乐id
music_id = 2122122972
song_data = {
    "ids": f"[{music_id}]",
    "level": "standard",
    "encodeType": "aac",
    "csrf_token": csrf_token
}

# 获取js运行的结果
try:
    efg_obj = js.call("get_efg")
    res = js.call("decrypt", *(json.dumps(song_data), efg_obj["e"], efg_obj["f"], efg_obj["g"]))
except:
    print(traceback.format_exc())


data = {
    "params": res["encText"],
    "encSecKey": res["encSecKey"],
}

resp = requests.post(url, headers=headers, data=data)

print(resp.status_code)
print(resp.text)

music = requests.get(url=resp.json()["data"][0]["url"])
with open(f"{music_id}.m4a", "wb") as f:
    f.write(music.content)

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

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

相关文章

深入了解 SSL/TLS 协议及其工作原理

深入了解 SSL/TLS 协议及其工作原理 一. 什么是 SSL/TLS?二. SSL/TLS 握手过程三. SSL/TLS 数据加密与传输四. 总结 点个免费的赞和关注&#xff0c;有错误的地方请指出&#xff0c;看个人主页有惊喜。 作者&#xff1a;神的孩子都在歌唱 一. 什么是 SSL/TLS? 安全套接层&am…

Java四大常用JSON解析性能对比:Hutool、Fastjson2、Gson与Jackson测试

1. 引言 JSON 是现代软件开发中常用的数据交换格式&#xff0c;尤其在微服务和前后端分离的架构中更是必不可少。 本文将对 Java 中四大主流 JSON 解析库——Hutool、Fastjson2、Gson 和 Jackson 进行性能测试和对比分析&#xff0c;通过实测 20 万条数据解析&#xff0c;揭示…

【整理集合大全】MySQL(4) 数据库增删改查SQL语句

查看数据库 show databases; 使用数据库 use 数据库名;创建数据库 CREATE DATABASE 数据库名;删除数据库 DROP DATABASE 数据库名;创建表 create table 表名(列名1 类型(长度) [约束],列名2 类型(长度) [约束],…… );长度区别 int类型带长度&#xff1a;不影响存取值&…

升级 Spring Boot 3 配置讲解 —— Spring Boot 3 核心源码专讲

学会这款 &#x1f525;全新设计的 Java 脚手架 &#xff0c;从此面试不再怕&#xff01; Spring Boot 3 是 Spring 生态中的重要里程碑&#xff0c;它不仅全面支持 Java 17&#xff0c;还引入了许多新特性&#xff0c;如对 GraalVM 原生镜像的支持、改进的性能优化以及更灵活的…

vue3中el-table实现多表头并表格合并行或列

1、el-table中添加事件 :span-method"genderSpanCity" <el-table :span-method"genderSpanCity":data"data.tableData":fit"true" table-layout"fixed" header-align"center" stripestyle"width:100%;he…

OpenGL —— 流媒体播放器 - ffmpeg解码rtsp流,opengl渲染yuv视频(附源码,glfw+glad)

效果 说明 FFMpeg和OpenGL作为两大技术巨头,分别在视频解码和图形渲染领域发挥着举足轻重的作用。本文将综合两者实战视频播放器,大概技术流程为:ffmpeg拉取rtsp协议视频流,并经过解码、尺寸格式转换为yuv420p后,使用opengl逐帧循环渲染该yuv实时视频。 核心源码 vertexSh…

Web安全扫盲

1、建立网络思维模型的必要 1 . 我们只有知道了通信原理&#xff0c; 才能够清楚的知道数据的交换过程。 2 . 我们只有知道了网络架构&#xff0c; 才能够清楚的、准确的寻找漏洞。 2、局域网的简单通信 局域网的简单通信&#xff08;数据链路层&#xff09; 一般局域网都通…

HTML 显示器纯色亮点检测工具

HTML 显示器纯色亮点检测工具 相关资源文件已经打包成html等文件&#xff0c;可双击直接运行程序&#xff0c;且文章末尾已附上相关源码&#xff0c;以供大家学习交流&#xff0c;博主主页还有更多Html相关程序案例&#xff0c;秉着开源精神的想法&#xff0c;望大家喜欢&#…

ARM发布Armv9.5架构:迈向更强性能与灵活性的新时代

2024年11月30日&#xff0c;ARM正式发布了其最新的Armv9.5架构&#xff0c;这是Arm技术发展的又一重要里程碑。从表中信息来看&#xff0c;Armv9.5架构的发布标志着该公司的架构系列在性能、灵活性和可扩展性方面取得了进一步突破。本次发布不仅是技术上的提升&#xff0c;更是…

被催更了,2025元旦源码继续免费送

“时间从来不会停下&#xff0c;它只会匆匆流逝。抓住每一刻&#xff0c;我们才不会辜负自己。” 联系作者免费领&#x1f496;源&#x1f496;码。 三联支持&#xff1a;点赞&#x1f44d;收藏⭐️留言&#x1f4dd;欢迎留言讨论 &#x1f525;亲爱的朋友们&#xff0c;感谢你…

【Rust自学】10.4. trait Pt.2:trait作为参数和返回类型、trait bound

喜欢的话别忘了点赞、收藏加关注哦&#xff0c;对接下来的教程有兴趣的可以关注专栏。谢谢喵&#xff01;(&#xff65;ω&#xff65;) 说句题外话&#xff0c;写这篇的时间比写所有权还还花的久&#xff0c;trait是真的比较难理解的概念。 10.4.1. 把trait作为参数 继续以…

R机器学习:神经网络算法的理解与实操,实例解析

神经网络算法是一种模仿生物神经网络&#xff08;尤其是人脑&#xff09;结构和功能的算法。它由大量相互连接的节点&#xff08;称为神经元&#xff09;组成&#xff0c;这些神经元组织成层&#xff0c;通过传递信号来处理信息。神经网络算法在机器学习、人工智能等领域中扮演…

Java(day4)

二维数组 静态初始化 动态初始化 练习 public class test1 {public static void main(String[]args){int arr[][]{{22,66,44},{77,33,88},{25,45,65},{11,66,99}};int sum0;for(int i0;i<arr.length;i){int a0;for(int j0;j<arr[i].length;j){sumarr[i][j];aarr[i][j];…

element-plus大版本一样,但是小版本不一样导致页面出bug

npm 的版本 node的版本 npm的源这些都一样&#xff0c;但是效果不一样 发现是element的包版本不一样导致的 2.9.1与2.8.1的源是不一样的&#xff0c;导致页面出bug;

【Docker】安装registry本地镜像库,开启Https功能

下载镜像 docker pull registry:2 需要启动https功能&#xff0c;就要生成服务端的自签名的证书和私钥&#xff0c;以及在docker客户端安装这个经过签名的证书。 第一步&#xff1a;生成公私钥信息&#xff0c;第二步&#xff0c;制作证书签名申请文件&#xff0c; 第三步&…

单片机-LED点阵实验

要将第一个点点亮&#xff0c;则 1 脚接高电平 a 脚接低电平&#xff0c;则第一个点就亮了&#xff1b;如果要将第一行点亮&#xff0c;则第 1 脚要接高电平&#xff0c;而&#xff08;a、b、c、d、e、f、g、h &#xff09;这些引脚接低电平&#xff0c;那么第一行就会点亮&…

PDFMathTranslate: Star13.8k,一款基于AI的PDF文档全文双语翻译PDF文档全文双语翻译,保留格式神器,你应该需要它

嗨&#xff0c;大家好&#xff0c;我是小华同学&#xff0c;关注我们获得“最新、最全、最优质”开源项目和高效工作学习方法 PDFMathTranslate是一个开源项目&#xff0c;旨在为用户提供便捷的PDF科学论文翻译解决方案。它不仅能够翻译文本&#xff0c;还能保留公式、图表、目…

RockyLinux9配置静态ip地址教程

以往我们配置linux系统的ip地址是在 /etc/sysconfig/network-scripts/ifcfg-网卡名 配置文件中编辑的&#xff0c;详情请见 Rocky8.10配置网络和主机名教程_rocky8配置网络-CSDN博客 但是在RockyLinux9系统中弃用了以前的这种方式&#xff0c;改为了新的配置方式。下面我们介绍…

民宿酒店预订系统小程序+uniapp全开源+搭建教程

一.介绍 一.系统介绍 基于ThinkPHPuniappuView开发的多门店民宿酒店预订管理系统&#xff0c;快速部署属于自己民宿酒店的预订小程序&#xff0c;包含预订、退房、WIFI连接、吐槽、周边信息等功能。提供全部无加密源代码&#xff0c;支持私有化部署。 二.搭建环境 系统环境…

【C++数据结构——图】图的邻接矩阵和邻接表的存储(头歌实践教学平台习题)【合集】

目录&#x1f60b; 任务描述 相关知识 1. 带权有向图 2. 图的邻接矩阵 3. 图的邻接表 测试说明 通关代码 测试结果 任务描述 本关任务&#xff1a;编写一个程序实现图的邻接矩阵和邻接表的存储。 相关知识 为了完成本关任务&#xff0c;你需要掌握&#xff1a; 带权有向图…