-
Notifications
You must be signed in to change notification settings - Fork 44
网易云音乐API分析 weapi
该第二版 API 为最新版本,返回结构有大幅度变动,交互地址有个特征 weapi
所有交互需要指定两个参数:
key | value |
---|---|
referer | http://music.163.com |
Cookie | os=uwp; osver=10.0.10586.318; appver=1.2.1; |
下面列出的所有参数均为明文参数,实际提交需要进行加密,详见最下方第 7 条目
POST http://music.163.com/weapi/cloudsearch/get/web?csrf_token=
s: 关键字
limit: 返回数据条数限制
offset: 偏移数量,用于分页
total: true
csrf_token: 非关键操作,值可为空
type: 搜索类型
- 1 单曲
- 10 专辑
- 100 歌手
- 1000 歌单
- 1002 用户
- 1009 电台
- NULL 推荐(实测失效)
object(stdClass)#224 (2) {
["result"] => object(stdClass)#223 (2) {
["songs"] => array(30) {
[0] => object(stdClass)#7 (30) {
["rtUrls"] => array(0) {
}
["ar"] => array(1) {
[0] => object(stdClass)#6 (2) {
["id"] => int(46487)
["name"] => string(5) "Adele"
}
}
["al"] => object(stdClass)#5 (4) {
["id"] => int(3377030)
["name"] => string(5) "Hello"
["pic_str"] => string(16) "3388694837506899"
["pic"] => int(3388694837506899)
}
["st"] => int(0)
["cd"] => string(0) ""
["no"] => int(1)
["ftype"] => int(0)
["rtype"] => int(0)
["rurl"] => NULL
["t"] => int(0)
["v"] => int(11)
["a"] => NULL
["m"] => object(stdClass)#9 (4) {
["br"] => int(160000)
["fid"] => int(3294136840472685)
["size"] => int(5911554)
["vd"] => float(-2.95)
}
["pst"] => int(0)
["alia"] => array(0) {
}
["pop"] => float(100)
["rt"] => NULL
["mst"] => int(9)
["cp"] => int(390012)
["mv"] => int(501053)
["cf"] => string(0) ""
["dt"] => int(295502)
["h"] => object(stdClass)#8 (4) {
["br"] => int(320000)
["fid"] => int(3294136840472684)
["size"] => int(11823063)
["vd"] => float(-3.39)
}
["l"] => object(stdClass)#10 (4) {
["br"] => int(96000)
["fid"] => int(3294136840472686)
["size"] => int(3546950)
["vd"] => float(-2.97)
}
["crbt"] => NULL
["rtUrl"] => NULL
["fee"] => int(0)
["name"] => string(5) "Hello"
["id"] => int(35847388)
["privilege"] => object(stdClass)#11 (13) {
["id"] => int(35847388)
["fee"] => int(0)
["payed"] => int(0)
["st"] => int(0)
["pl"] => int(320000)
["dl"] => int(320000)
["sp"] => int(7)
["cp"] => int(1)
["subp"] => int(1)
["cs"] => bool(false)
["maxbr"] => int(999000)
["fl"] => int(320000)
["toast"] => bool(false)
}
}
...
}
["songCount"] => int(9999)
}
["code"] => int(200)
}
POST http://music.163.com/weapi/v1/album/{album_id}?csrf_token=
album_id: 专辑 ID,在 url 也需要包含
csrf_token: 非关键操作,值可为空
object(stdClass)#12 (3) {
["songs"] => array(1) {
[0] => object(stdClass)#7 (30) {
["rtUrls"] => array(0) {
}
["ar"] => array(1) {
[0] => object(stdClass)#6 (2) {
["id"] => int(46487)
["name"] => string(5) "Adele"
}
}
["al"] => object(stdClass)#5 (4) {
["id"] => int(3377030)
["name"] => string(5) "Hello"
["pic_str"] => string(16) "3388694837506899"
["pic"] => int(3388694837506899)
}
["st"] => int(0)
["a"] => NULL
["m"] => object(stdClass)#9 (4) {
["br"] => int(160000)
["fid"] => int(3294136840472685)
["size"] => int(5911554)
["vd"] => float(-2.95)
}
["no"] => int(1)
["v"] => int(11)
["t"] => int(0)
["cd"] => string(0) ""
["fee"] => int(0)
["ftype"] => int(0)
["rtype"] => int(0)
["rurl"] => NULL
["pst"] => int(0)
["alia"] => array(0) {
}
["pop"] => float(100)
["rt"] => NULL
["mst"] => int(9)
["cp"] => int(390012)
["mv"] => int(501053)
["cf"] => string(0) ""
["dt"] => int(295502)
["h"] => object(stdClass)#8 (4) {
["br"] => int(320000)
["fid"] => int(3294136840472684)
["size"] => int(11823063)
["vd"] => float(-3.39)
}
["l"] => object(stdClass)#10 (4) {
["br"] => int(96000)
["fid"] => int(3294136840472686)
["size"] => int(3546950)
["vd"] => float(-2.97)
}
["crbt"] => NULL
["rtUrl"] => NULL
["name"] => string(5) "Hello"
["id"] => int(35847388)
["privilege"] => object(stdClass)#11 (13) {
["id"] => int(35847388)
["fee"] => int(0)
["payed"] => int(0)
["st"] => int(0)
["pl"] => int(320000)
["dl"] => int(320000)
["sp"] => int(7)
["cp"] => int(1)
["subp"] => int(1)
["cs"] => bool(false)
["maxbr"] => int(999000)
["fl"] => int(320000)
["toast"] => bool(false)
}
}
}
["code"] => int(200)
["album"] => object(stdClass)#13 (24) {
["songs"] => array(0) {
}
["paid"] => bool(false)
["onSale"] => bool(false)
["status"] => int(0)
["alias"] => array(0) {
}
["picId"] => int(3388694837506899)
["company"] => string(13) "XL Recordings"
["picUrl"] => string(69) "http://p3.music.126.net/br3IrdCvT7-GjCyUVNONiA==/3388694837506899.jpg"
["briefDesc"] => NULL
["publishTime"] => int(1445529600007)
["artist"] => object(stdClass)#14 (12) {
["img1v1Id"] => int(0)
["musicSize"] => int(279)
["alias"] => array(1) {
[0] => string(24) "Adele Laurie Blue Adkins"
}
["picId"] => int(3263350518850889)
["trans"] => string(9) "阿黛尔"
["picUrl"] => string(69) "http://p3.music.126.net/_cSzHw9F-Nkgy9gb2QPI_A==/3263350518850889.jpg"
["briefDesc"] => string(0) ""
["albumSize"] => int(28)
["img1v1Url"] => string(69) "http://p3.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg"
["name"] => string(5) "Adele"
["id"] => int(46487)
["transNames"] => array(1) {
[0] => string(9) "阿黛尔"
}
}
["artists"] => array(1) {
[0] => object(stdClass)#15 (11) {
["img1v1Id"] => int(0)
["musicSize"] => int(0)
["alias"] => array(0) {
}
["picId"] => int(0)
["trans"] => string(0) ""
["picUrl"] => string(0) ""
["briefDesc"] => string(0) ""
["albumSize"] => int(0)
["img1v1Url"] => string(69) "http://p4.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg"
["name"] => string(5) "Adele"
["id"] => int(46487)
}
}
["blurPicUrl"] => string(69) "http://p3.music.126.net/br3IrdCvT7-GjCyUVNONiA==/3388694837506899.jpg"
["companyId"] => int(0)
["pic"] => int(3388694837506899)
["description"] => string(74) "Adele新专辑《25》首发单曲《Hello》于2015年10月23日发行。"
["tags"] => string(0) ""
["copyrightId"] => int(390012)
["commentThreadId"] => string(14) "R_AL_3_3377030"
["name"] => string(5) "Hello"
["id"] => int(3377030)
["type"] => string(9) "EP/Single"
["size"] => int(1)
["info"] => object(stdClass)#16 (9) {
["latestLikedUsers"] => NULL
["liked"] => bool(false)
["comments"] => NULL
["resourceType"] => int(3)
["resourceId"] => int(3377030)
["shareCount"] => int(413)
["commentCount"] => int(990)
["threadId"] => string(14) "R_AL_3_3377030"
["likedCount"] => int(0)
}
}
}
POST http://music.163.com/weapi/v3/playlist/detail?csrf_token=
id: 歌单 ID
csrf_token: 非关键操作,值可为空
object(stdClass)#14 (3) {
["playlist"] => object(stdClass)#7 (27) {
["subscribers"] => array(0) {
}
["subscribed"] => bool(false)
["creator"] => object(stdClass)#6 (24) {
["vipType"] => int(0)
["backgroundImgId"] => int(3441471400879005)
["avatarImgId"] => int(3427177752657109)
["userId"] => int(76696522)
["remarkName"] => NULL
["mutual"] => bool(false)
["djStatus"] => int(0)
["nickname"] => string(11) "ZAYN-MALIK-"
["avatarUrl"] => string(69) "http://p3.music.126.net/YjMiwnpbTMBvW7VEH_sk3Q==/3427177752657109.jpg"
["expertTags"] => NULL
["accountStatus"] => int(0)
["authStatus"] => int(0)
["detailDescription"] => string(0) ""
["followed"] => bool(false)
["province"] => int(1000000)
["defaultAvatar"] => bool(false)
["gender"] => int(2)
["birthday"] => int(1020441600000)
["city"] => int(1007700)
["backgroundUrl"] => string(69) "http://p1.music.126.net/AzJdp8YtwCvKNCDnQ2Yu4g==/3441471400879005.jpg"
["userType"] => int(0)
["description"] => string(0) ""
["signature"] => string(34) "爱1D,Zayn,Westlife,Shane,Troye..."
["authority"] => int(0)
}
["tracks"] => array(1) {
[0] => object(stdClass)#5 (29) {
["rtUrls"] => array(0) {
}
["ar"] => array(1) {
[0] => object(stdClass)#9 (2) {
["id"] => int(46487)
["name"] => string(5) "Adele"
}
}
["al"] => object(stdClass)#8 (4) {
["id"] => int(3377030)
["name"] => string(5) "Hello"
["pic_str"] => string(16) "3388694837506899"
["pic"] => int(3388694837506899)
}
["st"] => int(0)
["cd"] => string(0) ""
["no"] => int(1)
["fee"] => int(0)
["ftype"] => int(0)
["rtype"] => int(0)
["rurl"] => NULL
["t"] => int(0)
["v"] => int(11)
["a"] => NULL
["m"] => object(stdClass)#10 (4) {
["br"] => int(160000)
["fid"] => int(3294136840472685)
["size"] => int(5911554)
["vd"] => float(-2.95)
}
["crbt"] => NULL
["rtUrl"] => NULL
["pst"] => int(0)
["alia"] => array(0) {
}
["pop"] => float(100)
["rt"] => NULL
["mst"] => int(9)
["cp"] => int(390012)
["mv"] => int(501053)
["cf"] => string(0) ""
["dt"] => int(295502)
["h"] => object(stdClass)#11 (4) {
["br"] => int(320000)
["fid"] => int(3294136840472684)
["size"] => int(11823063)
["vd"] => float(-3.39)
}
["l"] => object(stdClass)#12 (4) {
["br"] => int(96000)
["fid"] => int(3294136840472686)
["size"] => int(3546950)
["vd"] => float(-2.97)
}
["name"] => string(5) "Hello"
["id"] => int(35847388)
}
}
["trackIds"] => array(1) {
[0] => object(stdClass)#13 (2) {
["id"] => int(35847388)
["v"] => int(11)
}
}
["cloudTrackCount"] => int(0)
["trackNumberUpdateTime"] => int(1446884413425)
["adType"] => int(0)
["status"] => int(0)
["playCount"] => int(10)
["updateTime"] => int(1446884413425)
["userId"] => int(76696522)
["trackCount"] => int(1)
["commentThreadId"] => string(16) "A_PL_0_124394335"
["coverImgId"] => int(3388694837506899)
["specialType"] => int(0)
["createTime"] => int(1446884412646)
["highQuality"] => bool(false)
["subscribedCount"] => int(0)
["trackUpdateTime"] => int(1467984278182)
["newImported"] => bool(false)
["description"] => NULL
["tags"] => array(0) {
}
["name"] => string(11) "Hello,Adele"
["id"] => int(124394335)
["shareCount"] => int(0)
["commentCount"] => int(0)
}
["code"] => int(200)
["privileges"] => array(1) {
[0] => object(stdClass)#15 (13) {
["id"] => int(35847388)
["fee"] => int(0)
["payed"] => int(0)
["st"] => int(0)
["pl"] => int(320000)
["dl"] => int(320000)
["sp"] => int(7)
["cp"] => int(1)
["subp"] => int(1)
["cs"] => bool(false)
["maxbr"] => int(999000)
["fl"] => int(320000)
["toast"] => bool(false)
}
}
}
POST http://music.163.com/weapi/v3/song/detail
c: Json 格式字符串,格式如:[{"id":3377030}]
csrf_token: 非关键操作,值可为空
object(stdClass)#11 (2) {
["songs"] => array(1) {
[0] => object(stdClass)#7 (29) {
["rtUrls"] => array(0) {
}
["ar"] => array(1) {
[0] => object(stdClass)#6 (2) {
["id"] => int(46487)
["name"] => string(5) "Adele"
}
}
["al"] => object(stdClass)#5 (4) {
["id"] => int(3377030)
["name"] => string(5) "Hello"
["pic_str"] => string(16) "3388694837506899"
["pic"] => int(3388694837506899)
}
["st"] => int(0)
["ftype"] => int(0)
["rtype"] => int(0)
["rurl"] => NULL
["t"] => int(0)
["v"] => int(11)
["no"] => int(1)
["pst"] => int(0)
["alia"] => array(0) {
}
["pop"] => float(100)
["rt"] => NULL
["mst"] => int(9)
["cp"] => int(390012)
["mv"] => int(501053)
["cf"] => string(0) ""
["dt"] => int(295502)
["h"] => object(stdClass)#9 (4) {
["br"] => int(320000)
["fid"] => int(3294136840472684)
["size"] => int(11823063)
["vd"] => float(-3.39)
}
["l"] => object(stdClass)#8 (4) {
["br"] => int(96000)
["fid"] => int(3294136840472686)
["size"] => int(3546950)
["vd"] => float(-2.97)
}
["a"] => NULL
["m"] => object(stdClass)#10 (4) {
["br"] => int(160000)
["fid"] => int(3294136840472685)
["size"] => int(5911554)
["vd"] => float(-2.95)
}
["fee"] => int(0)
["cd"] => string(0) ""
["crbt"] => NULL
["rtUrl"] => NULL
["name"] => string(5) "Hello"
["id"] => int(35847388)
}
}
["code"] => int(200)
}
POST http://music.163.com/weapi/song/enhance/player/url?csrf_token=
id: 歌单 ID
br: 比特率,320000
csrf_token: 非关键操作,值可为空
object(stdClass)#6 (2) {
["data"] => array(1) {
[0] => object(stdClass)#7 (14) {
["id"] => int(35847388)
["url"] => string(130) "http://m8.music.126.net/20160711164257/ead9b97be441c8841dec2f624652bc1c/ymusic/a3bc/b02c/b25b/7a1f79bb4c732d4bd2a2ab967c2bb7d1.mp3"
["br"] => int(320000)
["size"] => int(11823063)
["md5"] => string(32) "7a1f79bb4c732d4bd2a2ab967c2bb7d1"
["code"] => int(200)
["expi"] => int(1200)
["type"] => string(3) "mp3"
["gain"] => float(-3.38)
["fee"] => int(0)
["uf"] => NULL
["payed"] => int(0)
["flag"] => int(0)
["canExtend"] => bool(false)
}
}
["code"] => int(200)
}
http://m8.music.126.net/[expTime]/[token]/ymusic/[key1]/[key2]/[key3]/[MD5].mp3
expTime: 过期时间戳,标识本 URL 只能在过期时间前请求,否则返回 403 token: 随 expTime 变动,为校验码,加密方式尚不清楚 key123: 固定值,随歌曲 md5 而改变,我还没搞明白,求大神们指教 MD5: 该歌曲的 MD5 校验码,小写
实际请求的参数应当加密为如下形式:
params: Db3xGrqMzXwQqWAIe7AlqILYssUuypZlUS+6Dr8g//OEK8SPpjsZht2j+/C+UZ/rAh1bsXoFDEZxQUwdVB5oc1nSRRT3gpmRgzmwhR8yBCboIk+Uf8PvV2azs2WQ10zewCEps4IAIW1Dbes4jxGcEh7pmUXurQQcrjf9VjzOp64XwKuzunQbb0JG8CwybMIyHjWAC6osTnopHVkSikLsMggTLCVADoK3s+a75VWaYY0srdCoS3FJq8tvvnVGim6k3TpsFkiII/r5DCm8EyvfLrZcsiB5Kpx96ZjxZXYw4yU=
encSecKey: 8ac3219a491bfde0c81532fb4d6c8cd919cc2613631f11a82a72a1fd02e535eb5fbce3c51e7bb8ad2ba06590c391ddec326aa6d6535f36bcb2dd074cf9601f1e874fbfe96787f341d824ea8f03781713355e745472949cb44d8b4c6ed1c76944e2d684add7e746f8ab6119caa7270dd3373320345d946dfb2647c66ab6ef51e5
其中 params 为 AES 对称加密后的参数,encSecKey 为 RSA 加密后的 AES 密钥。 所有公钥等参数详见代码,这里不列出。
AES 密钥需要随机,否则服务器会 dump 掉相同密钥的请求(数量多的话)。
密钥的形式为 16 位随机字母或数字,[0-9a-zA-Z]
function createSecretKey($length=16){
$str='0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$r='';
for($i=0;$i<$length;$i++){
$r.=$str[rand(0,strlen($str)-1)];
}
return $r;
}
在上述 API 中,首先将 POST 参数值拼写为如下形式,以搜索 hello
为例:
{"s":"hello","type":"1","limit":"1000","offset":"0","csrf_token":""}
然后对上面的明文进行两次 AES 加密,第一次密钥为 nonce,第二次为第一步生成的密钥。
$data['params']=$this->aes_encode($string,$this->_nonce);
$data['params']=$this->aes_encode($data['params'],$this->_secretKey);
AES 加密的具体算法为:AES-128-CBC
,输出格式为 base64
AES 加密时需要指定 iv:0102030405060708
本步骤加密后的结果即为 params
最后对第一步生成的 secretKey 进行 RSA 加密,不过这个加密非常诡异,不是标准的形式。下面引用 darknessomi
的结论
RSA 加密采用非常规填充方式,既不是
PKCS1
也不是PKCS1_OAEP
,网易的做法是直接向前补0
这样加密出来的密文有个特点:加密过程没有随机因素,明文多次加密后得到的密文是相同的
然而,我们常用的RSA
加密模块均不支持此种加密,所以需要手写一段简单的RSA
加密
加密过程convertUtf8toHex(reversedText)^e%N
输入过程中需要对加密字符串进行hex
格式转码
PHP 中需要使用大数运算类,如果嫌不够清真的话可以自己实现,需要使用快速幂算法加速
function rsa_encode($text){
$rtext=strrev(utf8_encode($text));
$keytext=$this->bchexdec($this->strToHex($rtext));
$a=new Math_BigInteger($keytext);
$b=new Math_BigInteger($this->bchexdec($this->_pubKey));
$c=new Math_BigInteger($this->bchexdec($this->_modulus));
$key=$a->modPow($b, $c)->toHex();
return str_pad($key,256,'0',STR_PAD_LEFT);
}
function bchexdec($hex){
$dec=0;
$len=strlen($hex);
for($i=0;$i<$len;$i++) {
$dec=bcadd($dec,bcmul(strval(hexdec($hex[$i])),bcpow('16',strval($len-$i-1))));
}
return $dec;
}
function strToHex($str){
$hex='';
for($i=0;$i<strlen($str);$i++){
$hex.=dechex(ord($str[$i]));
}
return $hex;
}
本步骤加密后的结果即为 encSecKey