![1722000ecb59f1081d39812920c42e64.png](https://img-blog.csdnimg.cn/img_convert/1722000ecb59f1081d39812920c42e64.png)
原文链接
https://mp.weixin.qq.com/s/bh8Y2Ix0G6yPNh1J0EklnAmp.weixin.qq.com导语
万年拖更党周末终于准时上线更新啦~
小伙伴们还记得公众号之前开源的音乐下载器嘛:
哇,公众号发布的音乐下载器又全新升级啦~
自从发了这篇文章之后,每隔一段时间就会收到小伙伴们关于xxx平台又失效了的私信。作为一个成熟的小伙伴,你明明应该学会自己试着分析一下失效的原因,然后在Github上给我一个PR呀,难道关注我的小伙伴都是传说中的产品经理。(开个玩笑,PM们别生气哈~)
默默更新了repo一段时间之后,我决定上线手把手教学一波,希望小伙伴们能学会自己抓包分析,而不是只吃鱼,不捕鱼。正好百度的千千音乐的接口又失效了,就拿它举例来说明呗。
废话不多说,让我们愉快地开始吧~
开发工具
Python版本:3.6.4
相关模块:
requests模块;
pycryptodome模块;
click模块;
prettytable模块;
以及一些python自带的模块。
环境搭建
安装Python并添加到环境变量,pip安装需要的相关模块即可。
原理简介
根据小伙伴们的反馈,之前的接口返回的数据一直是空,简单测试一下是不是真的是这样:
import requests
params = {
'query': '那些年',
'method': 'baidu.ting.search.common',
'format': 'json',
'page_no': '1',
'page_size': '5'
}
url = 'http://musicapi.qianqian.com/v1/restserver/ting'
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36',
'Referer': 'http://music.baidu.com/'
}
print(requests.get(url, headers=headers, params=params).json())
上面的代码运行效果如下:
![a9998607ac963e9120ba6cfe464cee5d.png](https://img-blog.csdnimg.cn/img_convert/a9998607ac963e9120ba6cfe464cee5d.png)
看来是真的失效了,那就重新去抓一波包呗,首先去千千音乐的官网尝试性地搜索一些歌名(记得打开开发者工具哈~):
![42b071295377ca8a0a6e9cfb5eb33648.png](https://img-blog.csdnimg.cn/img_convert/42b071295377ca8a0a6e9cfb5eb33648.png)
可以发现只需要请求以下接口就可以返回搜索结果了:
![33feda5d5bb1e019e47575b74caa0ed7.png](https://img-blog.csdnimg.cn/img_convert/33feda5d5bb1e019e47575b74caa0ed7.png)
而请求这个接口需要携带的参数如下:
![7893988b38b848fbee9280f227a8f6b4.png](https://img-blog.csdnimg.cn/img_convert/7893988b38b848fbee9280f227a8f6b4.png)
显然,各参数的含义为:
sign: 签名
word: 搜索的关键词
timestamp: 时间戳, int(time.time())就可以获取了
那么现在的问题就是如何确定sign值了,和之前一样,看下请求是如何发起的:
![269b7a48ba21c1c9326e072a9d220650.png](https://img-blog.csdnimg.cn/img_convert/269b7a48ba21c1c9326e072a9d220650.png)
逐个搜索之后,发现sign值的计算在这个js文件里定义了:
![de6ba13cfc50d2cfeab2fb7b876f0380.png](https://img-blog.csdnimg.cn/img_convert/de6ba13cfc50d2cfeab2fb7b876f0380.png)
打个断点重新运行后各个参数的含义就一目了然啦:
![80da9291c01148344170a5ce78600e5c.png](https://img-blog.csdnimg.cn/img_convert/80da9291c01148344170a5ce78600e5c.png)
把js代码转成python后简单测试一下:
import time
import hashlib
import requests
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36',
'Referer': 'https://music.taihe.com/'
}
secret = '0b50b02fd0d73a9c4c8c3a781c30845f'
e = {
'word': '如果当时',
'timestamp': str(int(time.time()))
}
n = list(e.keys())
n.sort()
i = f'{n[0]}={e[n[0]]}'
for r in range(1, len(n)):
o = n[r]
i += f'&{o}={e[o]}'
sign = hashlib.md5((i + secret).encode('utf-8')).hexdigest()
params = {
'sign': sign,
'word': '如果当时',
'timestamp': str(int(time.time()))
}
url = 'https://music.taihe.com/v1/search'
print(requests.get(url, headers=headers, params=params).json())
效果如下:
![bd1af6c06a2c2267773d2c20e3c08451.png](https://img-blog.csdnimg.cn/img_convert/bd1af6c06a2c2267773d2c20e3c08451.png)
大功告成,类似地,再来看看歌曲下载部分的请求抓包:
![3c685e0eb033abd4964e3e472b37bb0d.png](https://img-blog.csdnimg.cn/img_convert/3c685e0eb033abd4964e3e472b37bb0d.png)
多了三个参数,但都是已知的:
TSID: T10038826793, 歌曲的ID, 请求搜索接口的时候会返回
from: web, 固定值
s_protocol: 1, 固定值
写个类似的脚本简单测试一下发现返回的数据确实是对的:
![dc5ba6f19ccf4e69212f517940dfe04a.png](https://img-blog.csdnimg.cn/img_convert/dc5ba6f19ccf4e69212f517940dfe04a.png)
于是,经过我们的不屑努力,终于成功修复了我们开源的音乐下载的千千音乐部分啦,效果如下:
![51cfdc8f3fc23cfa1516c7757ffd7d0b.png](https://img-blog.csdnimg.cn/img_convert/51cfdc8f3fc23cfa1516c7757ffd7d0b.png)
完整源代码详见相关文件哈~
效果展示
知乎视频www.zhihu.com相关文件
本文涉及到的所有相关源代码见:
CharlesPikachu/musicdl