Java 使用HttpURLConnection获取网易云(我喜欢的音乐)歌单歌单内歌曲
1.HttpURLConnection简介2.前期准备2.1 目标url2.2 歌曲ID获得2.3 uerkey的获取 3.代码实现4.结果如果不想看前面的逼逼赖赖,可以直接 ——>点击跳转
跳到代码部分。
1.HttpURLConnection简介
JDK的包中提供了访问HTTP协议的基本功能的类:HttpURLConnection。
HttpURLConnection的父类为:URLConnection,其是个抽象类,它有两个直接子类分别是HttpURLConnection和JarURLConnection。另外一个重要的类是URL,通常URL可以通过传给构造器一个String类型的参数来生成一个指向特定地址的URL实例。
HttpURLConnection是Java的标准类,它继承自URLConnection,可用于向指定网站发送GET请求、POST请求,也可以根据自身具体需求设置请求头或响应头,并获取目标连接的响应内容。
想要具体了解HttpURLConnection可以查看详解HttpURLConnection
2.前期准备
2.1 目标url
根据其他大佬的发布,我们很容易就可以知道网易云的歌单信息接口为:
/api/playlist/detail?id=
而id后的参数为要获取的歌单的id。
假设我们要获取歌单为:
其歌单id为:2294396974的歌单的歌曲,则完整的请求路径url为:
/api/playlist/detail?id=2294396974
直接访问连接,可以看到返回数据如下:
复制得到的数据,使用json在线解析网站可以得到:
对比网易云的歌单内容,可以发现 " result " 下的 " tracks "便是我们需要的歌曲信息数组,说明url接口正确,这个接口也就是我们本次要使用到的接口。
2.2 歌曲ID获得
得到了请求的接口,那我们如何得到我们需要获取的歌单的歌单ID呢?
这个反而是最简单的一步,在网易云官网中点击我们想要获取的歌单,例如:
点击后在地址栏中,我们可以看到:
id=5398806550中的5398806550便是歌单的歌单ID
按照这个方法,我们就可以看到自己的歌单中(我喜欢的音乐)的歌单ID。
2.3 uerkey的获取
正常来说,拿到目标url和要请求的歌单ID后,我们就可以开始写代码,但是我们重新回到之前请求得到的歌单json数据,如果对比我们拿到的数据和网易云官网的歌单数据,会发现:接口返回的歌单数据只有前10首歌曲。
这显然与我们想获取歌单的所有歌曲的目标不符,其实这个情况的出现是因为我们未登录网易云账号,接口便只能返回前10首歌曲。
那如何让接口认为我们是登录状态呢?
这个时候就要需要我们做一些骚操作了:
打开网易云官网,先退出自己的账号,然后再准备登录自己的账号,我这里是使用的手机账号登录。在登录账号之前,先使用F12打开控制台,这里我用的谷歌浏览器,找到Network选项,先清空之前的日志:
然后登录自己的网易云账号,登录后在查看日志,找到图中这一条:
点开下拉,找到set-cookie
其中,__csrf和MUSIC_U参数就是我们需要的。
在正常的访问中,网易云官网就是通过查看你的cookie中是否有这两个参数来判断你是否已经登录,所以我们需要在请求过程中设置cookie,带上这两个参数。
3.代码实现
好了,现在已经完事具备,可以直接开始代码的编写了,话不多说,直接上代码:
package tools;import net.sf.json.JSONArray;import net.sf.json.JSONObject;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import .HttpURLConnection;import .URL;public class Detail_Get {public static JSONObject GET_Date(String DetailId, String userKey) {String Url = "/api/playlist/detail?id=" + DetailId;String date = httpURLConnection(Url,userKey);JSONObject jsonObject = JSON_Processing(date);return jsonObject;}private static String httpURLConnection(String Url,String userKey) {StringBuilder sBuilder = null;try {URL url = new URL(Url);HttpURLConnection connection = (HttpURLConnection) url.openConnection();//设置请求头,带上cookie参数connection.setRequestProperty("cookie",userKey);//一定要先设置,再开始连接connection.connect();//读取接口响应的数据BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream(),"UTF-8"));String line;sBuilder = new StringBuilder();while ((line = br.readLine()) != null) {sBuilder.append(line);}br.close();connection.disconnect();} catch (IOException e) {e.printStackTrace();}return sBuilder.toString();}//对响应的歌单数据进行处理private static JSONObject JSON_Processing(String date) {String DetailName = JSONObject.fromObject(date).getJSONObject("result").getString("name");JSONArray Detail_Array = JSONObject.fromObject(date).getJSONObject("result").getJSONArray("tracks");JSONObject Music_JsonObject;JSONArray list = new JSONArray();int play_time, minute, second;System.out.println(Detail_Array.size());for (int i = 0; i < Detail_Array.size(); ++i) {JSONObject map = new JSONObject();Music_JsonObject = (JSONObject) Detail_Array.get(i);map.put("name", Music_JsonObject.getString("name"));//歌曲的歌名map.put("id", Music_JsonObject.getString("id"));//歌曲的ID//歌曲歌手的姓名map.put("Singer", ((JSONObject) (Music_JsonObject.getJSONArray("artists").get(0))).getString("name"));//歌曲的播放时长,初始时间为毫秒,将其处理转为(分:秒)形式play_time = (Music_JsonObject.getInt("duration"));minute = play_time / 60000; //分钟second = play_time / 1000 % 60; //秒if (second >= 10) {map.put("time", minute + ":" + second);} else {map.put("time", minute + ":0" + second);}//歌曲的封面图片url地址map.put("image", Music_JsonObject.getJSONObject("album").getString("picUrl"));//判断歌曲是否为付费歌曲,主要看if (Music_JsonObject.getInt("fee") == 1) {map.put("vip", "true");} else {map.put("vip", "false");}list.add(map);}JSONObject jsonObject = new JSONObject();jsonObject.put("DetailName",DetailName);jsonObject.put("DetailMusic",list);return jsonObject;}public static void main(String[] args) {//userKey的形式为:__csrf=**********;MUSIC_U=*************;String DetailId = "******";String userkey = "__csrf=**********;MUSIC_U=*************;"JSONObject jsonObject = GET_Date(DetailId ,userkey);System.out.println(jsonObject);}}
因为接口响应回来的数据为json形式,所以我使用到了json的类来处理返回的数据。
这里我只拿取并输出了歌单中歌单的歌单名,歌曲的歌名,歌曲ID,歌手姓名,歌曲时长。其他的数据可以根据自己自身的需要拿取。
至于我为什么要拿取歌曲ID,当然是想用这个ID搞其他事情啦,如果后面有时间的话,我也会再写通过歌曲ID来得到歌曲,实现在自己写的网页上播放网易云歌曲的效果。
通过这个可以拿到我喜欢的歌曲的歌单的所有数据,也可以获得其他的歌单的歌曲,但出于网易云的限制,如果不是自己创建的歌单,在网页端则只能获得前20首歌曲。
而如果觉得获取__csrf和MUSIC_U参数麻烦,或者不介意的同志,可以令userKey为空字符串:String userKey = "";
,但是这样便只能获取前10首的歌曲,可以根据自己的需求取舍。
4.结果
最后展示一下代码实现的结果,这里我获取的是我自己的歌单,输出如下: