首页 > 其他分享 >js逆向——酷狗音乐&酷狗音乐爬虫

js逆向——酷狗音乐&酷狗音乐爬虫

时间:2023-01-28 18:25:40浏览次数:48  
标签:album kugou 音乐 js 酷狗 headers encode com id

寒假期间当然要开卷了。今天我们要爬取酷狗音乐的歌曲,个人觉得酷狗还是比较容易的。虽然付费音乐的apl我没找到,但有个会员就能听,能听就能下载,就不用单曲购买了,会员到期了也能听付费音乐了。想想还是不错滴。

OK,长话短说,来到酷狗音乐,输入想听的歌。点击播放,进入播放页面。这里我搜的是周杰伦的晴天。要点击播放才会出现indix.pip?r这个接口。可以看到这个接口里面是有音乐播放地址的。

 

 

 请求的是这个玩意儿

 

 

 我们知道,get方法请求的一些URL有些是可以删减的。删减后请求的URL是:https://wwwapi.kugou.com/yy/index.php。当然,你直接请求是拿不到数据的,原因没有携带参数。其实删不删都无所谓,可能删了后好看一点吧。

同样,看看要携带的参数哪些是变化的。

 

 

 可以看到只有encode_album_audio_id和时间戳是变化的。但是啊,这个encode_album_audio_id应该不是加密的,为什么呐?因为我们请求的URL里面是不是就有这个encode_album_audio_id啊,这个参数一变,音乐就变了。所以encode_album_audio_id应该是单独一首歌的“身份证”。

回到我们的搜索页面,

 

 

 

 不错,看来encode_album_audio_id确实是固定的。同样,我们只需要带上参数去请求https://complexsearch.kugou.com/v2/search/song就可以。参数如下:

 

 

 

 只有signature和keyword不一样,还有个clienttime时间戳。signature只有32位,猜测是MD5加密。这里我们用跟栈的方法(通过了最后一个栈请求就发出去了,所以沿着堆栈往回找,就能很准确的找到参数生成的位置。应该是这样的。)找到了signature加密的位置,如下。上面有时间戳生成的方法clienttime = (new Date).getTime()。

在控制台打印一下s,

 

 

可以看到s里面的东西就是上面请求https://complexsearch.kugou.com/v2/search/song所需要的。

 

 

然后 s.join("")就是把请求参数变成字符串,然后再MD5加密(后面有一行“H5签名前参数”,所以d函数应该就是MD5加密算法)返回结果就是signature。

 

 

 

 分析完毕!!具体代码如下:

import hashlib
import time
import requests
import json
name = input('请输入:')
text = [
    "NVPh5oo715z5DIWAeQlhMDsWXXQV4hwt",
    "appid=1014",
    "bitrate=0",
    "callback=callback123",
    "clienttime={}".format(int(time.time() * 1000)),
    "clientver=1000",
    "dfid=4XSnWz14ZQos2PYFIl2MiDLH",
    "filter=10",
    "inputtype=0",
    "iscorrection=1",
    "isfuzzy=0",
    "keyword={}".format(name),
    "mid=8a6709b0f4f0674f12dabeb3a710313a",
    "page=1",
    "pagesize=30",
    "platform=WebFilter",
    "privilege_filter=0",
    "srcappid=2919",
    "token=",
    "userid=0",
    "uuid=8a6709b0f4f0674f12dabeb3a710313a",
    "NVPh5oo715z5DIWAeQlhMDsWXXQV4hwt"
]
data = "".join(text)#变成字符串
md5 = hashlib.md5(data.encode(encoding='utf-8')).hexdigest()#md5加密
url = "https://complexsearch.kugou.com/v2/search/song"
headers = {
    "cookie": "这里加上自己的cookie,有会员就能下载付费音乐,这几充还是白嫖别人的就看各位了",
    "authority": "complexsearch.kugou.com",
    "referer": "https://www.kugou.com/",
    "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36"
}
params = {
    "callback": "callback123",
    "srcappid": "2919",
    "clientver": "1000",
    "clienttime": int(time.time() * 1000),
    "mid": "8a6709b0f4f0674f12dabeb3a710313a",
    "uuid": "8a6709b0f4f0674f12dabeb3a710313a",
    "dfid": "4XSnWz14ZQos2PYFIl2MiDLH",
    "keyword": f"{name}",
    "page": "1",
    "pagesize": "30",
    "bitrate": "0",
    "isfuzzy": "0",
    "inputtype": "0",
    "platform": "WebFilter",
    "userid": "0",
    "iscorrection": "1",
    "privilege_filter": "0",
    "filter": "10",
    "token": "",
    "appid": "1014",
    "signature": md5
}
lll = json.loads(requests.get(url=url, headers=headers, params=params).text[12:-2])
kkk = lll['data']['lists']
for s, li in enumerate(kkk):
    ids = li['EMixSongID']
    AlbumName = li['SongName']
    singername = li['SingerName']
    print(s + 1, AlbumName, singername)
