先来分析一下页面
当我们点击播放按钮的时候,音乐开始播放。实际上这个逻辑背后的原理是这个按钮后面对应的是一个url,这个地址是通过ajax来进行局部刷新的。
所以我们可以通过抓包工具,来看看点点击播放按钮的时候到底发送了哪些网络请求。我们逐个去分析这些请求,就可以从这些请求中拿到我们想要的数据了。
那么我们想要下载这个音乐其实只需要三步:
点击播放,这里产生了一堆数据表,这里我们需要逐个去分析。
找到这个请求,返回的数据里面有一个url
http://m701.music.126.net/20240105104834/ad9643baf3be3fea26ec3af8fe02b556/jdyyaac/obj/w5rDlsOJwrLDjj7CmsOj/32048585194/3ae6/9029/4439/a1ee98567f8ef9469319a85700a24486.m4a
直接把这个url放到浏览器里
发现就是这个音乐本身,那么这个url就是我们要的音频的下载地址。
接着我们来分析这个请求
首先URL是这一个
https://music.163.com/weapi/song/enhance/player/url/v1?csrf_token=
直接构造就可以了,那么怎么知道下载的是哪一首歌曲呢,这个体现在参数里
这里一共提交了两个参数,params和encSecKey,那么这两个参数从哪来的就是我们要进行分析的。
我们点开Initiator,随便选一个调用堆栈往上跟
这里gA4E.data
是我们要追踪的加密字段
而这个值来源于当前的参数,所以我们要继续往上找调用堆栈
找到上一层,发现还是来源于参数
一直往上回溯,直到找到这个位置,这里就是他的加密逻辑
var bVi9Z = window.asrsea(JSON.stringify(i3x), bsu5z(["流泪", "强"]), bsu5z(Xo5t.md), bsu5z(["爱心", "女孩", "惊恐", "大笑"]));
e3x.data = j3x.cr3x({
params: bVi9Z.encText,
encSecKey: bVi9Z.encSecKey
})
params
字段和encSecKey
字段均来源于bVi9Z
,那么关键就在于分析出asrsea
函数和他的几个参数
函数代码如下:
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
}
函数内还执行了a,b,c函数,我们顺便把其他的函数一起拿下来
!function() {
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 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
}
function e(a, b, d, e) {
var f = {};
return f.encText = c(a + e, b, d),
f
}
window.asrsea = d,
window.ecnonasr = e
}();
这是第一波扣的代码。
第二波,把Crypto加密库扣下来
第三波,把全局函数扣下来
然后就拿到运行结果了,
也可以通过补全第三方库的方式,来解决这个问题。
接下来需要搞定加密函数的参数
var bVi9Z = window.asrsea(JSON.stringify(i3x), bsu5z(["流泪", "强"]), bsu5z(Xo5t.md), bsu5z(["爱心", "女孩", "惊恐", "大笑"]));
这四个参数都是固定的
我们可以直接把结果拿下来,放到函数里面。
如果你想要其他的数据,比如评论,获取评论的接口也是用的这两个参数,只不过传入的参数不一样,那就得去扣bsu5z
函数,我这里是扣不动了。
最后 写代码发请求,然后把音乐内容下载保存即可。
另外,评论的接口,也是用的这两个参数,需要扣,只不过传入的加密参数不一样,各位有兴趣可以自行分析。