拨开荷叶行,寻梦已然成。仙女莲花里,翩翩白鹭情。
IMG-LOGO
主页 文章列表 Python获取优酷真实m3u8播放链接,成品来了

Python获取优酷真实m3u8播放链接,成品来了

白鹭 - 2022-03-15 2130 0 0

目录

前言

使用前说明

完整原始码

打包好的软件


前言

大家好我叫善念

CSDN很好的,把一群喜欢编程的小伙伴都聚集在了一起,
平时也喜欢来逛逛,学习一些大佬的经验,
现在,我也来分享一下


使用前说明


1. 考虑到一部分小伙伴编码基础薄弱,接下来,我也会详细的解说一下,


2. 阉割了决议后直接播放的功能, 如果需要, 可以将代码里播放的功能位置,把注释去掉即可,懂的应该能懂,

关于 cookie的获取:
打开 优酷首, 按F12 (这是一个功能键), 打开到网络, 然后重绘浏览器!



这样就抓到包了, 找到首页的包, 点击一下, 如图所示, 复制这里的 cookie



然后再粘贴到 决议工具里面!!! 最后找到需要决议的视频链接, 粘贴进去,,,,



接下来,就决议完成了,



接下来, 就是复制m3u8地址, 找个下载工具就能下载了,

完整原始码

import re, requests, time, subprocess, json, base64
from hashlib import md5

