Node爬虫入门之制作QQ音乐卡片 | 世外天堂

Node爬虫入门之制作QQ音乐卡片

本项目基于Node.js制作,根据歌名爬取歌曲链接以及生成JSON卡片,最后通过机器人发送出去

难点

  • 1.处理非标准返回消息至JSON
  • 2.获取vkey
  • 3.音乐卡片JSON的提取

上代码:
以我比较喜欢听的音乐快乐合成器(GUMI)为例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
const axios = require('axios')
var str = '点歌快乐合成器 GUMI';
var songname = '';
var reg = /点歌(.+)$/gi;
var arr = reg.exec(str);
songname = encodeURIComponent(arr[1])
var songid = '';
var albumid = '';
var name = '';
var singer = '';
getSongUrl()
//获取音乐ID(返回Promise对象)
function getSongId() {
return new Promise((resolve, reject) => {
axios.get(
"https://c.y.qq.com/soso/fcgi-bin/client_search_cp?ct=24&qqmusic_ver=1298&new_json=1&remoteplace=txt.yqq.song&searchid=66137917959202681&t=0&aggr=1&cr=1&catZhida=1&lossless=0&flag_qc=0&p=1&n=10&w=" +
songname)
.then(res => {
str1 = res.data.replace("callback(", "");
str2 = str1.replace("})", "}");
var res1 = JSON.parse(str2);
songid = res1.data.song.list[0].id;
albumid = res1.data.song.list[0].album.id;
name = res1.data.song.list[0].name;
singer = res1.data.song.list[0].singer[0].name;
resolve(res1.data.song.list[0].mid)
})
.catch(err => {
reject(err)
})
});
}
//获取音乐链接(异步函数)
async function getSongUrl() {
let mid=await getSongId();
axios.get(
"https://u.y.qq.com/cgi-bin/musicu.fcg?format=json&data=%7B%22req_0%22%3A%7B%22module%22%3A%22vkey.GetVkeyServer%22%2C%22method%22%3A%22CgiGetVkey%22%2C%22param%22%3A%7B%22guid%22%3A%22358840384%22%2C%22songmid%22%3A%5B%22" +
mid +
"%22%5D%2C%22songtype%22%3A%5B0%5D%2C%22uin%22%3A%221443481947%22%2C%22loginflag%22%3A1%2C%22platform%22%3A%2220%22%7D%7D%2C%22comm%22%3A%7B%22uin%22%3A%2218585073516%22%2C%22format%22%3A%22json%22%2C%22ct%22%3A24%2C%22cv%22%3A0%7D%7D"
)
.then(res => {
var purl = res.data['req_0']['data']['midurlinfo'][0]['purl']
var card = {
app: "com.tencent.structmsg",
desc: "音乐",
view: "music",
ver: "0.0.0.1",
prompt: "[分享]" + name,
appID: "",
sourceName: "",
actionData: "",
actionData_A: "",
sourceUrl: "",
meta: {
music: {
"action": "",
"android_pkg_name": "",
"app_type": 1,
"appid": 100497308,//qq音乐为100497308,网易为100495085
"desc": singer,
"jumpUrl": "https:\/\/i.y.qq.com\/v8\/playsong.html?_wv=1&songid=" + songid,
"musicUrl": "https://isure.stream.qqmusic.qq.com/" + purl,
"preview": "http:\/\/imgcache.qq.com\/music\/photo\/album_500\/42\/500_albumpic_" + albumid + "_0.jpg",
"sourceMsgId": "0",
"source_icon": "",
"source_url": "",
"tag": "QQ音乐",
"title": name
}
},
config: {
autosize: true,
ctime: Math.round(new Date().getTime()/1000),
forward: true,
token: "3bf9c46bac36e9161d5958394dbb6c2a",
type: "normal"
},
text: "",
sourceAd: ""
}
console.log(card)
})
.catch(err => {
console.log(err)
})
}

网易音乐的就更简单了,只需请求一次取数据即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
const axios = require('axios')
var str = '点歌快乐合成器 GUMI';
var songname = '';
var reg = /点歌(.+)$/gi;
var arr = reg.exec(str);
songname = encodeURIComponent(arr[1])
var songid = '';
var album = '';
var name = '';
var singer = '';
getSongUrl();
function getSongUrl() {
axios.get(
"http://music.163.com/api/search/pc?s=" + songname + "&type=1")
.then(res => {
songid = res.data.result.songs[0].id;
name = res.data.result.songs[0].name;
album = res.data.result.songs[0].album.picUrl;
for (let i = 0; i < res.data.result.songs[0].artists.length; i++) {
if (i == res.data.result.songs[0].artists.length) {
singer += res.data.result.songs[0].artists[i]['name'];
break;
}
singer += res.data.result.songs[0].artists[i]['name'] + '/';
}
var card = {
app: "com.tencent.structmsg",
desc: "音乐",
view: "music",
ver: "0.0.0.1",
prompt: "[分享]" + name,
appID: "",
sourceName: "",
actionData: "",
actionData_A: "",
sourceUrl: "",
meta: {
music: {
"action": "",
"android_pkg_name": "",
"app_type": 1,
"appid": 100495085,
"desc": singer,
"jumpUrl": "http://music.163.com/song/" + songid + "/",
"musicUrl": "http://music.163.com/song/media/outer/url?id=" + songid + ".mp3",
"preview": album,
"sourceMsgId": "0",
"source_icon": "",
"source_url": "",
"tag": "网易云音乐",
"title": name
}
},
config: {
autosize: true,
ctime: Math.round(new Date().getTime() / 1000),
forward: true,
token: "3bf9c46bac36e9161d5958394dbb6c2a",
type: "normal"
},
text: "",
sourceAd: ""
}
console.log(card)
})
.catch(err => {
console.log(err)
})
}