获取网易云音乐开放接口api的推荐歌单
网易云音乐开放api接口
网址:https://binaryify.github.io/NeteaseCloudMusicApi/#/?id=neteasecloudmusicapi
项目地址:https://github.com/Binaryify/NeteaseCloudMusicApi
下载下来之后,安装依赖:npm install
启动服务: node app.js
启动成功之后,根据api接口文档就可以获取请求的url了。
本文需求是,获取推荐歌单30张,并把数据存储到MySQL数据库,并且根据每张歌单的图片url将图片下载下来存到本地。
先看一下获取歌单列表的api文档
文档地址:https://binaryify.github.io/NeteaseCloudMusicApi/#/?id=neteasecloudmusicapi
全局搜索Ctrl + F 推荐歌单,可以看到一个api
试一试看能不能得到数据
把项目启动,网址输入:50张歌单
http://localhost:3000/personalized?limit=50
可以得到数据,现在来存储到数据库,并且下载图片
先看一下数据结构,存储哪些数据
这里我们只要歌单的id,picUrl,name,playCount
先建表
springboot连接数据库,代码生成controller,service,mapper等,使用mybatis-plus
先存储
controller:
/** * 获取歌单列表 * api接口地址:https://binaryify.github.io/NeteaseCloudMusicApi/#/?id=neteasecloudmusicapi * 项目地址:https://github.com/Binaryify/NeteaseCloudMusicApi * 下载下来之后 * npm install * 运行 node app.js * 默认运行端口:3000 */ @GetMapping("/getListSongs") public ResponseWrapper getListSongs(){ return gedanService.getListSongs(); }
service实现
/** * 获取歌单列表 * api接口地址:https://binaryify.github.io/NeteaseCloudMusicApi/#/?id=neteasecloudmusicapi * 项目地址:https://github.com/Binaryify/NeteaseCloudMusicApi * 下载下来之后 * npm install * 运行 node app.js * 默认运行端口:3000 */ @Override public ResponseWrapper getListSongs() { // 推荐歌单的请求地址:http://localhost:3000/personalized?limit= /** * 推荐歌单 * 说明 : 调用此接口 , 可获取推荐歌单 * * 可选参数 : limit: 取出数量 , 默认为 30 (不支持 offset) * * 接口地址 : /personalized * * 调用例子 : /personalized?limit=1 */ // 获取100个歌单 String url = "http://localhost:3000/personalized?limit=50"; String s = HttpUtils.sendGetRequest(url); log.info(s); // JSON字符串转JSONObject对象 JSONObject jsonObj = JSONObject.parseObject(s); // JSONObject对象转map Map<String, Object> map = JSONUtilsTool.JSONObjectToMap(jsonObj); log.info(map.toString()); log.info(map.get("code").toString()); if (map.get("code").toString().equals("200")){ // 200 说明获取数据成功 Object result = map.get("result"); log.info(result.toString()); // 获取到了歌单列表 JSONArray resuArr = JSONObject.parseArray(result.toString()); log.info(resuArr.get(0).toString()); // JSONArray 转 list<javaBean> List<Gedan> gedanList = resuArr.toJavaList(Gedan.class); log.info(gedanList.size() + "张歌单"); // 把歌单信息存入数据库 for (Gedan gedan : gedanList) { List<Gedan> gedans = gedanMapper.selectList(new LambdaQueryWrapper<Gedan>() .eq(Gedan::getId, gedan.getId()) ); if (gedans.size() > 0){ for (Gedan gedan1 : gedans) { gedan1.setName(gedan.getName()); gedan1.setPicUrl(gedan.getPicUrl()); gedan1.setPlayCount(gedan.getPlayCount()); gedanMapper.updateById(gedan1); } }else { gedanMapper.insert(gedan); } } log.info("歌单数据保存数据库成功"); return ResponseWrapper.markCustomSuccess("数据保存数据库成功"); }else { log.info("数据获取失败"); return ResponseWrapper.markCustomError("数据请求失败"); } }
HttpUtils.sendGetRequest方法:
/** * 发送get请求,没有参数 * * @param url * @return */ public static String sendGetRequest(String url) { String result = ""; BufferedReader in = null; try { URL realUrl = new URL(url); // 打开和URL之间的连接 HttpURLConnection connection = (HttpURLConnection) realUrl .openConnection(); // 设置通用的请求属性 connection.setRequestProperty("accept", "*/*"); connection.setRequestProperty("connection", "Keep-Alive"); connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); // 建立实际的连接 connection.connect(); // 定义 BufferedReader输入流来读取URL的响应 (防止中文乱码可以换成“gbk”) in = new BufferedReader(new InputStreamReader( connection.getInputStream(), "utf-8")); String line; while ((line = in.readLine()) != null) { result += line; } } catch (Exception e) { System.out.println("发送GET请求出现异常!" + e); e.printStackTrace(); } // 使用finally块来关闭输入流 finally { try { if (in != null) { in.close(); } } catch (Exception e) { e.printStackTrace(); } } return result; }
JSONUtilsTool.JSONObjectToMap方法:
/** * JSONObject转map * @param jsonObject * @return map对象 */ public static Map<String,Object> JSONObjectToMap(JSONObject jsonObject){ if (jsonObject.isEmpty()){ return new HashMap<String,Object>(); }else { HashMap<String, Object> map = new HashMap<>(); for (Map.Entry<String, Object> entry : jsonObject.entrySet()) { map.put(entry.getKey(), entry.getValue()); } log("map对象:" + map); if (map.size() > 0){ return map; }else { return new HashMap<>(); } } }
歌单实体类:
import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import lombok.Data; import lombok.EqualsAndHashCode; import java.io.Serializable; /** * <p> * 网易云音乐歌单 * </p> * * @author fzg * @since 2022-12-05 */ @Data @EqualsAndHashCode(callSuper = false) public class Gedan implements Serializable { private static final long serialVersionUID = 1L; @TableId(value = "aid", type = IdType.AUTO) private Integer aid; /** * 歌单图片url */ private String picUrl; /** * 歌单点击量 */ private Long playCount; /** * 歌单名字 */ private String name; /** * 歌单id */ private Long id; }
最后启动项目输入controller的get请求
数据已成功存入数据库
接下来下载图片到本地
controller:
/** * 数据库查询歌单的图片url * 根据url下载图片到本地 */ @GetMapping("/downLoadGeDanPicByDataBaseQuery") public ResponseWrapper downLoadGeDanPicByDataBaseQuery(){ return gedanService.downLoadGeDanPicByDataBaseQuery(); }
Service实现类:
/** * 数据库查询歌单的图片url * 根据url下载图片到本地 */ @Override public ResponseWrapper downLoadGeDanPicByDataBaseQuery() { ArrayList<String> res = new ArrayList<>(); List<Gedan> gedanList = gedanMapper.selectList(null); if (gedanList.size() > 0){ String path = "E:\\pictures\\wangyiyun-imgs\\gedan"; for (Gedan gedan : gedanList) { String name = "歌单图片" + gedan.getId(); String url = gedan.getPicUrl(); File file = new File(path + "\\" + name + ".jpg"); if (file.exists()){ res.add(name + ".jpg 已存在"); }else { try { ImageCodeTool.download(url,name,path); res.add(name + "下载成功"); } catch (Exception e) { res.add(name + "下载失败"); e.printStackTrace(); } } } return ResponseWrapper.markCustomSuccess("歌单图片下载完成,本地路径:" + path,res); }else { return ResponseWrapper.markCustomError("数据库查询歌单为空"); } }
ImageCodeTool.download方法:
/** * java 通过url下载图片保存到本地 * @param urlString 图片链接地址 * @param imgName 图片名称 * @param path 图片要保存的路径 * @throws Exception */ public static void download(String urlString, String imgName, String path) throws Exception { // 构造URL URL url = new URL(urlString); // 打开连接 URLConnection con = url.openConnection(); // 输入流 InputStream is = con.getInputStream(); // 1K的数据缓冲 byte[] bs = new byte[1024]; // 读取到的数据长度 int len; // 输出的文件流 String filename = path + "\\" + imgName + ".jpg"; //本地路径及图片名称 File file = new File(filename); FileOutputStream os = new FileOutputStream(file, true); // 开始读取 while ((len = is.read(bs)) != -1) { os.write(bs, 0, len); } // System.out.println(imgName); // 完毕,关闭所有链接 os.close(); is.close(); }
最后启动服务,输入controller中get请求的网址
图片已经下载成功
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具