num = input('下载哪一个:')
ID = lll['data']['lists'][int(num) - 1]['EMixSongID']
name = lll['data']['lists'][int(num) - 1]['SongName']
urls = f'https://wwwapi.kugou.com/yy/index.php?r=play/getdata&callback=jQuery191015294419033165485_1674051666168&dfid=4XSnWz14ZQos2PYFIl2MiDLH&appid=1014&mid=8a6709b0f4f0674f12dabeb3a710313a&platid=4&encode_album_audio_id={ID}&_=1674051666169'
params = {
    "r": "play/getdata",
    "callback": "jQuery19101351666471912658_1674051302167",
    "dfid": "4XSnWz14ZQos2PYFIl2MiDLH",
    "appid": "1014",
    "mid": "8a6709b0f4f0674f12dabeb3a710313a",
    "platid": "4",
    "encode_album_audio_id": f"{ID}",
    "_": "1674051302168"
}
respons = json.loads(requests.get(url=urls, headers=headers, params=params).text[41:-2])
last = respons['data']['play_url']
downlode=requests.get(url=last,headers=headers).content
with open('D:/音乐/'+f'{name}.mp3','wb')as sp:
    sp.write(downlode)
    print(last)
    print(f'{name}下载完成')

 

 OK,大功告成!!

 

标签:album,kugou,音乐,js,酷狗,headers,encode,com,id
From: https://www.cnblogs.com/wxd501/p/17071045.html

相关文章

  • React --- jsx语法规则
    jsx语法规则:1、定义虚拟dom时,不要写引号//创建虚拟DOM 1constVDOM=<h1><span>hello,react</span></h1> 2、标签中混入JS表达式时要用{}1//定义属性和标签内容2c......
  • C# 序列化Json时如何忽略JsonProperty(PropertyName =“ someName”)
    前言序列化大家都很常见,就是把一个对象序列化成一串Json字符串。最近对接第三方的时候遇到了一个情况,我们C#都是用骆驼命名,而他们呢需要接收的Json字符串的 key 是 ......
  • Js学习之 ----- 数组sort()排序
    数组的sort()方法会把数组中的元素转为字符串,然后根据字符串首位字符的Unicode码(或ASCII码)值来排序【默认从小到大】【ps:ASCII码是Unicode码的子集~】1、没有参数的情......
  • GRPC与JSON-RPC区别
      GRPC与JSON-RPC都是rpc的一种。 一.RPCRPC是什么RPC(RemoteProcedureCall)指的是远程过程调用,简单的说,RPC就是从一台机器上通过参数传递的方式调用另一台......
  • JS加解密之AES
      demo<scriptsrc="https://cdn.bootcss.com/crypto-js/3.1.9-1/crypto-js.min.js"></script><script>alert(aesDecrypt(aesEncrypt("yvioo","wa1234535")......
  • AJAX服务器响应JSON数据&设置响应体数据类型
    <!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width,initial-scale=1.0"><title>JSON响......
  • js 导入excel数据 时间转换
    废话不多说,直接上代码:formatDate(timeNum){consttime=newDate(((Number(timeNum)-70*365-19)*24*3600-8*3600-42.5)*1000)constyear=......
  • js方法中回调函数的使用
    js方法中回调函数的使用什么是回调函数(Callback)在JavaScript中,函数是对象。因此,函数可以将函数作为参数,并且可以由其他函数返回。执行此操作的函数称为高阶函数。作为......
  • vue配置反向代理解决跨域__Vue.js
    正向代理与反向代理正向代理:在客户端和原始服务器(originserver)之间架设一个代理服务器,为了从原始服务器取得内容,客户端向代理发送一个请求并指定目标(原始服务器),然后......
  • js中function的写法
    js文件中function的写法//Js代码functionfoo(){console.log('helloworld');}foo();//用匿名函数:varfoo=function(){console.log('helloworld')......