郑重声明:
本项目的所有代码和相关文章,仅用于经验技术交流分享,禁止将相关技术应用到不正当途径,因为滥用技术产生的风险与本人无关。
文章仅源自个人兴趣爱好,不涉及他用,侵权联系删
1 目标
爬取目标网站音频数据
2 网站
https://www.ximalaya.com/gerenchengzhang/19596428/
3 流程分析
3.1 目标页分析
F12,点击播放按钮,我们发现一个音频文件https://aod.cos.tx.xmcdn.com/group53/M02/1C/D5/wKgLfFv8v8WjjPi3AJIoAbFhZp8330.m4a
发现是我们刚才首页点击播放的音频,同理,我们需要的是下面所有课程的音频数据,可以测试一下,
音频就在这里,那让我们来拿到数据。
3.2 详情页尝试拿数据
None,直接访问链接https://www.ximalaya.com/revision/play/v1/audio?id=139836377&ptype=1
查看一下请求头,发现 xm-sign是由js加密而成,会即时发生变化,所以我们需要在请求的时候带上xm-sign参数即可拿到数据。
3.3 寻找js加密文件
全局搜索xm-sign,找到所在js文件,在此断点调试,找到所在函数.getSign(),
查看函数所在位置,继续断点调试
这里,我们基本发现xm-sign的生成代码了,跟以前大同小异
e = Date[s("0x2c")](),
"{himalaya-"[s("0x2d")](t, "}(")[s("0x2d")](p(100), ")")[s("0x2d")](t, "(")[s("0x2d")](p(100), ")")[s("0x2d")](e).replace(/{([\w-]+)}/, (function(t, e) {
return c(e)
}
))
此处使用replace是将{}里面的数据替换成c(e)函数返回的数据。这里t就是服务器的时间戳
使用get请求,会返回服务器的时间戳,e,就是现在的时间戳,此时我们就可以大致构造出xm-sign的代码了,
{} +(100以内的随机数) + 服务器时间戳 + (100以内的随机数) + 现在的时间戳,因为{}的数据被替换为c(e)函数返回的值,所以我们继续进入函数,断点调试。
得到(此处为之前截取,可自行调试,我这太卡。。)
格式类似于MD5编码,md5加密的数据,一般都是32位的字符,我们尝试一下
(这里喜马拉雅会将字母变动,现在版本为hamalaya),此时我们就可以直接调用python的md5进行编码即可,不需调用js。到这里我们就得到了xm-sign完整生成过程。
md5(ximalaya-服务器时间戳) +(100以内的随机数) + 服务器时间戳 + (100以内的随机数) + 现在的时间戳
对应代码
sign = str(hashlib.md5("himalaya-{}".format(serverTime).encode()).hexdigest()) + "({})".format(str(round(random.random()*100))) + serverTime + "({})".format(str(round(random.random()*100))) + nowTime
简单整理整体代码:
# -*- coding: utf-8 -*-
import requests
import time
import hashlib
import random
import json
from requests.packages.urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
# 获取sign签名
def get_sign(headers):
serverTimeUrl = "https://www.ximalaya.com/revision/time"
response = requests.get(serverTimeUrl,headers=headers,verify=False)
serverTime = response.text
nowTime = str(round(time.time()*1000))
sign = str(hashlib.md5("himalaya-{}".format(serverTime).encode()).hexdigest()) + "({})".format(str(round(random.random()*100))) + serverTime + "({})".format(str(round(random.random()*100))) + nowTime
# 在这里添加入请求头
headers["xm-sign"] = sign
return headers
def get_header():
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.90 Safari/537.36"
}
headers = get_sign(headers)
return headers
if __name__ == '__main__':
# 这是一个搜索接口
url = "https://www.ximalaya.com/revision/play/v1/audio?id=139836377&ptype=1"
s = requests.get(url,headers=get_header(),verify=False)
print(s.json())
"""
return
{'ret': 200, 'data': {'trackId': 139836377, 'canPlay': True, 'isPaid': False, 'hasBuy': True, 'src': 'https://aod.cos.tx.xmcdn.com/group53/M02/1C/D5/wKgLfFv8v8WjjPi3AJIoAbFhZp8330.m4a', 'albumIsSample': False, 'sampleDuration': 0, 'isBaiduMusic': False, 'firstPlayStatus': True, 'isVipFree': False, 'lyricPath': ''}}
"""
到此就成功拿到src数据,成功拿到音频文件https://aod.cos.tx.xmcdn.com/group53/M02/1C/D5/wKgLfFv8v8WjjPi3AJIoAbFhZp8330.m4a。
转载请注明转自:https://blog.csdn.net/Owen_goodman/article/details/108579622