随国内版权意识逐渐增强,各大音乐平台已要求付费下载歌曲,但大部分歌曲可以在线播放,播放时会把歌曲的相关信息获取到本地。网上已有很多相关 API 的分析及根据 API 写好的工具,本文主要对网页端判断歌曲能否播放的代码进行了简单分析,仅作学习研究使用。
QQ音乐
点击播放按钮,弹出新标签页,查看网络请求,发现:
可以验证这就是 m4a 格式的歌曲文件。
歌词
继续查看之前的几个请求,可以发现获取歌词的请求 https://c.y.qq.com/lyric/fcgi-bin/fcg_query_lyric_new.fcg
,返回的歌词经过了 Base64 编码:
URL
获取 URL 的请求是 https://u.y.qq.com/cgi-bin/musicu.fcg
:
GET 请求需要 data 参数,经过搜索,在此处断点:
相关参数如下:
1 | function _getGuid() { |
观察到 guid 为 [0, 1e10) 的随机数,不登录时 uin 为 0。最终的 URL 由 CDN 与 purl 拼接而成。
歌曲能否播放
有些歌曲由于版权原因不能播放,因此基本不能通过这些方法获取歌曲文件,需先进行过滤。无法播放的歌曲在网页端显示为灰色,点击播放,弹框提示,直接搜索字符串,未找到相关代码:
分析播放按钮的响应函数,添加断点:
调试发现在此处弹框:
继续调试,发现 play 函数:
执行流程与 s[0].action.play
有关,搜索 action.play
,
添加断点进行验证,代码执行到此处,于是最终判断歌曲能否播放的代码如下:
1 | e["switch"] || (e["switch"] = 403); |
e 是歌曲的详细数据:
1 | { |
网易云音乐
网易云音乐的 HTTP 请求都经过了 AES 加密,具体的 POST 数据可以通过断点获得,url、搜索等 API 已有很多相关帖子。
歌曲能否播放
无法播放的歌曲显示为灰色:
点击播放,出现:
尝试搜索字符串,下断点:
相关代码如下
1 | function cnp9g(d5i) { |
猜测当 sg1x
等于 10, 100, 11
时歌曲无法播放。在 bgW3x
处断点,可以发现歌曲能播放时会进入到该分支。sg1x
由 l5q.qy0x
返回:
1 | l5q.qy0x = function(bm5r) { |
bm5r
是在搜索“周杰伦”时返回的相关歌曲信息:
1 | { |
歌单详情
歌单数据在返回的响应中能看到歌名,更详细的信息在网页中以密文的形式隐藏了:
解密的方法参考网易云音乐歌单详情列表爬虫破解