Files
2026-07-05 04:58:38 +00:00

224 lines
9.0 KiB
Python

# -*- coding: utf-8 -*-
# 本资源来源于互联网公开渠道,仅可用于个人学习爬虫技术。
# 严禁将其用于任何商业用途,下载后请于 24 小时内删除,搜索结果均来自源站,本人不承担任何责任。
from base.spider import Spider
import sys,time,base64,secrets,hashlib,urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
sys.path.append('..')
class Spider(Spider):
headers, host = {
'User-Agent': 'okhttp/3.12.11',
'Connection': 'Keep-Alive',
'Accept-Encoding': 'gzip'
}, ''
def init(self, extend=''):
default_host = 'http://194.147.100.13'
try:
if not extend.startswith('http'):
extend = default_host
self.host = extend.strip().rstrip('/')
except Exception:
self.host = default_host
def homeContent(self, filter):
if not self.host: return None
response = self.fetch(f'{self.host}/api.php/v2.vod/androidtypes', headers=self.headers, verify=False).json()
data = response['data']
filters, class_list = {}, []
for item in data:
type_id = item.get('type_id', '')
type_name = item.get('type_name', '')
if not (type_id == '' and type_name == ''):
class_list.append({'type_id': type_id,'type_name': type_name})
classes = item.get('classes', [])
areas = item.get('areas', [])
years = item.get('years', [])
filter_items = []
class_values = [{'n': '全部', 'v': ''}]
for cls in classes:
n_val,v_val = cls,cls
if not (n_val == '' and v_val == ''):
class_values.append({'n': n_val, 'v': v_val})
filter_items.append({'key': 'class','name': '类型','value': class_values})
area_values = [{'n': '全部', 'v': ''}]
for area in areas:
n_val,v_val = area,area
if not (n_val == '' and v_val == ''): area_values.append({'n': n_val, 'v': v_val})
filter_items.append({'key': 'area','name': '地区','value': area_values})
year_values = [{'n': '全部', 'v': ''}]
for year in years:
n_val,v_val = year,year
if not (n_val == '' and v_val == ''):
year_values.append({'n': n_val, 'v': v_val})
filter_items.append({'key': 'year','name': '年份','value': year_values})
filter_items.append({
'key': 'sortby','name': '排序',
'value': [{'n': '时间', 'v': 'updatetime'},{'n': '人气', 'v': 'hits'},{'n': '评分', 'v': 'score'}]
})
if type_id != '': filters[type_id] = filter_items
return {'class': class_list, 'filters': filters}
def homeVideoContent(self):
response = self.fetch(f'{self.host}/api.php/v2.main/androidhome', headers=self.headers, verify=False).json()
data = response['data']
videos = self.arr2vods(data.get('top', []))
for i in data.get('list', []):
if isinstance(i, dict):
videos.extend(self.arr2vods(i.get('list', [])))
return {'list': videos}
def categoryContent(self, tid, pg, filter, extend):
params = {
k: v for k, v in {
'page': pg,
'type': tid,
'area': extend.get('area'),
'year': extend.get('year'),
'sortby': extend.get('sortby'),
'class': extend.get('class')
}.items() if v is not None and v != ''
}
response = self.fetch(f'{self.host}/api.php/v2.vod/androidfilter10086',params=params, headers=self.headers, verify=False).json()
videos = self.arr2vods(response.get('data', []))
return {'list': videos, 'page': pg}
def searchContent(self, key, quick, pg='1'):
response = self.fetch(f"{self.host}/api.php/v2.vod/androidsearch10086?page=1&wd={key}", headers=self.headers, verify=False).json()
videos = self.arr2vods(response.get('data', []))
return {'list': videos, 'page': pg}
def detailContent(self, ids):
response = self.fetch(f"{self.host}/api.php/v3.vod/androiddetail2?vod_id={ids[0]}", headers=self.headers2(), verify=False).json()
data = response['data']
play_urls = []
for i in data['urls']:
if not(i['key'] == '及时雨' or i['url'] == 'dlNQWVppbnZXVVZsZnRhMnRpTkVNT2JaTnpyS010VEs='):
play_urls.append(f"{i['key']}${i['url']}")
video = {
'vod_id': data['id'],
'vod_name': data['name'],
'vod_pic': data['pic'],
'vod_year': data['year'],
'vod_area': data['area'],
'vod_actor': data['actor'],
'vod_director': data['director'],
'vod_content': data['content'],
'vod_play_from': 'LiteApple',
'vod_play_url': '#'.join(play_urls),
'type_name': data['className'],
}
return {'list': [video]}
def playerContent(self, flag, vid, vip_flags):
parse, url, headers = 0, '', {'User-Agent':'Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1'}
if vid.startswith("JBN_"):
url = "https://www.yangshipin.cn/tv/home?pid=" + vid[4:]
parse, headers = 1, {'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36'}
elif "HTTP" in vid.upper():
url = vid
else:
url = 'http://c.xpgtv.net/m3u8/' + vid + '.m3u8'
headers = {**self.headers2(), 'User-Agent': 'com.stub.StubApp/1.6.0 (Linux;Android 12) ExoPlayerLib/2.14.2'}
return {'jx': 0, 'parse': parse, 'url': url, 'header': headers}
def headers2(self):
token_param_cache_key = 'com.phoenix.tv_33ee1768b8ee539a_token_param'
token_param = self.getCache(token_param_cache_key)
if not token_param:
token_param = F'{self.random32()}||||{self.random11()}||||unknown||xiaomi/b0q/b0q:12/V417IR/913:user/release-keys'
self.setCache(token_param_cache_key, token_param)
token2_cache_key = 'com.phoenix.tv_33ee1768b8ee539a_token2'
token2 = self.getCache(token2_cache_key)
if not token2:
token2 = self.encrypt(self.random32())
self.setCache(token2_cache_key, token2)
timestamp = str(int(time.time()))
version = 'XPGBOX com.phoenix.tv1.6.0'
return {
**self.headers.copy(),
'token': self.encrypt(token_param),
'token2': token2,
'user_id': "XPGBOX",
'version': version,
'timestamp': timestamp,
'hash': self.hash(f'{token_param}{version}{timestamp}'),
'screenx': "1600",
'screeny': "900"
}
def cipher(self, data):
bytes_key = "XPINGGUO".encode('utf-8')
b_arr2 = bytearray(i % 256 for i in range(333))
if len(bytes_key) > 0:
i2 = 0
i3 = 0
for i4 in range(333):
i5 = bytes_key[i2] & 0xFF
b_val = b_arr2[i4]
i3 = (i5 + (b_val & 0xFF) + i3) % 333
b_arr2[i4], b_arr2[i3] = b_arr2[i3], b_val
i2 = (i2 + 1) % len(bytes_key)
b_arr3 = bytearray(len(data))
i6 = 0
i7 = 0
for i8 in range(len(data)):
i6 = (i6 + 1) % 333
b2 = b_arr2[i6]
i9 = b2 & 0xFF
i7 = (i7 + i9) % 333
b_arr2[i6], b_arr2[i7] = b_arr2[i7], b2
i10 = ((b_arr2[i6] & 0xFF) + i9) % 333
b_arr3[i8] = b_arr2[i10] ^ data[i8]
return bytes(b_arr3)
def arr2vods(self, arr):
videos = []
if isinstance(arr, list):
for i in arr:
videos.append({
'vod_id': i['id'],
'vod_name': i['name'],
'vod_pic': i['pic'],
'vod_remarks': i['updateInfo'],
'vod_year': i.get('year'),
'vod_content': i.get('content')
})
return videos
def encrypt(self, s):
try:
byte_data = s.encode('utf-8')
encrypted_data = self.cipher(byte_data)
return base64.b64encode(encrypted_data).decode('utf-8')
except UnicodeEncodeError:
return ""
def random11(self):
return ''.join(secrets.choice('0123456789ABCDEF') for _ in range(11))
def random32(self):
random_bytes = secrets.token_bytes(32)
return base64.b64encode(random_bytes).decode('utf-8')
def hash(self, s):
hash_hex = hashlib.md5(s.encode()).hexdigest()
return hash_hex[8:12]
def getName(self):
pass
def isVideoFormat(self, url):
pass
def manualVideoCheck(self):
pass
def destroy(self):
pass
def localProxy(self, param):
pass