Sync all projects
This commit is contained in:
@@ -0,0 +1,223 @@
|
||||
# -*- 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
|
||||
Reference in New Issue
Block a user