利用Node.js的核心模块path和fs模块,以及第三方模块cheerio模块和请求模块request爬取酷狗音乐的详细歌手的歌曲。详细的思路如下:
1.酷狗音乐的搜索页面地址:如周杰伦的详细歌单 http://www.kugou.com/yy/html/search.html#searchType=song&searchKeyWord=周杰伦
- 你可以在Node.js中读取命令行输入的参数(歌手的名字),然后把参数拼接到搜索的网址,然后请求响应的歌手详细页面。
2.获取歌手详细的地址:http://www.kugou.com/yy/singer/home/3060.html
- 关于这个歌手详细地址的搜索页面里面的a标签的值;
3.在歌手详细地址的页面可以看到歌手的每一条单曲;审查元素可以看到的一条标签如下:
<input class='cb song_hid' value='薛之谦 - 丑八怪|2688ADB1CA449448388270987BDCE6E8|253000 '/>
- 这个value值中的hash值是唯一可以确定歌手单曲的详细地址的,因为酷狗音乐已经把地址加密了,如果要知道hash的算法由来只有抓包分析其中的参数以及加密步骤;现在我们已经取巧了,直接通过js的正则的表达式来窃取中间这一段hash值,也是爬取酷狗音乐的关键步骤之一。
4. 把hash值拼接起来批量抓取歌曲;通过chrome浏览器的抓包分析可以看到歌曲的请求是异步获取的;请求的地址是http://www.kugou.com/yy/index.php?r=play/getdata&hash=928BA6597476E1D9DF06EA425CE43131&album_id=1747549&_=1495258259290
- 其中有四个参数是传的,参数是:
let options={
r=play/getdata,
_=new Date().getTime(),
album_id=0,
hash=2688ADB1CA449448388270987BDCE6E8
};
- 请求获取到的json格式的数据如下所示,其中的paly_url字段是我们需要获取的值:
{
"status": 1,
"err_code": 0,
"data": {
"hash": "928BA6597476E1D9DF06EA425CE43131",
"timelength": 305000,
"filesize": 4884733,
"audio_name": "薛之谦 - 下雨了",
"have_album": 1,
"album_name": "初学者",
"album_id": "1747549",
"img": "http://imge.kugou.com/stdmusic/20160718/20160718092740664264.jpg",
"have_mv": 1,
"video_id": "181461",
"author_name": "薛之谦",
"song_name": "下雨了",
"lyrics": "[00:00.11]薛之谦 - 下雨了\r\n[00:01.87]词:薛之谦\r\n[00:02.70]曲:薛之谦\r\n[00:03.53]编曲:张宝宇\r\n[00:04.43]制作人:赵英俊\r\n[00:05.45]配唱制作人:赵英俊\r\n[00:06.78]录音师:王晓海\r\n[00:07.80]混音师:鲍锐\r\n[00:08.74]母带处理工程师:鲍锐\r\n[00:20.30]偷偷的下雨的时候月亮偷偷的\r\n[00:30.97]慢慢的街上的人群慢慢安静了\r\n[00:41.59]我在想你可以不必掩饰了\r\n[00:51.79]那雨会停的就随你去了\r\n[01:01.05]雨还在下像在说话\r\n[01:06.29]他敲我的窗叮叮当当\r\n[01:13.92]恋爱的季节勉强不如放下\r\n[01:22.42]雨还在下你听得见吗\r\n[01:27.78]是我的思念滴滴答答\r\n[01:35.53]滴入你的心就会想起我\r\n[01:43.78]雨还在下像在寻你\r\n[01:49.07]它敲我的窗说找不到你\r\n[01:56.70]这样的季节就会特别想你\r\n[02:05.08]雨还在下你仔细听啊\r\n[02:10.32]是我的思念滴滴答答\r\n[02:18.12]滴入你的心告诉你我在想你\r\n[02:46.79]远远的无关的人不经意逃避着\r\n[02:57.31]轻轻的像不像话题被谁提起了\r\n[03:07.17]怎么会没人记得是不是我疯了\r\n[03:18.38]那雨别停了能否算爱着\r\n[03:27.75]雨还在下像在说话\r\n[03:33.04]他敲我的窗叮叮当当\r\n[03:40.62]恋爱的季节勉强不如放下\r\n[03:49.03]雨还在下你听得见吗\r\n[03:54.31]是我的思念滴滴答答\r\n[04:01.88]滴入你的心就会想起我\r\n[04:10.37]雨还在下像在寻你\r\n[04:15.63]它敲我的窗说找不到你\r\n[04:23.44]这样的季节就会特别想你\r\n[04:31.77]雨还在下你仔细听啊\r\n[04:37.05]是我的思念滴滴答答\r\n[04:44.49]还能去屋檐下等你吗\r\n",
"author_id": "3060",
"privilege": 0,
"privilege2": "0",
"play_url": "http://fs.web.kugou.com/c939235ce25f0002481e782e24e6f39c/591fcef1/G065/M01/02/14/IZQEAFeEyVmAYtKaAEqI_eQvOtA748.mp3",
"authors": [
{
"is_publish": "1",
"author_id": "3060",
"avatar": "20170515114300444.jpg",
"author_name": "薛之谦"
}
],
"bitrate": 128
}
}
5.详细的代码如下:
var request = require('request');
var cheerio = require('cheerio');
var path = require('path');
var fs = require('fs');
var requrl="http://www.kugou.com/singer/420.html";
var listUrl=new Array();
var filenames=new Array();
request(requrl, function (error, response, body) {
if (!error && response.statusCode == 200) {
acquireData(body);
}
for(let i=0;i<listUrl.length;i++){
let time=new Date().getTime();
request('http://www.kugou.com/yy/index.php?r=play/getdata&hash='+listUrl[i]+'&album_id=0'+'&_='+time, function (error, response, body) {
if (!error && response.statusCode == 200) {
acquireMusic(body,i);
}
});
}
});
function acquireData(data) {
var $ = cheerio.load(data);
var songlist = $('#song_container input').toArray();
for(let i=0;i<songlist.length;i++){
let info=songlist[i].attribs.value;
let reg=/\|/;
let hash=new Array();
hash=info.split(reg);
listUrl.push(hash[1]);
filenames.push(hash[0]);
}
}
function acquireMusic(data,Num){
var info=JSON.parse(data);
var imgsrc=info.data.play_url;
// var filename = parseUrlForFileName(imgsrc);
var filename=filenames[Num];
downloadImg(imgsrc,filename,function(){
console.log(filename + ' done');
});
}
function parseUrlForFileName(address) {
var filename = path.basename(address);
return filename;
}
var downloadImg = function(uri, filename, callback){
request.head(uri, function(err, res, body){
if (err) {
console.log('err: '+ err);
return false;
}
console.log('res: '+ res);
request(uri).pipe(fs.createWriteStream('images/'+filename+'.mp3')).on('close', callback); //调用request的管道来下载到 images文件夹下
});
};
- 总结:酷狗音乐的歌曲已经爬取成功;酷狗音乐的web端只给出了歌手的三十首的歌曲;如果想获取更多歌曲可以直接下载酷狗客户端然后抓包分析;至于网易云音乐的下载;已经有高手完整地总结出API外链了;作者也曾经研究过网易云的抓取;网易云音乐的获取json格式的post请求参数已经进行了加密;可以网上搜索网易云音乐加密的方法;相类似的请求方法,下面给出抓取的歌曲的图片,作者比较喜欢陈奕迅的歌曲: