xx云音乐 encSecKey参数逆向分析

 

        网易云音乐唯一的加密地方在每个音乐的评论数据上,一些做自然语言nlp的同学可能会需要这部分的数据。本篇文章将带着大家逐步分析网易云音乐 params 和 encSecKey 参数的加密方法,以及如何逆向得出加密参数。

        我们先随便进入一首歌的页面当中,然后打开浏览器抓包,找到这首音乐下面的评论区数据。33db13df36f8409c8cc4f4f9c79333af.png

         为了方便查找,我直接把接口的 url 地址放出来,大家也可以自己动动手通过浏览器 F12 抓包获取,https://music.163.com/weapi/comment/resource/comments/get?csrf_token=。该 url 的请求格式为 post 请求,所以我们需要提交正确的表单参数服务器才会给我返回正确的数据,点击 playload 就能看到浏览器在请求该 url 的时候提交了 params encSecKey 这两个参数,这两个参数就是我们本篇文章所需要逆向分析的关键参数。

98d1324437bc441694af60da5bb39cd2.png

         点击 Initiator 开始跟栈分析,大家都知道 web端 如果 post 表单中存在着加密参数,一般都是通过该网站所加载的 js 文件进行加密的,跟栈的目的就是为了在 js 文件当中找到加密的最初位置以及加密部分的代码,可以理解为从最后一步一直向上一步跟进。点击最上面的一个栈进入dad8d61bab3a4cb7b14cbe57c2515909.png   08079ce1a5994107afe22aaec05e7373.png        浏览器会自己跟到最后一处地方,我们在当前的位置打上断点,然后刷新当前页面,刷新过后浏览器会自动断在当前的断点处,此处有一个 send 发送了个名为 gC9t.data 的数据,用鼠标括住 gC9t 把光标放在 gC9t 上可以看到,gC9t 内部有许多参数,其中的 data 就包含 paramsencSecKey 这两个参数,这就能够确定数据是从上一个栈传过来的,在右边的 Call Stack 可以向上一个栈跟进。a09b46907ba143eb870795520a7cc3e6.png

        进入上一个栈,自动跳转到 this.ci8a(d7e) 其中的 d7e 就是往下一个栈传的参数,鼠标放上去看看里面有啥。能够看到其中的 requestdata 包含着我们需要的参数 params,encSeckey

b8a0513ce5174d28a3e1d2de1b1838fd.png

        此时我们需要注意查看当前断点函数的内部是否重新定义了 d7e ,如果没有重新定义则往函数头部查看 d7e 是否为上一个栈传进来的参数。虽然当前的函数内部定义了 d7e( var d7e = xxxx),但是任何加密方法生成新的参数。我们往头部查看可以发现传进来的 ib7 为一串字符串,其中包含着 params,encSecKey ,这就可以断定我们需要的参数还是从上一个栈中传进来的,接着往上一个栈跟,发现传入的数据变成 ed7.data ,往头部查看发现 ed7 为传入的参数,继续往上一个栈跟。2d2e0820be9d4dbf97fc445443e235d7.png

         进到上一个栈后,发现向下一个栈传递的数据为 Y8Q, e7d 还是老方法看当前函数内部有没有重新定义 e7d , 向上看第一眼就看到了 e7d.data = j7c.cr8j(括号内跟着一个字典类型的数据)802038e112084e2ea6dfa3263bc33384.png

         看到有重新定义 e7d.data 我们就需要注意,需要在 e7d.data 当前这一行下断点查看是否有重新生成新的参数。我们找到的这个地方很明显就是一个加密的入口,已经可以看到我们想找的 paramsencSecKey

e7d.data = j7c.cr8j({
                params: bMr5w.encText,
                encSecKey: bMr5w.encSecKey
            })

fb0059ae5475418db569d7b8d19e1197.png

         params bMr5wencText  encSecKey bMr5wencSecKey ,现在我们需要搞明白 bMr5W 是什么东西,把它括住进到内部查看发现就在上一面一行定义了一个 bMr5w

