引言
之前找到了一个音乐解析平台,速度相当的快。
https://api.toubiec.cn/wyapi.html
你们可以测试一下
我就想着监听请求然后使用python批量去解析歌单下载到u盘,放在车上听,有时候回老家某个地方有强大力量会让你的手机进入飞行模式。
1.0 监听解析网站请求
1.1 首先分析获取token值的请求能否模拟
老规矩右键复制为curl(bash)格式到
https://curlconverter.com/
得到代码
import requests
headers = {
'accept': 'application/json, text/plain, */*',
'accept-language': 'zh-CN,zh;q=0.9',
'cache-control': 'no-cache',
# 'content-length': '0',
'origin': 'https://api.toubiec.cn',
'pragma': 'no-cache',
'priority': 'u=1, i',
'referer': 'https://api.toubiec.cn/wyapi.html',
'sec-ch-ua': '"Google Chrome";v="131", "Chromium";v="131", "Not_A Brand";v="24"',
'sec-ch-ua-full-version-list': '"Google Chrome";v="131.0.6778.265", "Chromium";v="131.0.6778.265", "Not_A Brand";v="24.0.0.0"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-model': '""',
'sec-ch-ua-platform': '"Windows"',
'sec-ch-ua-platform-version': '"19.0.0"',
'sec-fetch-dest': 'empty',
'sec-fetch-mode': 'cors',
'sec-fetch-site': 'same-origin',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36',
}
response = requests.post('https://api.toubiec.cn/api/get-token.php', headers=headers)
print(response.text)
拿到输出
{“token”:”cc248f357e85319ec86eb67aea44967e”}
1.2 模拟获取解析数据的请求
观察源请求
这里回首上一步获取token的返回值
哦吼,完犊子,token不一致。只能逆向了。
截断第二步请求查看加密方式
这一步,我就差不多已经知道加密方式是MD5。并且是32位小写
验证一下
打开 https://www.sojson.com/md5/
验证得到
完美直接解决
这里就能拿到解析的完整过程
2.0复刻解析过程
首先拿到token,和上面的代码一样,改一下请求头命名
import requests
headers_token = {
'accept': 'application/json, text/plain, */*',
'accept-language': 'zh-CN,zh;q=0.9',
'cache-control': 'no-cache',
# 'content-length': '0',
'origin': 'https://api.toubiec.cn',
'pragma': 'no-cache',
'priority': 'u=1, i',
'referer': 'https://api.toubiec.cn/wyapi.html',
'sec-ch-ua': '"Google Chrome";v="131", "Chromium";v="131", "Not_A Brand";v="24"',
'sec-ch-ua-full-version-list': '"Google Chrome";v="131.0.6778.265", "Chromium";v="131.0.6778.265", "Not_A Brand";v="24.0.0.0"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-model': '""',
'sec-ch-ua-platform': '"Windows"',
'sec-ch-ua-platform-version': '"19.0.0"',
'sec-fetch-dest': 'empty',
'sec-fetch-mode': 'cors',
'sec-fetch-site': 'same-origin',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36',
}
response_token = requests.post('https://api.toubiec.cn/api/get-token.php', headers=headers_token)
token_data = response_token.json()
token_token = token_data['token']
然后使用python库 hashlib
对token值进行MD5加密(32位小写)
md5_hash = hashlib.md5(token_token.encode()).hexdigest()
老规矩右键第二步请求为curl(bash)格式
得到代码
import requests
headers = {
'accept': 'application/json, text/plain, */*',
'accept-language': 'zh-CN,zh;q=0.9',
'authorization': 'Bearer d305524182c159f5ec13b893ec54ec46',
'cache-control': 'no-cache',
'content-type': 'application/json',
'origin': 'https://api.toubiec.cn',
'pragma': 'no-cache',
'priority': 'u=1, i',
'referer': 'https://api.toubiec.cn/wyapi.html',
'sec-ch-ua': '"Google Chrome";v="131", "Chromium";v="131", "Not_A Brand";v="24"',
'sec-ch-ua-full-version-list': '"Google Chrome";v="131.0.6778.265", "Chromium";v="131.0.6778.265", "Not_A Brand";v="24.0.0.0"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-model': '""',
'sec-ch-ua-platform': '"Windows"',
'sec-ch-ua-platform-version': '"19.0.0"',
'sec-fetch-dest': 'empty',
'sec-fetch-mode': 'cors',
'sec-fetch-site': 'same-origin',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36',
}
json_data = {
'url': 'https://music.163.com/song?id=29816400',
'level': 'standard',
'type': 'song',
'token': '423dd1067a04e3d58a4b66b3272446ee',
}
response = requests.post('https://api.toubiec.cn/api/music_v1.php', headers=headers, json=json_data)
这个过程有意思的是
请求头中 authorization 的值是没有被加密的token
所以需要修改一下
'authorization': f'Bearer {token_token}',
负载中的请求token为加密过后的token
'token': md5_hash,
最后会得到json返回字符串
{
"status": 200,
"msg": "解析成功!",
"song_info": {
"name": "Chogan (Original Mix)",
"alia": "未知出处",
"artist": "Marco V/East & Young",
"album": "Chogan",
"level": "标准音质",
"cover": "https://p3.music.126.net/dDgMHxznT9X-Y0badZ8GHA==/109951163692764305.jpg?param=320y320"
},
"lrc": {
"lyric": "[00:00.00-1] 作词 : Marco Verkuijlen/Marc van Oosterbaan/Michiel Jenner/Ivo De Jong\n[00:00.00-1] 作曲 : Marco Verkuijlen/Marc van Oosterbaan/Michiel Jenner/Ivo De Jong\n",
"tlyric": ""
},
"yrc": {
"lyric": "未知"
},
"url_info": {
"url": "https://m7.music.126.net/20250312131401/06dc2688d4f0d0140ad299398411c65a/ymusic/075c/070f/5653/06d21f41a30eb4dc06e5a92151089518.mp3?vuutv=xp+x+T3XuON28XERq3ytPx1YBr9BZKeAjzH5MKHo2gATscIcN0Y+UKNX+ujhunVUw1kyrHlI9qb2q/z2ZwhDpZz4NG6v/Md+WMsd8IPvqMo=",
"size": "3.72MB",
"interval": "04:04",
"type": "mp3"
},
"mv_info": {
"url": "未知MV",
"size": "未知MV大小"
},
"copyright": {
"msg": "源码编译:苏晓晴 2023.10.7",
"api_vers": "music_cnv1",
"type": "单曲解析",
"token": "473f583c7dc66072ae38df5a92ae0f51"
}
}
首先将返回数据json格式化
data = response.json()
拿到音乐名称和下载链接
url = data['url_info']['url']
name = data.get("song_info", {}).get("name")
写一个简单的保存代码
response = requests.get(url)
with open(f"{name}.mp3", 'wb') as f:
f.write(response.content)
最后得到单个文件下载成功
最后音质替换第二步请求负载中的
'level'
分别是
1. 标准音质 standard
2. 极高音质 exhigh
3. 无损音质 lossless
4. 高解析度无损 hires
5. 高清环绕音 jyeffect
"6. 沉浸环绕硬音 sky
7. 超声母带 jymaster
最后完整代码