最近有点闲,听歌的时候遇见好听的想下载却遇到尴尬的事,版权!唉,知道我干什么了吧

网易云音乐

  获取排行榜中的歌曲列表

    https://music.163.com/discover/toplist?id=

    参数id:左侧分类的id,比如云音乐热歌榜:3778678

  获取具体歌曲链接

    http://music.163.com/weapi/song/enhance/player/url?csrf_token=&ids=xxx&br=999000

    参数:ids:歌曲id集合,br歌曲码率

  获取歌词:

    http://music.163.com/weapi/song/lyric?csrf_token=&id=xxx&os=pc&lv-1&kv=-1&tv=-1

    参数:id:歌曲id  

网易云的参数先经过JSON序列化然后进行加密,所有加密代码:

需要用到的一些Head及参数:

  1. #region 属性
  2. private string _MODULUS = "00e0b509f6259df8642dbc35662901477df22677ec152b5ff68ace615bb7b725152b3ab17a876aea8a5aa76d2e417629ec4ee341f56135fccf695280104e0312ecbda92557c93870114af6c9d05c4f7f0c3685b7a46bee255932575cce10b424d813cfe4875d3e82047b97ddef52741d546b8e289dc6935b3ece0462db0a22b8e7";
  3. private string _NONCE = "0CoJUm6Qyw8W8jud";
  4. private string _PUBKEY = "";
  5. private string _VI = "";
  6. private string _USERAGENT = "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36";
  7. private string _COOKIE = "os=pc;osver=Microsoft-Windows-10-Professional-build-16299.125-64bit;appver=2.0.3.131777;channel=netease;__remember_me=true";
  8. private string _REFERER = "http://music.163.com/";
  9. // use keygen in c#
  10. private string _secretKey;
  11. private string _encSecKey;
  12. #endregion

加密方法:

  1. private string CreateSecretKey(int length)
  2. {
  3. var str = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
  4. var r = "";
  5. var rnd = new Random();
  6. for (int i = ; i < length; i++)
  7. {
  8. r += str[rnd.Next(, str.Length)];
  9. }
  10. return r;
  11. }
  12. private Dictionary<string, string> Prepare(string raw)
  13. {
  14. Dictionary<string, string> data = new Dictionary<string, string>();
  15. data["params"] = AESEncode(raw, _NONCE);
  16. data["params"] = AESEncode(data["params"], _secretKey);
  17. data["encSecKey"] = _encSecKey;
  18.  
  19. return data;
  20. }
  21. private string RSAEncode(string text)
  22. {
  23. string srtext = new string(text.Reverse().ToArray()); ;
  24. var a = BCHexDec(BitConverter.ToString(Encoding.Default.GetBytes(srtext)).Replace("-", ""));
  25. var b = BCHexDec(_PUBKEY);
  26. var c = BCHexDec(_MODULUS);
  27. var key = BigInteger.ModPow(a, b, c).ToString("x");
  28. key = key.PadLeft(, '');
  29. if (key.Length > )
  30. return key.Substring(key.Length - , );
  31. else
  32. return key;
  33. }
  34.  
  35. private BigInteger BCHexDec(string hex)
  36. {
  37. BigInteger dec = new BigInteger();
  38. int len = hex.Length;
  39. for (int i = ; i < len; i++)
  40. {
  41. dec += BigInteger.Multiply(new BigInteger(Convert.ToInt32(hex[i].ToString(), )), BigInteger.Pow(new BigInteger(), len - i - ));
  42. }
  43. return dec;
  44. }
  45.  
  46. private string AESEncode(string secretData, string secret = "TA3YiYCfY2dDJQgg")
  47. {
  48. byte[] encrypted;
  49. byte[] IV = Encoding.UTF8.GetBytes(_VI);
  50.  
  51. using (var aes = Aes.Create())
  52. {
  53. aes.Key = Encoding.UTF8.GetBytes(secret);
  54. aes.IV = IV;
  55. aes.Mode = CipherMode.CBC;
  56. using (var encryptor = aes.CreateEncryptor())
  57. {
  58. using (var stream = new MemoryStream())
  59. {
  60. using (var cstream = new CryptoStream(stream, encryptor, CryptoStreamMode.Write))
  61. {
  62. using (var sw = new StreamWriter(cstream))
  63. {
  64. sw.Write(secretData);
  65. }
  66. encrypted = stream.ToArray();
  67. }
  68. }
  69. }
  70. }
  71. return Convert.ToBase64String(encrypted);
  72. }
  73. private string CURL(string url, Dictionary<string, string> parms, string method = "POST")
  74. {
  75. string result;
  76. using (var wc = new WebClient())
  77. {
  78. wc.Headers.Add(HttpRequestHeader.ContentType, "application/x-www-form-urlencoded");
  79. wc.Headers.Add(HttpRequestHeader.Referer, _REFERER);
  80. wc.Headers.Add(HttpRequestHeader.UserAgent, _USERAGENT);
  81. wc.Headers.Add(HttpRequestHeader.Cookie, _COOKIE);
  82. var reqparm = new System.Collections.Specialized.NameValueCollection();
  83. foreach (var keyPair in parms)
  84. {
  85. reqparm.Add(keyPair.Key, keyPair.Value);
  86. }
  87.  
  88. byte[] responsebytes = wc.UploadValues(url, method, reqparm);
  89. result = Encoding.UTF8.GetString(responsebytes);
  90. }
  91. return result;
  92. }

获取歌曲详情调用方法:

  1. public DetailResult Detail(long song_id)
  2. {
  3. string url = "http://music.163.com/weapi/v3/song/detail?csrf_token=";
  4. var data = new Dictionary<string, string> {
  5. { "c",
  6. "[" + JsonConvert.SerializeObject(new Dictionary<string, string> { //神tm 加密的json里套json mdzz (说不定一次可以查多首歌?)
  7. { "id", song_id.ToString() }
  8. }) + "]"
  9. },
  10. {"csrf_token",""},
  11. };
  12. string raw = CURL(url, Prepare(JsonConvert.SerializeObject(data)));
  13.  
  14. var deserialedObj = JsonConvert.DeserializeObject<DetailResult>(raw);
  15. return deserialedObj;
  16. }

QQ音乐

  获取排行榜类别

    https://c.y.qq.com/v8/fcg-bin/fcg_v8_toplist_opt.fcg?page=index&format=html&tpl=macv4&v8debug=1

  获取排行榜中的歌曲

    https://c.y.qq.com/v8/fcg-bin/fcg_v8_toplist_cp.fcg?tpl=3&page=detail&date={update_key}&topid={Id}&type=top&song_begin=0&song_num=30}&g_tk=5381&loginUin=0&hostUin=0&format=json&inCharset=utf8&outCharset=utf-8&notice=0&platform=yqq.json&needNewCode=0

  参数:id:排行榜的类别id,song_num 每页显示的条数

  获取歌曲链接

    https://u.y.qq.com/cgi-bin/musicu.fcg?-=getplaysongvkey7202785251801513&g_tk=5381&loginUin=0&hostUin=0&format=json&inCharset=utf8&outCharset=utf-8&notice=0&platform=yqq.json&needNewCode=0&data=%7B%22req%22%3A%7B%22module%22%3A%22CDN.SrfCdnDispatchServer%22%2C%22method%22%3A%22GetCdnDispatch%22%2C%22param%22%3A%7B%22guid%22%3A%229756534816%22%2C%22calltype%22%3A0%2C%22userip%22%3A%22%22%7D%7D%2C%22req_0%22%3A%7B%22module%22%3A%22vkey.GetVkeyServer%22%2C%22method%22%3A%22CgiGetVkey%22%2C%22param%22%3A%7B%22guid%22%3A%226541487400%22%2C%22songmid%22%3A%5B%22{mid}%22%5D%2C%22songtype%22%3A%5B0%5D%2C%22uin%22%3A%220%22%2C%22loginflag%22%3A1%2C%22platform%22%3A%2220%22%7D%7D%2C%22comm%22%3A%7B%22uin%22%3A0%2C%22format%22%3A%22json%22%2C%22ct%22%3A20%2C%22cv%22%3A0%7D%7D

    参数:mid:歌曲的mid  

  1. private string GetSongUrl(string mid)
  2. {
  3. var url = $"https://u.y.qq.com/cgi-bin/musicu.fcg?-=getplaysongvkey7202785251801513&g_tk=5381&loginUin=0&hostUin=0&format=json&inCharset=utf8&outCharset=utf-8&notice=0&platform=yqq.json&needNewCode=0&data=%7B%22req%22%3A%7B%22module%22%3A%22CDN.SrfCdnDispatchServer%22%2C%22method%22%3A%22GetCdnDispatch%22%2C%22param%22%3A%7B%22guid%22%3A%229756534816%22%2C%22calltype%22%3A0%2C%22userip%22%3A%22%22%7D%7D%2C%22req_0%22%3A%7B%22module%22%3A%22vkey.GetVkeyServer%22%2C%22method%22%3A%22CgiGetVkey%22%2C%22param%22%3A%7B%22guid%22%3A%226541487400%22%2C%22songmid%22%3A%5B%22{mid}%22%5D%2C%22songtype%22%3A%5B0%5D%2C%22uin%22%3A%220%22%2C%22loginflag%22%3A1%2C%22platform%22%3A%2220%22%7D%7D%2C%22comm%22%3A%7B%22uin%22%3A0%2C%22format%22%3A%22json%22%2C%22ct%22%3A20%2C%22cv%22%3A0%7D%7D";
  4. WebClient client = new WebClient();
  5. client.Encoding = Encoding.UTF8;
  6. var result = client.DownloadString(url);
  7. }

  获取歌词:

    https://c.y.qq.com/lyric/fcgi-bin/fcg_query_lyric_new.fcg?songmid={songmid}&g_tk=5381

    参数:songmid:歌曲id    

  1. var url = $"https://c.y.qq.com/lyric/fcgi-bin/fcg_query_lyric_new.fcg?songmid={songmid}&g_tk=5381";
  2. WebClient client = new WebClient();
  3.  
  4. client.Headers.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.110 Safari/537.36");
  5. client.Headers.Add("Accept", "*/*");
  6. client.Headers.Add("Referer", "https://y.qq.com/portal/player.html");
  7. client.Headers.Add("Accept-Language", "zh-CN,zh;q=0.8");
  8. client.Headers.Add("Cookie", "tvfe_boss_uuid=c3db0dcc4d677c60; pac_uid=1_2728578956; qq_slist_autoplay=on; ts_refer=ADTAGh5_playsong; RK=pKOOKi2f1O; pgv_pvi=8927113216; o_cookie=2728578956; pgv_pvid=5107924810; ptui_loginuin=2728578956; ptcz=897c17d7e17ae9009e018ebf3f818355147a3a26c6c67a63ae949e24758baa2d; pt2gguin=o2728578956; pgv_si=s5715204096; qqmusic_fromtag=66; yplayer_open=1; ts_last=y.qq.com/portal/player.html; ts_uid=996779984; yq_index=0");
  9.  
  10. client.Headers.Add("Host", "c.y.qq.com");
  11. var result = client.DownloadString(url);
  12. result = result.Substring(result.IndexOf('(') + );
  13. result = result.Substring(, result.LastIndexOf(')'));
  14. var data = JsonConvert.DeserializeObject<dynamic>(result);

