Files
tvbox_collect/tbapi2/py/app/proxy_drama.py
T
2026-07-05 04:58:38 +00:00

185 lines
6.6 KiB
Python

# -*- coding: utf-8 -*-
# 本资源来源于互联网公开渠道,仅可用于个人学习爬虫技术。
# 严禁将其用于任何商业用途,下载后请于 24 小时内删除,搜索结果均来自源站,本人不承担任何责任。
import traceback
from base64 import b64encode
from base.spider import Spider
from Crypto.PublicKey import RSA
from Crypto.Util.Padding import pad
from urllib.parse import quote_plus, unquote_plus, urlencode
import sys,time,json,random,hashlib,urllib3
from Crypto.Cipher import AES, PKCS1_v1_5
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
sys.path.append('..')
class Spider(Spider):
cache_host = {}
def localProxy(self, params):
if params.get('type') == 'drama':
response = '获取域名失败'
try:
if params.get('from') == 'host':
url = params.get('url')
if url.startswith('http'):
response = self.cache_host.get(url)
if not(response and isinstance(response,str) and response.startswith('http')):
res = self.fetch(url,headers={'User-Agent': 'okhttp/3.12.1'}).json()
print('域名获取结果:',res)
if res['domain'].startswith('http'):
response = res['domain']
self.cache_host[url] = response
elif params.get('from') == 'paramsData':
data = self.params_data(params)
response = data
return [200, 'text/text;charset=utf-8', response]
except Exception as e:
return [500, 'text/text;charset=utf-8', f'处理出错: {e}\n\n错误堆栈:\n{traceback.format_exc()}']
return None
def params_data(self,params):
ver_name = params.get('verName')
ver = params.get('ver',ver_name.replace('.',''))
app_name = params.get('AppName')
pkg = params.get('pkg')
public_key = params.get('publicKey').replace(' ','+')
if not(ver and ver_name and app_name and pkg and public_key): return '请按要求传参'
# 设备信息
android_id = '313c3eeeb2a098a1'
mac = '02:00:00:00:00:00' # 网卡MAC地址
model = '23113RKC6C' # 型号
manufacturer = 'Xiaomi' # 制造商
# 计算UUID
uuid = hashlib.md5(f"{android_id}{mac}{model}{manufacturer}".encode()).hexdigest().upper()
timestamp = self.get_13_digit_timestamp()
random_str = self.random_str_function()
# AES加密生成sign
aes_key = 'OC1A06E197EF10CF3F6058CA7A803B5E'.encode()
cipher_aes = AES.new(aes_key, AES.MODE_ECB)
sign_data = f"{timestamp}{random_str}".encode()
sign_encrypted = cipher_aes.encrypt(pad(sign_data, AES.block_size))
sign = b64encode(sign_encrypted).decode()
# 构建设备信息
device_info = {
"country": "CN",
"vName": ver_name,
"cpuId": "",
"young": 0,
"facturer": manufacturer,
"pkg": pkg,
"uuid": uuid,
"resolution": "900x1600",
"mac": quote_plus(mac),
"sig": self.rsa_encrypt(f"{timestamp}{random_str}{ver}", public_key),
"abid": "6249",
"model": model,
"plat": "android",
"udid": uuid,
"dpi": "240",
"net": "1",
"lang": "zh",
"random_str": random_str,
"brand": "Redmi", # 品牌
"timestamp": timestamp,
"density": "3.25",
"appName": quote_plus(app_name),
"cpu": "arm64-v8a",
"chid": "10000",
"carrier": quote_plus('移动'), # 网络运营商
"sig2": sign[:8],
"sig3": sign[8:],
"_vOsCode": "32",
"vOs": "12", # 安卓版本
"vApp": ver,
"device": "0",
"androidID": android_id
}
# JSON序列化并AES加密
dat = json.dumps(device_info, ensure_ascii=False, separators=(',', ':'))
# AES-128-CBC加密
aes_key2 = 'ed5fdsgucxumegqa'.encode()
iv = 'ed5fdsgucxumegqa'.encode()
cipher_aes2 = AES.new(aes_key2, AES.MODE_CBC, iv)
dat_encrypted = cipher_aes2.encrypt(pad(dat.encode(), AES.block_size))
dat_hex = dat_encrypted.hex()
return dat_hex
def rsa_encrypt(self,plaintext, public_key_str):
"""RSA加密"""
# 构建PEM格式的公钥
public_key_pem = f"-----BEGIN PUBLIC KEY-----\n{public_key_str}\n-----END PUBLIC KEY-----"
# 导入公钥
rsa_key = RSA.import_key(public_key_pem)
cipher_rsa = PKCS1_v1_5.new(rsa_key)
# 加密
encrypted = cipher_rsa.encrypt(plaintext.encode())
# Base64编码
return b64encode(encrypted).decode()
def random_str_function(self,length=16):
"""生成随机字符串"""
char_array = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
result_str = ''
i = 0
while i < length - 1:
c = random.choice(char_array)
if c not in result_str:
result_str += c
i += 1
return result_str + "="
def get_13_digit_timestamp(self):
"""获取13位时间戳"""
return int(round(time.time() * 1000))
def init(self, extend=''):
pass
def homeContent(self, filter):
pass
def homeVideoContent(self):
pass
def categoryContent(self, tid, pg, filter, extend):
pass
def searchContent(self, key, quick, pg='1'):
pass
def detailContent(self, ids):
pass
def playerContent(self, flag, id, vipflags):
pass
def getName(self):
pass
def isVideoFormat(self, url):
pass
def manualVideoCheck(self):
pass
def destroy(self):
pass
if __name__ == "__main__":
sp = Spider()
formatJo = None
# formatJo = sp.localProxy({"type": "drama", "from": "host", "url":"https://1234-1349250429.cos.ap-hongkong.myqcloud.com/app.txt"}) # host
formatJo = sp.localProxy({"type": "drama","from": "paramsData", "verName": "3.0.1.7", "AppName": "橘汁", "pkg": "com.tjjiangh.android", "publicKey": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCp9Ek4wIlQAtwFnuBRlsFiow2tr%2B4UOciGeNKbY7nL74etUqUb6fvpOSOHhFEfaWlfwUpOB17x3JEL3No19nfjCeVYrYPjlJcgoqUWH%2FtfIfFAQWvtxBIBlKazkhw8d3ChysWmeWRikKqkBsVRY4oqNPuj4sjm6Zult0U4I4prRQIDAQAB"}) # paramsData
print(formatJo)