forked from wbt5/real-url
-
Notifications
You must be signed in to change notification settings - Fork 8
/
sports_iqiyi.py
142 lines (125 loc) · 4.03 KB
/
sports_iqiyi.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
# -*- coding: utf-8 -*-
# @Time: 2021/6/19 20:39
# @Project: my-spiders
# @Author: wbt5
# @Blog: https://wbt5.com
import binascii
import hashlib
import json
import re
import time
from urllib.parse import urlencode
import execjs
import requests
class sIQiYi:
def __init__(self, rid):
"""
收费直播间、未开播直播间、已结束直播间获取到的地址均无法播放;
Args:
rid: 这里传入完整的直播间地址
"""
url = rid
self.rid = url.split('/')[-1]
self.s = requests.Session()
def decodeurl(self):
"""
传入url地址,截取url中的直播间id
字符串lgqipu倒序后转为十进制数,作为qpid解码的传参
Returns:
qpid
"""
o = 'lgqipu'
o = int(binascii.hexlify(o[::-1].encode()), 16)
s = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
a = 0
rr = enumerate(self.rid)
for i, _ in rr:
a += s.index(_) * pow(36, len(self.rid) - (i + 1))
a = f'{a:b}'
n = f'{o:b}'
x = len(a)
y = len(n)
if x > y:
i = a[:x - y]
a = a[x - y:]
else:
i = n[:y - x]
n = n[y - x:]
for rs, ele in enumerate(a):
if ele == n[rs]:
i += '0'
else:
i += '1'
qpid = int(i, 2)
return qpid
def get_real_url(self):
"""
里面iqiyi.js是个加盐的md5,execjs执行后获取cmd5x的返回值
Returns:
m3u8格式播放地址
Raises:
Could not find an available JavaScript runtime: 是否安装了js环境
"""
qpid = self.decodeurl()
uid = 'ba4fe551bd889d73f3d321d2fadc6130'
ve = hashlib.md5(f'{qpid}function getTime() {{ [native code] }}{uid}'.encode('utf-8')).hexdigest()
v = {
'lp': qpid,
'src': '01014351010000000000',
'ptid': '02037251010000000000',
'uid': '',
'rateVers': 'H5_QIYI',
'k_uid': uid,
'qdx': 'n',
'qdv': 3,
'dfp': '',
've': ve,
'v': 1,
'k_err_retries': 0,
'tm': int(time.time()),
'k_ft4': 17179869185,
'k_ft1': 141287244169216,
'k_ft5': 1,
'qd_v': 1,
'qdy': 'a',
'qds': 0,
# 'callback': 'Q3d080ff19d8f233acb05683bf38e3a15',
# 'vf': 'f0b986f100ae81fff8e8f8f96053e815',
}
k = '/jp/live?' + urlencode(v)
cb = hashlib.md5(k.encode('utf-8')).hexdigest()
k = f'{k}&callback=Q{cb}'
# 生成vf
with open('iqiyi.js', 'r') as f:
content = f.read()
try:
cmd5x = execjs.compile(content)
vf = cmd5x.call('cmd5x', k)
except RuntimeError:
raise Exception('Could not find an available JavaScript runtime.')
# 请求url
url = f'https://live.video.iqiyi.com{k}&vf={vf}'
res = self.s.get(url).text
data = re.search(r'try{\w{33}\(([\w\W]+)\s\);}catch\(e\){};', res).group(1)
data = json.loads(data)
if data['code'] == 'A00004':
raise Exception('直播间地址错误!')
elif data['code'] == 'A00000':
try:
url = data['data']['streams'][-1]['url']
except IndexError:
raise Exception('可能直播未开始直播或为付费直播!')
else:
raise Exception('无法定位错误原因,可提交issue!')
return url
def get_real_url(rid):
try:
siqiyi = sIQiYi(rid)
return siqiyi.get_real_url()
except Exception as e:
print('Exception:', e)
return False
if __name__ == '__main__':
r = input('请输入爱奇艺体育直播间完整地址地址,注意只能获取免费直播:\n')
# https://sports.iqiyi.com/resource/pcw/live/gwbgbfbgc3
print(get_real_url(r))