如何使用node爬取某平台音乐,并保存到本地
注意:本项目仅供个人研究学习使用,切勿商用!
项目截图
项目部署环境与使用
- nodejs(用来做文件流的操做)
- axios(用来发送请求,获取音频的文件流)
-
- 使用
- 执行
项目思路
- 获取url地址
- 发送网络请求,使其以流的形式进行返回
- 使用nodejs的fs模块对返回的流文件进行操作
获取音乐url
目前网络上已经有很多的个人开放了各音乐平台的api接口,大家可以进行自行选择使用,也可以联系我获知比较优秀的几个api接口。
发送请求,并以流的形式进行返回
async function getMusicUrl(musicID, quality = "320") {
let res,resdata;
try{
res = await axios(`${baseURL}/url?id=${musicID}&quality=${quality}`,{
responseType: 'stream'
});
resdata = res.data;
}catch(e){
console.log(e)
};
return resdata;
}
按照 音乐人/专辑名/歌曲名的形式 创建文件夹
const getAlbumBySingerID = require("./api/1/getAlbumBySinger")
const getAlbumMusic = require("./api/1/getAlbumMusic")
const getMusicUrl = require("./api/1/getMusicURl")
const getSingerList = require("./api/1/getsingerlist")
const fs = require("fs");
// 下载音乐
async function downloadMusic(singerID){
let albumArr = await getAlbumBySingerID(singerID);
for(let i = 0;i < albumArr.length;i++){
// 获取到专辑信息
let ablumInfo = albumArr[i].musicData;
// 专辑名称
let albumName = ablumInfo.albumname;
// 专辑ID
let albumID = ablumInfo.albummid;
// 获取歌手名称(要注意这个地方的歌手名字可能不止一个)
let singerName = ablumInfo.singer[0].name;
let albumMusicArrInfo = await getAlbumMusic(albumID);
let albumMusicArr = albumMusicArrInfo.getSongInfo;
for(let j = 0;j < albumMusicArr.length;j++){
let musicInfo = albumMusicArr[j];
let musicID = musicInfo.songmid;
let musicName = musicInfo.songname;
console.log(musicName)
// 获取音乐 文件流数据
let streamData = await getMusicUrl(musicID);
// 如果音乐文件不存在,就跳过本次循环
if(!streamData){
break;
}
saveMusicToLocal("Music",singerName,albumName,musicName,streamData);
}
}
}
使用nodejs进行储存
// 储存音乐
async function saveMusicToLocal(basePath,singerName,albumName,musicName,data){
let pathName = `${basePath}/${singerName}/${albumName}`
try{
let temp = await fs.mkdirSync(pathName, { recursive: true })
}catch(e){
console.log(e)
}
// 检查文件夹是否存在
// 避免在创建流的时候出错
fs.exists(pathName,(flag)=>{
if(!flag){
// 如果文件夹不存在就递归创建
fs.mkdirSync(pathName,{ recursive: true})
}
// 当存在时执行以下操作
// 创建可写流
console.log(`${pathName}/${musicName}.mp3`)
let writeStream = fs.createWriteStream(`${pathName}/${musicName}.mp3`,{ encoding: "binary" })
data.pipe(writeStream);
data.on("close", function () {
writeStream.close()
})
})
}
注意
- 由于音乐平台的不同,某些歌曲可能在某个平台并不能够爬取到,所以在代码编写时一定要做好容错处理
- 创建流的时候,编码类型一定要是二进制格式,如下:
fs.createWriteStream(`${pathName}/${musicName}.mp3`,{ encoding: "binary" })
- 若有问题,欢迎评论交流!