在⽹易云⾳乐⽹页版上加下载按键进⾏下载歌曲
源由
每⼀次放假回家的时候,都会帮家⾥⾯的⼈下载歌曲,当然差不多⽤的都是⽹易云⾳乐⽹页版,但是只有客户端才提供下载按键,所以每次都是从 Chrome 的开发者⼯具的 Network 中链接,进⾏下载。所以我就想着能不能⽤ JS 代码来实现⼀个按键,⼀键就可以下载⾳乐。其实我可以直接⽤客户端来进⾏下载的,但随便为了学习⼀下,⽤ JS 来实现。
原理
其实原理很简单,先打开 Chrome 的开发者⼯具的 Network 中,数据类型选为 Media,再打开⽹易云⾳乐的界⾯,点击⼀⾸歌,即可看
到数据的 URL 地址,下载即可。
但这⾥的缺点是,重复操作,⽽且下载也没有歌曲名,你需要⼀个⼀个的下载,⼀个⼀个的更改歌名,所以接下来我打算解决两个点:
代码解决
思路
⼤概看云⾳乐界⾯情况,可知播放控制栏为固定的,则可以肯定,数据是通过 Ajax 发送,获取歌曲的 URL 地址,再进⾏加载播放。在开发者的 Network 中记录了所有的请求数据,请求的数据是按照时间来排序的,我们按照刚才的原理可以获取到歌曲的 URL 地址,所以在该歌曲的请求数据上⾯,肯定会有⼀个发送 Ajax 的请求,来请求歌曲的 URL 地址信息。所以我的思路是这样的,到该 Ajax 请求函数,模拟发送歌曲信息请求,获取歌曲的 URL 地址,然后进⾏下载。
1.  点击下载。
2.  ⾃动复制歌曲名。
我们把 Network 中的数据类型选中为 All,即可看到发送的 Ajax 歌曲信息请求。
在 Network 的 Name 栏可看到 55ea198fb 开头(最后⼀个)的请求,是发送的歌曲请求,所以在上⾯会有⼀个歌曲信息的请求,我们边往上边看请求的返回数据,⼤概知道该歌曲信息请求的返回值中肯定有歌曲的 URL 地址。在往上的第四条我们发现了该请求。
将该条⽬的具体信息关掉,也就是点击 Headers 左边的⼩叉叉,即可看到:
发送该 Ajax 请求的是云⾳乐的 core.js ⽂件。
将 core.js ⽂件下载下来,再,为什么我会把该代码下载下来呢,我是这么想的他发送 Ajax 请求,可能会是先填⼊发送的相关 URL 地址,然后需要的时候再加上参数调⽤发送,所以我们还需要知道发送该 Ajax 的具体 URL 地址是什么,在 Network 中点击发送获取歌曲信息的条⽬,可看到为:
Request URL:music.163/weapi/song/enhance/player/url?csrf_token=
将该 URL 在格式化后的 core.js 代码中进⾏查。我们⾸先查 weapi/song/enhance/player/url ⽆果,再次去除⼀些,再查song/enhance/player/url
金莎整容当看到 type: “json” 这个字段时,我们⼤胆的猜测 v5A.bl5q() 即为发送 Ajax 的函数。
Ajax 请求函数
华为手表太空人表盘怎么设置
我们再⼀次的全局搜索 v5A.bl5q 的定义代码,发送有⼀处代码为:
在该代码中我们发现:
j5o["csrf_token"] = v5A.gC7v("__csrf");
Y5d = place("api", "weapi");
我们很肯定这个就是云⾳乐发送 Ajax 的代码,只不过被混淆了,不过我们可以进⾏⿊箱操作,我们把该代码块提取出来,也就是(function() { … })();
中的代码,我们把提取出来的代码,复制在游览器云⾳乐页⾯的开发者⼯具 Console 中,但报错了:
点击最右的超链接,发现原来代码在 if (define) return; 返回了,这⾥应该是为了避免重复定义 Ajax 接⼝设置的,在这⾥不管,我们直接把他去掉,即可运⾏成功了,此时我们就可以在 Console 中,调⽤ v5A.bl5q() 发送 Ajax 请求了。
可以在 Console 中输⼊这个,即可获得歌曲的 URL 地址,但这⾥要发送有两个参数,⼀个是 ids、br。ids 应该是歌曲的 id 进⾏加密,所以this.cP6J.id  为歌曲的 id。全局到 DEFAULT_BR,可知道这个是⼀个变量,我猜测这⾥应该是⾳质的选择:
嗯,对的,就是⾳质的选择,那我们可以将该 DEFAULT_BR = 320e3 获取极⾼的⾳质。
onload  请求成功时调⽤,onerror  请求失败是调⽤,我们可以⽤下⾯这个函数来打印响应的数据。
此时我们已经知道获取歌曲 URL 地址的 Ajax 函数。
若参数还⽆法确定时,可采⽤在线调试云⾳乐的 core.js 代码,利⽤我之前写的在线调试 JS 的(点击即可访问),获取 Ajax 发送的请求数据,即可以在代码中输出对应的参数信息,即可观察到。
v5A .bl 5q("/api/song/enhance/player/url", {
杨洋吻郑爽type: "json",
query: {
ids: JSON .stringify ([this .cP 6J .id ]),
br: DEFAULT_BR
},
onload: this .bGl 1x .f 5k(this),
onerror: this .bGl 1x .f 5k(this)        })
笔记本电脑配置知识
var DEFAULT_BR = 128e3;
var  a = function () {console.log(arguments)}
获取 id 和歌名
在偶然间我发现,云⾳乐有⼀个 window.player 对象:
糊里糊涂类似的成语这⾥⾯有⼀个 getPlaying() 函数,⾥⾯记录了当前播放⾳乐的信息:
所以我们可以通过这个来获取到 id 和歌名
b4f .bFx 0x = function() {
this .zJ 3x();
console .log ("************debug***********请求数据")
console .log (this .cP 6J .id )
console .log (DEFAULT_BR)
console .log ("************debug***********请求数据")
v5A .bl 5q("/api/song/enhance/player/url", {
type: "json",
query: {
ids: JSON .stringify ([this .cP 6J .id ]),
br: DEFAULT_BR
},
onload: this .bGl 1x .f 5k(this),
onerror: this .bGl 1x .f 5k(this)
})
};
var track = Playing().track
// 歌曲 id
var id = track.id
// 歌⼿名
var singer = track.artists.map(e => e.name).join ('/');
// 歌曲名
泰坦护腿
var song = track.name;
var name = `${singer} - ${song}.mp3`;