TV-BOX/tvbox/江湖/py/py_stgay.py
yuanwangokk-1 7fb1457e88 main
2025-10-14 22:54:33 +08:00

160 lines
5.4 KiB
Python

# coding=utf-8
# !/usr/bin/python
import sys
import requests
from requests import Session
from base.spider import Spider
from pyquery import PyQuery as pq
from urllib.parse import quote, unquote
from Crypto.Cipher import AES
from Crypto.Util.Padding import unpad
sys.path.append('..')
class Spider(Spider):
def init(self, extend="{}"):
self.host = "https://stgay.com"
self.headers = {
'Referer': self.host,
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:144.0) Gecko/20100101 Firefox/144.0'
}
self.session = Session()
self.session.headers.update(self.headers)
def getName(self):
pass
def isVideoFormat(self, url):
pass
def manualVideoCheck(self):
pass
def destroy(self):
pass
def homeContent(self, filter):
rsp = self.getpq('all/play')
CLASSES = []
for a in rsp('#app-nav a.app-nav-item').items():
href = a.attr('href')
if href and '/videos/' in href:
CLASSES.append({
'type_name': a.text().strip(),
'type_id': href.split('/')[-1]
})
filter = []
for a in rsp('.dx-line-tab-item a').items():
href = a.attr('href').split('/')[-1]
if href != 'play':
filter.append({
'n': a.text().strip(),
'v': href
})
return {
'class': CLASSES,
'filters': {'play': [{'key': 'tag', 'value': filter}]}
}
def homeVideoContent(self):
pass
def categoryContent(self, tid, pg, filter, extend):
type = 'all' if tid == 'play' else 'category'
tag = extend["tag"] if 'tag' in extend else tid
rsp = self.getpq(f'{type}/{tag}/{pg}')
videos = []
for item in rsp('.video-item').items():
title_link = item.find('a.line-clamp-1')
href = title_link.attr('href')
text = title_link.text().strip()
img_src = item.find('img').attr('data-src')
duration = item.find('.flex.justify-end .text-white').text().strip()
videos.append({
"vod_id": href.split('/')[-1],
"vod_name": text,
"vod_pic": f"{self.getProxyUrl()}&type=img&url={quote(img_src)}",
"vod_remarks": duration
})
pager = rsp('ul.pager.dx-pager')
limit = int(pager.attr('data-rec-per-page'))
total = int(pager.attr('data-rec-total'))
return {
"list": videos,
"page": pg,
"pagecount": (total + limit - 1) // limit,
"limit": limit,
"total": total
}
def detailContent(self, array):
rsp = self.getpq(array[0])
mse_div = rsp('#mse')
id = mse_div.attr('data-video')
pic = mse_div.attr('data-poster')
url = mse_div.attr('data-url')
vod = {
"vod_id": id,
"vod_name": rsp('h1.dx-title').text().encode('latin-1').decode('utf-8').strip(),
"vod_pic": f"{self.getProxyUrl()}&type=img&url={quote(pic)}",
'vod_play_from': '搜同社区',
'vod_play_url': f"{id}${quote(url)}"
}
return {'list': [vod]}
def searchContent(self, key, quick, pg="1"):
rsp = self.getpq(f'search/{quote(key)}/{pg}')
videos = []
for item in rsp('.video-item').items():
title_link = item.find('a.line-clamp-1')
href = title_link.attr('href')
text = title_link.text().encode('latin-1').decode('utf-8').strip()
img_src = item.find('img').attr('data-src')
duration = item.find('.flex.justify-end .text-white').text().strip()
videos.append({
"vod_id": href.split('/')[-1],
"vod_name": text,
"vod_pic": f"{self.getProxyUrl()}&type=img&url={quote(img_src)}",
"vod_remarks": duration
})
pager = rsp('ul.pager.dx-pager')
limit = int(pager.attr('data-rec-per-page'))
total = int(pager.attr('data-rec-total'))
return {
"list": videos,
"page": pg,
"pagecount": (total + limit - 1) // limit,
"limit": limit,
"total": total
}
def playerContent(self, flag, id, vipFlags):
return {
"url": unquote(id),
"parse": '0',
"contentType": '',
"header": self.headers
}
def localProxy(self, param):
if param['type'] == 'img':
content = self.decrypt_img(unquote(param['url']))
return [200, "application/octet-stream", content]
def getpq(self, path):
try:
rsp = self.session.get(f'{self.host}/videos/{path}', timeout=5).text
return pq(rsp.encode('utf-8'))
except Exception as e:
print(f"请求失败: , {str(e)}")
return None
def decrypt_img(self, url):
key_str = 'f5d965df75336270'
iv_str = '97b60394abc2fbe1'
key = key_str.encode('utf-8')
iv = iv_str.encode('utf-8')
encrypted_bytes = self.session.get(url, timeout=5).content
cipher = AES.new(key, AES.MODE_CBC, iv)
decrypted_bytes = cipher.decrypt(encrypted_bytes)
final_data = unpad(decrypted_bytes, AES.block_size)
return final_data