之前有段时间一直在想如何在ios的快捷指令上实现一键获取当前正在直播的房间的真实连接,以便可以只用手机就可以观看直播。
但是我失败了。但是我写出了python版本,先看一下截图:
运行结果简单粗暴,毕竟吾爱已经有很多大佬来发pid转真实链接的了。我主要是爬了当前的主播。
本来是想一口气把所有斗鱼当前所有直播的直播源都爬下来的脚本的,但是运行了一下太慢了,而且写多线程的话估计还会封ip,所以就这样喽。
在此说一下重点:
代码中的class Douyu,是抄的cs某n的大佬代码或者是chiser丶博主的(我不知道谁更早一点)。
我只是爬了所有的主播的房间号而已,这个转链接我是真的不会,毕竟不懂js,没办法获得sign这个参数。
侵删!侵删!侵删! 重要的事情说三遍(不过我觉得大佬都发出来了,就不怕我用一用吧哈哈哈)
希望我可以直接在ios快捷指令上做出来,现在卡在了ios如何用正则了...
好了 废话不多说,代码来啦:
[Python] 纯文本查看 复制代码 # coding=utf-8
# 获取斗鱼直播间的真实流媒体地址,默认最高画质。
import requests
import re
import execjs
import time
import hashlib
import os
import pyperclip
class DouYu:
#这一类 是我参考的chiser丶
def __init__(self, rid):
# 房间号通常为1~7位纯数字,浏览器地址栏中看到的房间号不一定是真实rid.
self.did = '10000000000000000000000000001501'
self.t10 = str(int(time.time()))
self.t13 = str(int((time.time() * 1000)))
self.s = requests.Session()
self.res = self.s.get('https://m.douyu.com/' + str(rid)).text
result = re.search(r'rid":(\d{1,7}),"vipId', self.res)
if result:
self.rid = result.group(1)
else:
#raise Exception('房间号错误')
return '房间号错误'
@staticmethod
def md5(data):
return hashlib.md5(data.encode('utf-8')).hexdigest()
def get_pre(self):
url = 'https://playweb.douyucdn.cn/lapi/live/hlsH5Preview/' + self.rid
data = {
'rid': self.rid,
'did': self.did
}
auth = DouYu.md5(self.rid + self.t13)
headers = {
'rid': self.rid,
'time': self.t13,
'auth': auth
}
res = self.s.post(url, headers=headers, data=data).json()
error = res['error']
data = res['data']
key = ''
if data:
rtmp_live = data['rtmp_live']
key = re.search(r'(\d{1,7}[0-9a-zA-Z]+)_?\d{0,4}(/playlist|.m3u8)', rtmp_live).group(1)
return error, key
def get_js(self):
result = re.search(r'(function ub98484234.*)\s(var.*)', self.res).group()
func_ub9 = re.sub(r'eval.*;}', 'strc;}', result)
js = execjs.compile(func_ub9)
res = js.call('ub98484234')
v = re.search(r'v=(\d+)', res).group(1)
rb = DouYu.md5(self.rid + self.did + self.t10 + v)
func_sign = re.sub(r'return rt;}\);?', 'return rt;}', res)
func_sign = func_sign.replace('(function (', 'function sign(')
func_sign = func_sign.replace('CryptoJS.MD5(cb).toString()', '"' + rb + '"')
js = execjs.compile(func_sign)
params = js.call('sign', self.rid, self.did, self.t10)
params += '&ver=219032101&rid={}&rate=-1'.format(self.rid)
url = 'https://m.douyu.com/api/room/ratestream'
res = self.s.post(url, params=params).text
key = re.search(r'(\d{1,7}[0-9a-zA-Z]+)_?\d{0,4}(.m3u8|/playlist)', res).group(1)
return key
def get_real_url(self):
error, key = self.get_pre()
if error == 0:
pass
elif error == 102:
#raise Exception('房间不存在')
return '房间不存在'
elif error == 104:
#raise Exception('房间未开播')
return '房间未开播'
else:
key = self.get_js()
return "http://tx2play1.douyucdn.cn/live/{}.flv?uuid=".format(key)
def dic():
url = 'https://www.douyu.com/directory'
headers = {
'user-agent': '''Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36''',
}
p = re.compile('class="layout-Classify-card" href="/(\w+)">\n.+?<strong>(\w+)</strong>',re.DOTALL)#其实xpath更好用
html = requests.get(url,headers=headers).text
douyu_list = p.findall(html)
for i in range(len(douyu_list)): #一行显示5个
if (i/5-i//5==0)&(i!=0):
print(str(i)+':'+douyu_list[i][1])
else:
print(str(i)+':'+douyu_list[i][1],end=' ')
url = 'https://www.douyu.com/'+douyu_list[int(input('\n\n请输入你想看的分类: '))][0]
html = requests.get(url,headers=headers).text
#p = re.compile('"nn":"(\w+)".*?"od":"(\w*)".*?"rid":(\d+)') 这个会只能搜索出斗鱼有官方代号的人
p = re.compile('"nn":"(\w+)".*?"rid":(\d+)')
life_list = p.findall(html)
# os.system('cls')
for i in range(len(life_list)): #一行显示5个
if (i/5-i//5==0)&(i!=0):
print(str(i)+':'+life_list[i][0])
else:
print(str(i)+':'+life_list[i][0],end=' ')
s = DouYu(life_list[int(input('\n\n请输入你想看的主播:'))][1])
print('\n')
print(s.get_real_url())
pyperclip.copy(s.get_real_url())
print('\n直播源已复制')
input('按任意键退出')
c = input('1:查看目录\n2:直接输入房间号\n')
if c == '1':
dic()
elif c == '2':
s = DouYu(input('请输入你想看的主播:'))
print(s.get_real_url())
pyperclip.copy(s.get_real_url())
print('\n直播源已复制')
input('按任意键退出')
|