class YouKu:
    def __init__(self, cookie):
        self.cookie = cookie

    def youku_sign(self, t, data, token):
        appKey = '24679788'     # 固定值
        '''token值在cookie中'''
        sign = token + '&' + t + '&' + appKey + '&' + data
        md = md5()
        md.update(sign.encode('UTF-8'))
        sign = md.hexdigest()
        return sign

    def utid(self):
        cna = re.compile("cna=(.*?);")
        _m_h5_tk = re.compile("_m_h5_tk=(.*?)_.*?;")
        token = _m_h5_tk.findall(self.cookie+";")
        utid_ = cna.findall(self.cookie+";")
        return {"utid": utid_[0], "token": token[0]}

    # 若直接在首页小视窗上复制的视频网址,是重定向的网址,
    def redirect(self, url):
        headers = {
            "referer": "https://www.youku.com/",
            "user-agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36",
        }
        resp = requests.get(url=url, headers=headers)
        return resp.url

    def page_parser(self, url):
        headers = {
            "authority": "v.youku.com",
            "method": "GET",
            "path": url.replace("https://v.youku.com/",""),
            "scheme": "https",
            "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
            "accept-encoding": "gzip, deflate, br",
            "accept-language": "zh-CN,zh;q=0.9",
            "cache-control": "max-age=0",
            "cookie": self.cookie,
            "referer": "https://www.youku.com/",
            "sec-fetch-dest": "document",
            "sec-fetch-mode": "navigate",
            "sec-fetch-site": "none",
            "sec-fetch-user": "?1",
            "upgrade-insecure-requests": "1",
            "user-agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36",
        }
        resp = requests.get(url=url, headers=headers)
        html = resp.content.decode("utf-8")
        # print(html)
        videoId = re.compile("videoId: '(.*?)'")
        showid = re.compile("showid: '(.*?)'")
        currentEncodeVid = re.compile("currentEncodeVid: '(.*?)'")
        videoId = videoId.findall(html, re.S | re.M | re.I)
        current_showid = showid.findall(html, re.S | re.M | re.I)
        vid = currentEncodeVid.findall(html, re.S | re.M | re.I)
        return {"current_showid": current_showid[0], "videoId": videoId[0], "vid": vid[0]}

    def get_emb(self, videoId):
        emb = base64.b64encode(("%swww.youku.com/" % videoId).encode('utf-8')).decode('utf-8')
        return emb

    # 这个函式用来获取元素的第一个值
    def takeOne(self, elem):
        return float(elem[0])

    def m3u8_url(self, t, params_data, sign):
        url = "https://acs.youku.com/h5/mtop.youku.play.ups.appinfo.get/1.1/"

        params = {
            "jsv": "2.5.8",
            "appKey": "24679788",
            "t": t,
            "sign": sign,
            "api": "mtop.youku.play.ups.appinfo.get",
            "v": "1.1",
            "timeout": "20000",
            "YKPid": "20160317PLF000211",
            "YKLoginRequest": "true",
            "AntiFlood": "true",
            "AntiCreep": "true",
            "type": "jsonp",
            "dataType": "jsonp",
            "callback": "mtopjsonp1",
            "data": params_data,
        }

        headers = {
            "Accept": "*/*",
            "Accept-Encoding": "gzip, deflate, br",
            "Accept-Language": "zh-CN,zh;q=0.9",
            "Connection": "keep-alive",
            "Cookie": self.cookie,
            "Host": "acs.youku.com",
            "Referer": "https://v.youku.com/v_show/id_XNTA1MTYwMzU0OA==.html?spm=a2h0c.8166622.PhoneSokuUgc_3.dscreenshot",
            "Sec-Fetch-Dest": "script",
            "Sec-Fetch-Mode": "no-cors",
            "Sec-Fetch-Site": "same-site",
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36",
        }

        resp = requests.get(url=url, params=params, headers=headers)
        result =resp.text
        # print(result)
        data = json.loads(result[12:-1])
        # print(data)
        ret = data["ret"]
        video_lists = []
        if ret == ["SUCCESS::呼叫成功"]:
            stream = data["data"]["data"]["stream"]
            title = data["data"]["data"]["video"]["title"]
            print("决议成功:")
            for video in stream:
                m3u8_url = video["m3u8_url"]
                width = video["width"]
                height = video["height"]
                size = video["size"]
                size = '{:.1f}'.format(float(size) / 1048576)
                video_lists.append([size, width, height, title, m3u8_url])
                # print(f">>>  {title} 分辨率:{width}x{height} 视频大小:{size}M \tm3u8播放地址:{m3u8_url}")

            video_lists.sort(key=self.takeOne)
            for video_list in video_lists:
                print(f">>>  {title} 分辨率:{video_list[1]}x{video_list[2]} 视频大小:{video_list[0]}M \tm3u8播放地址:{video_list[4]}")
            # self.play(video_lists[-1][4])    # 选择播放串列最后一个视频(经过sort排序后,最后一个即为清晰度最高的一个)
        elif ret == ["FAIL_SYS_ILLEGAL_ACCESS::非法请求"]:
            print("请求自变量错误")
        elif ret == ["FAIL_SYS_TOKEN_EXOIRED::令牌过期"]:
            print("Cookie过期")
        else:
            print(ret[0])


    def play(self, x):
        text = 'ffplay -protocol_whitelist "file,http,https,rtp,udp,tcp,tls" -loglevel quiet -i "%s"' % x
        subprocess.call(text, shell=True)

    def start(self):
        while True:
            try:
                t = str(int(time.time() * 1000))
                user_info = self.utid()
                userid = user_info["utid"]
                url = input("\n\n请将优酷视频播放链接粘贴到这:\n")
                url = self.redirect(url)
                page_info = self.page_parser(url)
                emb = self.get_emb(page_info["videoId"])
                params_data = r'''{"steal_params":"{\"ccode\":\"0502\",\"client_ip\":\"192.168.1.1\",\"utid\":\"%s\",\"client_ts\":%s,\"version\":\"2.1.69\",\"ckey\":\"DIl58SLFxFNndSV1GFNnMQVYkx1PP5tKe1siZu/86PR1u/Wh1Ptd+WOZsHHWxysSfAOhNJpdVWsdVJNsfJ8Sxd8WKVvNfAS8aS8fAOzYARzPyPc3JvtnPHjTdKfESTdnuTW6ZPvk2pNDh4uFzotgdMEFkzQ5wZVXl2Pf1/Y6hLK0OnCNxBj3+nb0v72gZ6b0td+WOZsHHWxysSo/0y9D2K42SaB8Y/+aD2K42SaB8Y/+ahU+WOZsHcrxysooUeND\"}","biz_params":"{\"vid\":\"%s\",\"play_ability\":16782592,\"current_showid\":\"%s\",\"preferClarity\":99,\"extag\":\"EXT-X-PRIVINF\",\"master_m3u8\":1,\"media_type\":\"standard,subtitle\",\"app_ver\":\"2.1.69\",\"h265\":1}","ad_params":"{\"vs\":\"1.0\",\"pver\":\"2.1.69\",\"sver\":\"2.0\",\"site\":1,\"aw\":\"w\",\"fu\":0,\"d\":\"0\",\"bt\":\"pc\",\"os\":\"win\",\"osv\":\"10\",\"dq\":\"auto\",\"atm\":\"\",\"partnerid\":\"null\",\"wintype\":\"interior\",\"isvert\":0,\"vip\":1,\"emb\":\"%s\",\"p\":1,\"rst\":\"mp4\",\"needbf\":2,\"avs\":\"1.0\"}"}'''% (userid, t[:10], page_info["vid"], page_info["current_showid"], emb)
                sign = self.youku_sign(t, params_data, user_info["token"])
                self.m3u8_url(t, params_data, sign)
            except Exception as e:
                print('error:',e , "或可能cookie设定错误")
                break

if __name__ == '__main__':
    print("="*35 +'>> 欢迎使用优酷视频m3u8地址决议工具 <<'+"="*35)
    cookie = input("\n使用前,请设定优酷的cookie:\n")
    print("\n这是一个回圈:可以不停的决议...")
    youku = YouKu(cookie)
    youku.start()

打包好的软件

标签:

0 评论

发表评论

您的电子邮件地址不会被公开。 必填的字段已做标记 *