歌词是经过base64进行加密的,所以获取后需要进行base64解密

  1. /// <summary>
  2. /// Base64解码
  3. /// </summary>
  4. /// <param name="Message"></param>
  5. /// <returns></returns>
  6. public static string Base64Decode(string Message)
  7. {
  8. if ((Message.Length % ) != )
  9. {
  10. throw new ArgumentException("不是正确的BASE64编码,请检查。", "Message");
  11. }
  12. if (!System.Text.RegularExpressions.Regex.IsMatch(Message, "^[A-Z0-9/+=]*$", System.Text.RegularExpressions.RegexOptions.IgnoreCase))
  13. {
  14. throw new ArgumentException("包含不正确的BASE64编码,请检查。", "Message");
  15. }
  16. string Base64Code = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
  17. int page = Message.Length / ;
  18. System.Collections.ArrayList outMessage = new System.Collections.ArrayList(page * );
  19. char[] message = Message.ToCharArray();
  20. for (int i = ; i < page; i++)
  21. {
  22. byte[] instr = new byte[];
  23. instr[] = (byte)Base64Code.IndexOf(message[i * ]);
  24. instr[] = (byte)Base64Code.IndexOf(message[i * + ]);
  25. instr[] = (byte)Base64Code.IndexOf(message[i * + ]);
  26. instr[] = (byte)Base64Code.IndexOf(message[i * + ]);
  27. byte[] outstr = new byte[];
  28. outstr[] = (byte)((instr[] << ) ^ ((instr[] & 0x30) >> ));
  29. if (instr[] != )
  30. {
  31. outstr[] = (byte)((instr[] << ) ^ ((instr[] & 0x3c) >> ));
  32. }
  33. else
  34. {
  35. outstr[] = ;
  36. }
  37. if (instr[] != )
  38. {
  39. outstr[] = (byte)((instr[] << ) ^ instr[]);
  40. }
  41. else
  42. {
  43. outstr[] = ;
  44. }
  45. outMessage.Add(outstr[]);
  46. if (outstr[] != )
  47. outMessage.Add(outstr[]);
  48. if (outstr[] != )
  49. outMessage.Add(outstr[]);
  50. }
  51. byte[] outbyte = (byte[])outMessage.ToArray(Type.GetType("System.Byte"));
  52. return Encoding.UTF8.GetString(outbyte);
  53. }

完整项目地址:Demo

