利用Node.js的核心模塊path和fs模塊拐云,以及第三方模塊cheerio模塊和請(qǐng)求模塊request爬取酷狗音樂(lè)的詳細(xì)歌手的歌曲狞玛。詳細(xì)的思路如下:
1.酷狗音樂(lè)的搜索頁(yè)面地址:如周杰倫的詳細(xì)歌單 http://www.kugou.com/yy/html/search.html#searchType=song&searchKeyWord=周杰倫
- 你可以在Node.js中讀取命令行輸入的參數(shù)(歌手的名字)呢铆,然后把參數(shù)拼接到搜索的網(wǎng)址水慨,然后請(qǐng)求響應(yīng)的歌手詳細(xì)頁(yè)面湿颅。
2.獲取歌手詳細(xì)的地址:http://www.kugou.com/yy/singer/home/3060.html
- 關(guān)于這個(gè)歌手詳細(xì)地址的搜索頁(yè)面里面的a標(biāo)簽的值蔚叨;
3.在歌手詳細(xì)地址的頁(yè)面可以看到歌手的每一條單曲床蜘;審查元素可以看到的一條標(biāo)簽如下:
<input class='cb song_hid' value='薛之謙 - 丑八怪|2688ADB1CA449448388270987BDCE6E8|253000 '/>
- 這個(gè)value值中的hash值是唯一可以確定歌手單曲的詳細(xì)地址的,因?yàn)榭峁芬魳?lè)已經(jīng)把地址加密了蔑水,如果要知道hash的算法由來(lái)只有抓包分析其中的參數(shù)以及加密步驟邢锯;現(xiàn)在我們已經(jīng)取巧了,直接通過(guò)js的正則的表達(dá)式來(lái)竊取中間這一段hash值搀别,也是爬取酷狗音樂(lè)的關(guān)鍵步驟之一丹擎。
4. 把hash值拼接起來(lái)批量抓取歌曲;通過(guò)chrome瀏覽器的抓包分析可以看到歌曲的請(qǐng)求是異步獲取的;請(qǐng)求的地址是http://www.kugou.com/yy/index.php?r=play/getdata&hash=928BA6597476E1D9DF06EA425CE43131&album_id=1747549&_=1495258259290
- 其中有四個(gè)參數(shù)是傳的蒂培,參數(shù)是:
let options={
r=play/getdata,
_=new Date().getTime(),
album_id=0,
hash=2688ADB1CA449448388270987BDCE6E8
};
- 請(qǐng)求獲取到的json格式的數(shù)據(jù)如下所示,其中的paly_url字段是我們需要獲取的值:
{
"status": 1,
"err_code": 0,
"data": {
"hash": "928BA6597476E1D9DF06EA425CE43131",
"timelength": 305000,
"filesize": 4884733,
"audio_name": "薛之謙 - 下雨了",
"have_album": 1,
"album_name": "初學(xué)者",
"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]偷偷的下雨的時(shí)候月亮偷偷的\r\n[00:30.97]慢慢的街上的人群慢慢安靜了\r\n[00:41.59]我在想你可以不必掩飾了\r\n[00:51.79]那雨會(huì)停的就隨你去了\r\n[01:01.05]雨還在下像在說(shuō)話\r\n[01:06.29]他敲我的窗叮叮當(dāng)當(dāng)\r\n[01:13.92]戀愛(ài)的季節(jié)勉強(qiáng)不如放下\r\n[01:22.42]雨還在下你聽(tīng)得見(jiàn)嗎\r\n[01:27.78]是我的思念滴滴答答\r\n[01:35.53]滴入你的心就會(huì)想起我\r\n[01:43.78]雨還在下像在尋你\r\n[01:49.07]它敲我的窗說(shuō)找不到你\r\n[01:56.70]這樣的季節(jié)就會(huì)特別想你\r\n[02:05.08]雨還在下你仔細(xì)聽(tīng)啊\r\n[02:10.32]是我的思念滴滴答答\r\n[02:18.12]滴入你的心告訴你我在想你\r\n[02:46.79]遠(yuǎn)遠(yuǎn)的無(wú)關(guān)的人不經(jīng)意逃避著\r\n[02:57.31]輕輕的像不像話題被誰(shuí)提起了\r\n[03:07.17]怎么會(huì)沒(méi)人記得是不是我瘋了\r\n[03:18.38]那雨別停了能否算愛(ài)著\r\n[03:27.75]雨還在下像在說(shuō)話\r\n[03:33.04]他敲我的窗叮叮當(dāng)當(dāng)\r\n[03:40.62]戀愛(ài)的季節(jié)勉強(qiáng)不如放下\r\n[03:49.03]雨還在下你聽(tīng)得見(jiàn)嗎\r\n[03:54.31]是我的思念滴滴答答\r\n[04:01.88]滴入你的心就會(huì)想起我\r\n[04:10.37]雨還在下像在尋你\r\n[04:15.63]它敲我的窗說(shuō)找不到你\r\n[04:23.44]這樣的季節(jié)就會(huì)特別想你\r\n[04:31.77]雨還在下你仔細(xì)聽(tīng)啊\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.詳細(xì)的代碼如下:
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); //調(diào)用request的管道來(lái)下載到 images文件夾下
});
};
- 總結(jié):酷狗音樂(lè)的歌曲已經(jīng)爬取成功再愈;酷狗音樂(lè)的web端只給出了歌手的三十首的歌曲;如果想獲取更多歌曲可以直接下載酷狗客戶端然后抓包分析护戳;至于網(wǎng)易云音樂(lè)的下載翎冲;已經(jīng)有高手完整地總結(jié)出API外鏈了;作者也曾經(jīng)研究過(guò)網(wǎng)易云的抓认被摹抗悍;網(wǎng)易云音樂(lè)的獲取json格式的post請(qǐng)求參數(shù)已經(jīng)進(jìn)行了加密;可以網(wǎng)上搜索網(wǎng)易云音樂(lè)加密的方法肺樟;相類(lèi)似的請(qǐng)求方法檐春,下面給出抓取的歌曲的圖片,作者比較喜歡陳奕迅的歌曲:
爬取到的酷狗音樂(lè)的歌曲