var bMr5w = window.asrsea(JSON.stringify(i7b), bsg1x(["流泪", "强"]), bsg1x(TH2x.md),                 bsg1x(["爱心", "女孩", "惊恐", "大笑"]));

        bMr5w 是通过了 window.asrsea 这个方法,传入四个参数进行的加密, 分别括住四个参数查看。第一个参数跟我们当前的 url 有关(url 上的音乐id),传入的第二个参数则是一串固定的数字,第三个参数是取 TH2x 这个列表进行了一个加密的操作,然后取加密后返回的结构(也是固定的),第四个参数对一个字符串列表进行加密取返回的结果(固定的)。很明显,现在的思路基本可以定下来,我们可以把后三个参数直接写死,但是我们还需要分析 window.asrsea 这个方法的加密原理,直接进到内部查看。    b372faebb6074057abbab7877499e7f2.png

         进到内部就会自动跳到这一行,可以看到 d 这个方法里头return了 h.encTexth.encSecKey 这俩个数据。其中的 h.encText 就对应着我们的 params。现在开始分析 d 这个方法的内部是怎么实现的,首先是 var 了一个 h,然后是 var 了一个 i 而 i 又等于 a(16) 【 a(16)这是生成一串长度固定的随机数】​​​​​​ ,返回的 h.encText 先经过 b 方法进行加密,传入的 d 与 当前歌曲的 id 有关,g 则是固定值。然后将已经加密过的 h.encText 再一次传入 b 这个方法中加密,i 为我们上面提到的一串长度固定的随机数,简单理解为就是 h.encText 经过同一个方法加密了两次。我们进到 b 这个方法中看看。

function d(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
    }

      93c571d7e3b84ea2a28685c43fa18e16.png

         自动跳到着,第一眼就看到了 AES,一目了然 b 这个方法就是调用了 CryptoJS 做了一个 AES的加密,我们能看到最后 return 了 f.toString()  ,而 f 是经过 AES 加密的来,其中传入的 e salt(固定值)和 c(数组),大致了解此处的加密方法之后我们就可以开始扣js代码了。

Advanced Encryption Standard是一种分组加密标注,每个加密数据块大小固定为128位(16个字节),最终生成的加密密钥长度有128位、192位和256位。 AES 加密主要有五种加密模式(还有更多):CBC(Cipher-block chaining,密码分组链接),CFB (Cipher feedback,密文反馈),OFB (Output feedback,输出反馈),PCBC (Propagating cipher-block chaining,增强型密码分组链接),ECB (Electroniccodebook,电子密码本)

        第一部分主要是扣 b 这个方法,然后两次加密得到 h.encText(这个其实对应的就是我们想要的 params 参数),如下图所示,我们把 b 方法扣下来,用 encryption 重新命名,第一次运行这段代码会报 CryptoJS 不存在这个错误,解决的两种方法:第一种方法就是在js文件当中找到 CryptoJS 扣下来(一般都会很大串很大条:));第二种方法也是我用的方法,就是用nodejs提供的CryptoJS(能少扣不少代码)

const CryptoJS = require('crypto-js');

32fdfe36fc024b7fa7b66d71e52e1189.png         扣下来后,我们模拟 h.encText 的生成方法,先来第一次的加密,这里我们需要把传入的参数拿出来单独讲讲(就是之前说的和音乐id有关的参数),该参数的格式如下  ridthreadId 里头的一串数字对应着就是我们的音乐id 前面的 R_SO_4_ 则不用动。传入的第二个参数是固定的,直接写死,生成的结果如下图所示:

// 传入的参数1如下所示
{"rid":"R_SO_4_865632948","threadId":"R_SO_4_865632948","pageNo":"1","pageSize":"20","cursor":"-1","offset":"0","orderType":"1","csrf_token":""}

b5a3aa65104f46e9b8fbe8bed4c53da3.png

         接着就是 params 的第二次加密,在第二次加密中我们之前提到了一个重要的参数 i ,i 参数是一串长度固定且随机生成的参数,在上面我们能够看到 i 其实是等于 a(16) ,将 a 这个方法扣下来就能够模拟生成出 i 这个重要的参数了!我们直接进到 a 这个方法查看,内部的原理其实就是用random做了一个随机数,然后通过 charAt 取出特定位置的字符进行拼接,直接把这段代码扣下来,生成结果如下图所示。4da82fde011b4c1582dbfd3c1084c703.png

 f141b05169e04c5fbb4dd2fa30c39547.png

         得到生成的 i 值,接下来就能够把生成出的 i 值与第一次加密出来的结果传入我们定义的 encryption 中进行加密,最后加密出来就是我们想要的 params  ,结果如下图:

db1320516e5247d2b8001092387e9a41.png

        搞定 params 参数后,我们接着来看 encSecKey 参数,我们已经知道 h.encSecKey = c(i, e, f) ,i 值我们已经搞定 ,传入的 e 值为固定值(010001), f 值是一串很长的数据(其实也是固定值,直接定死),现在只需要把 c 这个方法扣出来就能够得到需要的 encSecKey ,进入 c 方法看看,进入后断在此处,不难看出 encSecKey 其实是通过 RSA 加密出来的,setMaxDigits(131) 是一个空值(不用管),重点在下面的 d 和 e。d0dedbbfec7041c7a59a985fa5265a69.png

         dnew 了一个新的方法名为 RSAKeyPair ,可以理解为 d 生成了 RSA 加密所需要的密钥 publickey ,然后将 da 传入 encryptedString 方法中加密,最后得到我们想要的 encSecKey ,直接把 c 这个方法扣出来,然后将 RSA 的加密方法补上以及下面的 encryptedString 方法(具体操作和扣 params 加密方法一样),随后运行,缺少什么函数就在当前的 js 文件中寻找然后补上,补完所有函数后我们想要的 encSecKey 也就生成了!(过程很简单我就不细说了,就是找到然后扣出来),最后扣完的代码一共390来行,扣完的代码在下面。

const CryptoJS = require('crypto-js');

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
}

function BigInt(a) {
    this.digits = "boolean" == typeof a && 1 == a ? null : ZERO_ARRAY.slice(0),
    this.isNeg = !1
}

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 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 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 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 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 biHighIndex(a) {
    for (var b = a.digits.length - 1; b > 0 && 0 == a.digits[b]; )
        --b;
    return 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 biCopy(a) {
    var b = new BigInt(!0);
    return b.digits = a.digits.slice(0),
    b.isNeg = a.isNeg,
    b
}

function biDivide(a, b) {
    return biDivideModulo(a, b)[0]
}

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 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 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 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 biMultiplyByRadixPower(a, b) {
    var c = new BigInt;
    return arrayCopy(a.digits, 0, c.digits, b, c.digits.length - 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 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 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 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 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 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 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 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 biDivideByRadixPower(a, b) {
    var c = new BigInt;
    return arrayCopy(a.digits, b, c.digits, 0, c.digits.length - b),
    c
}

function biModuloByRadixPower(a, b) {
    var c = new BigInt;
    return arrayCopy(a.digits, 0, c.digits, 0, b),
    c
}

function biToHex(a) {
    var d, b = "";
    for (biHighIndex(a),
    d = biHighIndex(a); d > -1; --d)
        b += digitToHex(a.digits[d]);
    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 reverseStr(a) {
    var c, b = "";
    for (c = a.length - 1; c > -1; --c)
        b += a.charAt(c);
    return b
}

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;
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 i(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
    }

// params
function encryption(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()
}

// encSecKey
function encSecKeyEncryption(a, b, c) {
    var d, e;
    return setMaxDigits(131),
        d = new RSAKeyPair(b, "", c),
        e = encryptedString(d, a)
}

// 生成i值
var i_data = i(16);

// encSecKey固定参数1
var encSecKeyParameterOne = '010001';
// encSecKey固定参数2
var encSecKeyParameterTwo = '00e0b509f6259df8642dbc35662901477df22677ec152b5ff68ace615bb7b725152b3ab17a876aea8a5aa76d2e417629ec4ee341f56135fccf695280104e0312ecbda92557c93870114af6c9d05c4f7f0c3685b7a46bee255932575cce10b424d813cfe4875d3e82047b97ddef52741d546b8e289dc6935b3ece0462db0a22b8e7';

// 生成params
var params = encryption(encryption('{"rid":"R_SO_4_865632948","threadId":"R_SO_4_865632948","pageNo":"1","pageSize":"20","cursor":"-1","offset":"0","orderType":"1","csrf_token":""}', '0CoJUm6Qyw8W8jud'), i_data)

// 生成encSecKey
var encSecKey = encSecKeyEncryption(i_data, encSecKeyParameterOne, encSecKeyParameterTwo)

function data() {
    return {
        'params': params,
        'encSecKey': encSecKey
    }
}
console.log(data())

        运行一下看看生成的结果,如下图所示:c0d5f28c035f47aa9b578e45303d33d3.png

        接着我们写一个简单的爬虫测试一下,注意大家自行修改当前的音乐id哦! 

# -*- coding: utf-8 -*-
import execjs
import requests

url = 'https://music.163.com/weapi/comment/resource/comments/get?csrf_token='
def get_response():
    ''' 请求 '''
    JsFile = open('parameter.js', encoding='utf-8')
    JsCode = JsFile.read()
    compile_JsCode = execjs.compile(JsCode)
    ParameterData = compile_JsCode.call('data')
    data = {
        'params': ParameterData['params'],
        'encSecKey': ParameterData['encSecKey']
    }
    print(data, '\n')
    response = requests.post(url=url, data=data).text
    print(response)


get_response()

1aa16b21df9f416e8e11b4b7e51591c4.png

可以看到服务器已经给我们返回正确的数据,证明加密的结果没有问题。 

 

 

 

 

 

 

 

 

 

 

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值