喜马拉雅是国内出名的音频网站,里面分为付费和免费的音频,小编这里教大家无需登录下载非vip音频,付费的小编还没有达到这个水平,主要是学习破解喜马拉雅xm-sign加密字段的方法
我们还是用老方法,先找接口,随便点击一个音频找到它加载的url,复制红圈里的内容,进行全局搜索
搜索后,找到一个新的URL,并且这个url的id就是网址中的最后一串数字,这个方法和kuwo音乐是一致的
并且我们在这个URL中的response选项卡中,可以找到最开始的url地址,说明音频的地址来源于
https://www.ximalaya.com/revision/play/v1/audio?id=324390263&ptype=1, 这个就是接口。根据经验更改这个id就可以链接到不同的音频
喜马拉雅不同的是,它有一个xm-sign加密字段,按照以往的话,如果我们直接访问这个URL,会得到一个字典形式的json数据,可以提取出来键为src的值,但是对于喜马拉雅不行,大家可以试试
访问结果如上图,得不到数据,这是因为我们在请求这个网页的时候,缺少xm-sign,需要把它加载请求头headers中去,再加上UA伪装,就可以了
接下来我们分析这个xm-sign
也就是生成这个东西,它的生成涉及到md5算法,时间戳(服务器时间戳和真实时间戳)和随机数,md5是一种加密的不可逆算法,需要在pycharm中安装第三方模块hashlib,根据小编查阅的资料以及咨询一些大神,这个xm-sign是由md5(himalaya-服务器时间戳)+100内随机数 +服务器时间戳 + 100内随机数 + 真实时间戳 组成
服务器时间戳由request 网址 https://www.ximalaya.com/revision/time 获得
随机数引入random
生成xm-sign的代码为
url = 'https://www.ximalaya.com/revision/time'
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36'
}
response = requests.get(url=url,headers=headers)
server_time = response.text
real_time = str(round(time.time()*1000))
xm_sign = str(hashlib.md5("himalaya-{}".format(server_time).encode()).hexdigest()) + "({})".format(str(round(random.random()*100))) + server_time + "({})".format(str(round(random.random()*100))) + real_time
print('此次请求的反爬xm-sign为{}'.format(xm_sign))
另外知乎上一位大神也分析了这个东西,写的比我好,大家也可以学习一下
https://zhuanlan.zhihu.com/p/217949786
将此xm-sign加入请求头后,就可以对URL进行访问了
此时访问的结果为
如果不加这个字段,是请求不到数据的,此时就简单了,按照字典格式的数据提取方法,就可以对src进行提取
用request对src的值进行访问保存即可
整个过程共使用的三次request,第一次是访问服务器时间戳,第二次是用来访问接口,第三次是访问音频。只有第二次需要加xm-sign,其余两次不需要
下面附上整个代码,运行时将网址输入即可例如https://www.ximalaya.com/xiangsheng/40601966/324390263,注意只能是喜马拉雅非vip 的音频,本文实际用处不大,可以学习用
import time
import hashlib
import random
import requests
input_url = input('请输入喜马拉雅网址:')
media_id = input_url.split('/')[-1].strip(' ')
print('歌曲id号为{}'.format(media_id))
print('正在生成反爬的xm-sign...')
url = 'https://www.ximalaya.com/revision/time'
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36'
}
response = requests.get(url=url,headers=headers)
server_time = response.text
real_time = str(round(time.time()*1000))
xm_sign = str(hashlib.md5("himalaya-{}".format(server_time).encode()).hexdigest()) + "({})".format(str(round(random.random()*100))) + server_time + "({})".format(str(round(random.random()*100))) + real_time
print('此次请求的反爬xm-sign为{}'.format(xm_sign))
new_headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36',
'xm-sign':xm_sign
}
media_url = 'https://www.ximalaya.com/revision/play/v1/audio?id={}&ptype=1'.format(media_id)
media_response = requests.get(url=media_url,headers=new_headers)
print(media_response.text)
print('请求音频网络地址为:')
print(media_response.json()['data']['src'])
media_url_listen = media_response.json()['data']['src']
print('正在下载')
media_response_listen = requests.get(url=media_url_listen,headers=headers)
with open(r'D:\喜马拉雅\{}.mp3'.format(media_id),'wb') as f:
f.write(media_response_listen.content)
print('完成')
附上效果视频
QQ录屏20210630123033