参考了一篇文章很有用
分析
从其源码上看,获取斗鱼的直播源倒也没有太复杂,总结起来就是以form-data
的形式向https://m.douyu.com/api/room/ratestream
发送POST
请求,如果成功,就会返回带有短效直播源地址的Json
,将短效直播源地址修改一下就能够获得一个长效的直播源地址。
而form-data
的结构中,唯一比较复杂的一点在于sign
值的获取。整个结构如下表:
form-data属性 | 值 | 备注 |
---|---|---|
v | 2501+tradetime | tradetime为当天日期,例如:20191031 |
did | 10000000000000000000000000001501 | 固定值 |
tt | timestamp | 10位时间戳,例如:1572507694 |
sign | sign | 32位加密字符串 |
ver | 219032101 | 固定值 |
rid | roomid | 实际直播房间ID |
rate | -1 | 固定值 |
具体代码如下,具体分析看我添加的注释,方便新手快速看懂。
tradetime和timestamp获取
def get_tt():
tt1 = str(int(time.time())) #10位时间戳
tt2 = str(int((time.time() * 1000))) #13位时间戳
today = time.strftime('%Y%m%d', time.localtime()) #当天日期
return tt1, tt2, today
roomid和sign获取
def get_homejs(rid):
room_url = 'https://m.douyu.com/' + rid
response = requests.get(url=room_url)
pattern_real_rid = r'"rid":(\d{1,7})'
real_rid = re.findall(pattern_real_rid, response.text, re.I)[0] #获取roomid(有一些主播的房间ID是viprid,也就是表面上的rid,例如周淑怡的22222,实际上则是290935)
if real_rid != rid:
room_url = 'https://m.douyu.com/' + real_rid
response = requests.get(url=room_url)
homejs = ''
pattern = r'(function ub9.*)[\s\S](var.*)'
result = re.findall(pattern, response.text, re.I)
str1 = re.sub(r'eval.*;}', 'strc;}', result[0][0])
homejs = str1 + result[0][1] #获得第一段JS代码
return homejs, real_rid
def get_sign(rid, post_v, tt, ub9):
docjs = execjs.compile(ub9) #执行第一段JS代码
res2 = docjs.call('ub98484234') #调用JS代码里的函数“ub98484234”
str3 = re.sub(r'\(function[\s\S]*toString\(\)', '\'', res2)
md5rb = hashlib.md5((rid + '10000000000000000000000000001501' + tt + '2501' +
post_v).encode('utf-8')).hexdigest()
str4 = 'function get_sign(){var rb=\'' + md5rb + str3
str5 = re.sub(r'return rt;}[\s\S]*','return re;};', str4)
str6 = re.sub(r'"v=.*&sign="\+', '', str5) #获得第二段JS代码
docjs1 = execjs.compile(str6) #执行第二段JS代码
sign = docjs1.call(
'get_sign', rid, '10000000000000000000000000001501', tt) #调用JS里的函数“get_sign”以获取sign值
return sign
获取和修改直播源地址
def get_sign_url(post_v, rid, tt, ub9):
sign = get_sign(rid, post_v, tt, ub9)
request_url = 'https://m.douyu.com/api/room/ratestream'
post_data = {
'v': '2501' + post_v,
'did': '10000000000000000000000000001501',
'tt': tt,
'sign': sign,
'ver': '219032101',
'rid': rid,
'rate': '-1'
}
header = {
'Content-Type': 'application/x-www-form-urlencoded',
'User-Agent': 'Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Mobile Safari/537.36'
}
response = requests.post(url=request_url, headers=header, data=post_data).json()
通过get_sign_url
函数获得Json
后可以从中提取到短效直播源地址。
举个例子,下方是提取的短效直播源地址,提取里边的290935rl8pFB4Chu
。
http://hls1a.douyucdn.cn/live/290935rl8pFB4Chu_2000/playlist.m3u8?wsSecret=8e85c3c47dcfd12c0f3f626b7e9dc06e\u0026wsTime=1572509708\u0026token=h5-douyu-0-290935-a9b3efee00dd21938f948106b9d7c0df\u0026did=10000000000000000000000000001501\u0026origin=all\u0026vhost=play2
短效的我不知道是多短效,反正自己放在电视的iptv中很好用,网上找的接口速度太慢,自己经过上面的分析之后稍作修改放在了flask的接口中,以后自己看电视可方便多了,自己测试切换斗鱼节目源时间在2s以内,可以接受,人真的是需要不断的去学习成长,抽空我再来研究这个斗鱼的js
之后执行flask /usr/local/bin/python3 /usr/local/bin/gunicorn –daemon -b 127.0.0.1:5005 -w 2 everyday_web:app
如果提示失败不能启动就要看下是否是centos缺少node环境,不然不能执行execjs的,其他的一路顺利,很赞。。。。