爬虫很难吗?手把手酷我音乐解析

您所在的位置:网站首页 酷我音乐674 爬虫很难吗?手把手酷我音乐解析

爬虫很难吗?手把手酷我音乐解析

2024-07-07 12:27| 来源: 网络整理| 查看: 265

Nodejs酷我爬虫参考 1.排行榜列表2.排行榜榜单详情3.根据rid获取歌曲mp3地址4.2023.07.17更新,请求头由“Cross”改为“Secret”5.根据rid获取VIP/高音质音乐链接6.根据rid获取歌词

1.排行榜列表 打开 kuwo.cn, 浏览器F12 监听网络请求,刷新一次页面。根据网页信息,定位接口地址。F12界面全局搜索(ctrl+shift+F)排行榜中的向云端 (你看到什么就搜什么 不固定)

在这里插入图片描述

点击搜索结果,跳转至关键词数据所在页面,在此页面搜索(ctrl+F)向云端,结论:数据来源于页面window._NUXT_.data.bang对象。如下图: 在这里插入图片描述 在这里插入图片描述 页面用的是Nuxt服务器端渲染,看到a,b,c,d,e,f...了吧,这段js被混淆了

数据提取。可能首先想到的是用正则匹配,那有没有办法办法直接获取到 __NUXT__ 对象呢?既然是js,那就想办法运行这段js。

技术选型。那就用 nodejs 吧! nodejs 爬虫实战,看代码:

let url = 'http://www.kuwo.cn/'; //模拟访问首页 let result = await get(url);//get方法为request封装 //正则匹配那段js var mc = result.match(/.*?/gi); //console.log(mc); var __NUXT__;//定义接收变量 let sc = mc[0] ?? ''; //一系列的替换 if (sc) { sc = sc.replace('', ''); sc = sc.replace('', ''); sc = sc.replace('window.', '');//由于不是浏览器没有window对象,就替换为空 sc = sc.replace(/\r/gi, ''); sc = sc.replace(/\n/gi, ''); //console.log(sc); } let js = eval(sc);//用nodejs的方便之处,eval搞定,直接把结果赋值给__NUXT__ //console.log(js); let bangs = __NUXT__.data[0].bang;

结果:

[ { "leader":"酷我热歌榜", "num":"300", "name":"酷我热歌榜", "pic":"https://img4.kuwo.cn/star/albumcover/120/1/29/1934979845.jpg", "id":"16", "pub":"2023-07-14", "musicList":[ { "musicrid":"MUSIC_279292599", "barrage":"0", "ad_type":"", "artist":"小霞&海洋Bo", "mvpayinfo":{ "play":0, "vid":0, "down":0 }, "pic":"https://img4.kuwo.cn/star/albumcover/500/1/29/1934979845.jpg", "isstar":0, "rid":279292599, "duration":251, "score100":"93", "ad_subtype":"0", "content_type":"0", "track":1, "hasmv":0, "releaseDate":"2023-06-29", "album":"向云端", "albumid":38777035, "pay":"16515324", "artistid":8854278, "albumpic":"https://img4.kuwo.cn/star/albumcover/500/1/29/1934979845.jpg", "originalsongtype":0, "isListenFee":false, "pic120":"https://img4.kuwo.cn/star/albumcover/120/1/29/1934979845.jpg", "name":"向云端", "online":1, 2.排行榜榜单详情 点击首页排行榜更多,监听网络请求 在这里插入图片描述

详情地址为: GET => https://www.kuwo.cn/api/www/bang/bang/musicList?bangId=93&pn=1&rn=20&httpsStatus=1&reqId=16fffd81-21fa-11ee-9cdf-25abfdc1606c&plat=web_www&from=

bangId=93//上个步骤中的id pn=1//页码 rn=20//每页多少条 reqId=16fffd81-21fa-11ee-9cdf-25abfdc1606//可有可无

同样用 nodejs 模拟这个请求,结果:

{ "success":false, "message":"CSRF token Invalid!", "now":"2023-07-14T05:49:44.720Z" } 爬虫的关键部分来了,请求头模拟。简单来说,就是用程序把请求做的像浏览器发出的一样。通过分析请求头,以及反复测试,最终得出以下两个头信息为必备:(把以下所有头信息都模拟更好) 在这里插入图片描述F12 界面全局搜Cross 定位出算法: 在这里插入图片描述 由上面代码可以看出来,Cross 是通过以 Hm_token 为参数,调用A()方法生成的。打断点调试A(): 在这里插入图片描述梳理这两个参数的关系: Created with Raphaël 2.3.0 Hm_token->EzAGdH3z6e3SPteBeHHSAYNKiBTGf4QP A() d30d2c87eac9797e2376acadbabba058

Cross 是由 Hm_token 加密处理得到。

由经验得知:Cross = md5(sha1(Hm_token))

常用的加密算法:md5 aes des sha 不知道数据用什么加密方式就全局搜,或者一个一个加密方法试。最后才选择单步调试~

加密算法有了,寻找 Hm_token : 在这里插入图片描述 每次请求,都会往cookie里面写入Hm_token ,用程序模拟并获取cookie: async function hmToken() { let url = `https://www.kuwo.cn/`; let result = await superagent.get(url); let cookie = result.header['set-cookie'][0] ?? ''; //console.log(cookie); let mc = cookie.match(/Hm_token=(.*?);/); let hm = mc[1] ?? ''; return hm; } 排行榜榜单详情最终代码: async function getBangMusicList(id, pn, rn) { let hm = await hmToken(); console.log(hm) var obj = crypto.createHash('sha1'); obj.update(hm); let hmSha = obj.digest('hex'); console.log(hmSha); obj = crypto.createHash('md5'); obj.update(hmSha); var cross = obj.digest('hex');//hex是十六进制 console.log(cross); let url = `http://www.kuwo.cn/api/www/bang/bang/musicList?bangId=${id}&pn=${pn}&rn=${rn}&httpsStatus=1&plat=web_www&reqId=`; var result = await get(url, {}, { Cross: cross, cookie: `Hm_token=${hm}` }); var obj = JSON.parse(result); return obj; } 3.根据rid获取歌曲mp3地址 点首歌,监听网络请求: 在这里插入图片描述程序模拟: async function getAudio(id) { let url = 'https://www.kuwo.cn/api/v1/www/music/playUrl?mid=' + id + '&type=music&httpsStatus=1&reqId=&plat=web_www&from='; let result = await get(url); //console.log(result); return result; } ====================================== getAudio(279292599) result 结果: { "code":200, "msg":"success", "reqId":"b9ca2ee89fec9ad131105ce494d05a2b", "data":{ "url":"https://other-web-nf01-sycdn.kuwo.cn/b09d144c5526bbb95e8d1166f1c8db8a/64b0fa4a/resource/n2/60/65/902137489.mp3?from$unkown&plat$web_www" }, "profileId":"site", "curTime":1689320311016, "success":true } 4.2023.07.17更新,请求头由“Cross”改为“Secret”

在这里插入图片描述 F12定位Secret: 在这里插入图片描述 单步调试这个h()方法: 在这里插入图片描述

分析完毕,看具体实现:

新增一个加密函数:(来源:某度) function encrypt(str, pwd) { if (pwd == null || pwd.length


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3