网易云和QQ音乐api的更多相关文章

  1. 【QQ音乐Api】移花接木 打造自己的音乐电台

    最近突发奇想想做个在线音乐小网页.需求很简单,如下 搜索歌曲 或 歌手 在线播放音乐 借用qq 或者 百度的 音乐接口 需求明确那就直接动手了 我首先尝试的百度音乐,但是不能在线播放(提示forbid ...

  2. QQ音乐API

    今天分享的是QQ音乐API 搜索歌曲API:http://s.music.qq.com/fcgi-bin/music_search_new_platform?t=0& amp;n={2}&am ...

  3. QQ音乐API分析记录

    我一直是QQ音乐的用户,最近想做一个应用,想用QQ音乐的API,搜索了很久无果,于是就自己分析QQ音乐的API. 前不久发现QQ音乐出了网页版的,是Flash的,但是,我用iPhone打开这个链接的时 ...

  4. 调皮的QQ音乐API:修复无法获取歌单

    上一篇完整版:http://www.cnblogs.com/TwilightLemon/p/7076938.html QQ音乐的API真是太调皮了,获取歌单的API又更换了好多次,喵喵喵 旧版API( ...

  5. 使用浏览器抓取QQ音乐接口(歌曲篇)

    前言 前面我们获取了歌曲的排行榜的数据,我们现在需要实现歌曲播放 前面我们写了一段函数来得到了回调的数据,现在我们需要使用这一段数据,来实现播放歌曲 完整代码 <!DOCTYPE html> ...

  6. QQ音乐的各种相关API

    QQ音乐的各种相关API 分类: oc2014-01-29 15:34 2676人阅读 评论(2) 收藏 举报 基本上论坛里做在线音乐的都在用百度的API,进来发现百度的API不仅歌曲的质量不可以保证 ...

  7. 网易音乐API

    本次分析的是网易音乐API 歌曲搜索API:http://music.163.com/api/search/get/web?csrf_token= 需要用POST来获取 参数: Referer=htt ...

  8. 音乐API之QQ音乐

    欢迎大家来到我的博客,这是我在博客园写的第一篇文章,但不会是最后一篇,希望大家多多关注我,支持我哦!正文开始,今天我们要讲的是QQ音乐的API,都是来源于官方的地址,以前我也想写一个,但百度谷歌之后都 ...

  9. QQ音乐无损歌曲接口api

    1.打开QQ音乐官网 y.qq.com 2.选择你要的歌曲,进入后查看网址,以虎口脱险这个歌曲为例:http://y.qq.com/#type=song&mid=000Ib8E71sUNi7 ...

随机推荐

  1. SQLI DUMB SERIES-20

    (1)登录成功后页面: (2)登录成功后,用burp开始抓包,刷新浏览器页面,将会跳出如下页面 (3)根据各种提示,知道需要从cookies入手,寻找闭合方式 闭合方式为单引号.注释符也可以用 (4) ...

  2. web h5常用代码总结

    注意:本文原创,转载请说明出处 1.使图片和文字水平居中,给图片css样式:vertical-align: middle;vertical-align:middle的时候,是该元素的中心对齐周围元素的 ...

  3. for循环、while循环、break、continue、exit

    1. for循环 语法:for 变量名 in 条件; do …; done案例1 #!/bin/bashsum=0for i in `seq 1 100`do# echo "$sum + $ ...

  4. useful urls

    数据挖掘技术: http://ddl.escience.cn/f/IwoF?rid=8188575 李航 统计学习方法: http://ddl.escience.cn/f/Iwn0

  5. 2018.9.12 B树总结

    1. B-Tree B-树是一种平衡的多路查找树,它在文件系统中很有用. 1.1 B-Tree 特性 关键字集合分布在整颗树中: 任何一个关键字出现且只出现在一个结点中: 搜索有可能在非叶子结点结束: ...

  6. centos7常用命令

    系统命令 shutdown -h now # 关机 shutdown -r now # 重启 reboot # 重启 systemctl status firewalld # 查看防火墙状态 syst ...

  7. D类IP地址和组播传输

    在224.0.0.0-239.255.255.255范围内的地址称为D类IP组播地址.其中,224.0.0.0-224.0.0.255为预留的组播地址(永久组地址),地址224.0.0.0保留不做分配 ...

  8. webpack 配置别名,解决 import 时路径查找麻烦的问题

    在编写代码时,使用 import 导入别的文件,可能会遇到查找路径麻烦的问题 比如这里的 ../../ 还要去思考多少个 ../ 那么可以在 webpack 中,将 src 目录设置一个别名,方便文件 ...

  9. Jrebel 配置

    先下载插件 http://139.199.89.239:1008/88414687-3b91-4286-89ba-2dc813b107ce http://jrebel.autoseasy.cn/xix ...

  10. WinForm控件开发总结目录

    WinForm控件开发总结(一)------开篇 WinForm控件开发总结(二)------使用和调试自定义控件 WinForm控件开发总结(三)------认识WinForm控件常用的Attrib ...