丶霁灵 发表于 2021-5-30 23:43

【python源码】斗鱼直播伴侣(potplayer或nplayer)

之前有段时间一直在想如何在ios的快捷指令上实现一键获取当前正在直播的房间的真实连接,以便可以只用手机就可以观看直播。
但是我失败了。但是我写出了python版本,先看一下截图:


运行结果简单粗暴,毕竟吾爱已经有很多大佬来发pid转真实链接的了。我主要是爬了当前的主播。
本来是想一口气把所有斗鱼当前所有直播的直播源都爬下来的脚本的,但是运行了一下太慢了,而且写多线程的话估计还会封ip,所以就这样喽。

在此说一下重点:
代码中的class Douyu,是抄的cs某n的大佬代码或者是chiser丶博主的(我不知道谁更早一点)。
我只是爬了所有的主播的房间号而已,这个转链接我是真的不会,毕竟不懂js,没办法获得sign这个参数。
侵删!侵删!侵删!   重要的事情说三遍(不过我觉得大佬都发出来了,就不怕我用一用吧哈哈哈)


希望我可以直接在ios快捷指令上做出来,现在卡在了ios如何用正则了...
好了 废话不多说,代码来啦:
# 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}+)_?\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}+)_?\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)
      else:
            print(str(i)+':'+douyu_list,end='   ')

    url = 'https://www.douyu.com/'+douyu_list
    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)
      else:
            print(str(i)+':'+life_list,end='   ')



    s = DouYu(life_list)
    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('按任意键退出')

轻凨 发表于 2021-5-31 06:22

感谢分享

tzlqjyx 发表于 2021-5-31 07:28

感谢分享,学习下思路

Wapj_Wolf 发表于 2021-5-31 07:44

感谢楼主分享PY源码,学习中……

吃兔子的肉 发表于 2021-5-31 07:58

学习了学习了

huanghen2 发表于 2021-5-31 08:13

学习一下 ,感谢楼主分享PY源码

风的梦想 发表于 2021-5-31 08:18

来学习学习

ermao 发表于 2021-5-31 08:25

移动端跳转APP:
douyutv://?type=4&room_id=8067328

Spa495 发表于 2021-5-31 08:54

感谢分享

supnet 发表于 2021-5-31 09:01

点赞支持
页: [1] 2 3
查看完整版本: 【python源码】斗鱼直播伴侣(potplayer或nplayer)