Files
tvbox_collect/sky4726/py_stripchat_(0).py
T
2026-06-29 03:41:14 +00:00

187 lines
7.4 KiB
Python

# coding=utf-8
# !/usr/bin/python
import sys
import requests
sys.path.append('..')
from base.spider import Spider
from datetime import datetime, timedelta
from typing import Tuple
# 搜索用户名,关键词格式为“类别+空格+关键词”
# 类别在标签上已注明,比如“女主播g”,则搜索类别为“g”
# 搜索“g per”,则在“女主播”中搜索“per”, 关键词不区分大小写,但至少3位,否则空结果
class Spider(Spider):
def init(self, extend="{}"):
origin = 'https://stripchat.com'
self.host = origin
self.headers = {
'Origin': origin,
'Referer': f"{origin}/",
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:142.0) Gecko/20100101 Firefox/142.0'
}
def getName(self):
pass
def isVideoFormat(self, url):
pass
def manualVideoCheck(self):
pass
def destroy(self):
pass
def homeContent(self, filter):
result = {}
classes = [{'type_name': '女主播g', 'type_id': 'girls'}, {'type_name': '情侣c', 'type_id': 'couples'}, {'type_name': '男主播m', 'type_id': 'men'}, {'type_name': '跨性别t', 'type_id': 'trans'}]
filters = {}
value = [{'n': '中国', 'v': 'tagLanguageChinese'}, {'n': '亚洲', 'v': 'ethnicityAsian'}, {'n': '白人', 'v': 'ethnicityWhite'}, {'n': '拉丁', 'v': 'ethnicityLatino'}, {'n': '混血', 'v': 'ethnicityMultiracial'}, {'n': '印度', 'v': 'ethnicityIndian'}, {'n': '阿拉伯', 'v': 'ethnicityMiddleEastern'}, {'n': '黑人', 'v': 'ethnicityEbony'}]
value_gay = [{'n': '情侣', 'v': 'sexGayCouples'}, {'n': '直男', 'v': 'orientationStraight'}]
for tid in ['girls', 'couples', 'men', 'trans']:
c_value = value[:]
if tid == 'men':
c_value += value_gay
filters[tid] = [{'key': 'tag', 'value': c_value}]
result['class'] = classes
result['filters'] = filters
return result
def homeVideoContent(self):
pass
def categoryContent(self, tid, pg, filter, extend):
limit = 60
offset = limit * (int(pg) - 1)
domain = f"{self.host}/api/front/models?improveTs=false&removeShows=false&limit={limit}&offset={offset}&primaryTag={tid}&sortBy=stripRanking&rcmGrp=A&rbCnGr=true&prxCnGr=false&nic=false"
if 'tag' in extend:
domain += "&filterGroupTags=%5B%5B%22" + extend['tag'] + "%22%5D%5D"
rsp = requests.get(domain, headers=self.headers).json()
vodList = rsp['models']
videos = []
for vod in vodList:
id = str(vod['id'])
name = str(vod['username']).strip()
stamp = vod['snapshotTimestamp']
country = str(vod['country']).strip()
flag = self.country_code_to_flag(country)
remark = "🎫" if vod['status'] == "groupShow" else ""
videos.append({
"vod_id": name,
"vod_name": f"{flag}{name}",
"vod_pic": f"https://img.doppiocdn.net/thumbs/{stamp}/{id}",
"vod_remarks": remark
})
total = int(rsp['filteredCount'])
result = {}
result['list'] = videos
result['page'] = pg
result['pagecount'] = (total + limit - 1) // limit
result['limit'] = limit
result['total'] = total
return result
def detailContent(self, array):
username = array[0]
domain = f"{self.host}/api/front/v2/models/username/{username}/cam"
rsp = requests.get(domain, headers=self.headers).json()
info = rsp['cam']
user = rsp['user']['user']
id = str(user['id'])
country = str(user['country']).strip()
isLive = "" if user['isLive'] else " 已下播"
flag = self.country_code_to_flag(country)
remark = ''
if info['show']:
show = info['show']['details']['groupShow']
BJtime = (datetime.strptime(show["startAt"], "%Y-%m-%dT%H:%M:%SZ") + timedelta(hours=8)).strftime("%m月%d日 %H:%M")
remark = f"🎫 始于 {BJtime}"
vod = [{
"vod_id": id,
"vod_name": str(info['topic']).strip(),
"vod_pic": str(user['avatarUrl']),
"vod_director": f"{flag}{username}{isLive}",
"vod_remarks": remark,
'vod_play_from': 'StripChat',
'vod_play_url': f"{id}${id}"
}]
result = {}
result['list'] = vod
return result
def process_key(self, key: str) -> Tuple[str, str]:
tags = {'G': 'girls', 'C': 'couples', 'M': 'men', 'T': 'trans'}
parts = key.split(maxsplit=1) # 仅分割第一个空格
if len(parts) > 1 and tags.get(parts[0].upper(), ''):
return tags[parts[0].upper()], parts[1].strip()
return 'girls', key.strip()
def searchContent(self, key, quick, pg="1"):
result = {}
if int(pg) > 1:
return result
tag, key = self.process_key(key)
domain = f"{self.host}/api/front/v4/models/search/group/username?query={key}&limit=900&primaryTag={tag}"
rsp = requests.get(domain, headers=self.headers).json()
users = rsp['models']
videos = []
for user in users:
if not user['isLive']:
continue
id = str(user['id'])
name = str(user['username']).strip()
stamp = user['snapshotTimestamp']
country = str(user['country']).strip()
flag = self.country_code_to_flag(country)
remark = "🎫" if user['status'] == "groupShow" else ""
videos.append({
"vod_id": name,
"vod_name": f"{flag}{name}",
"vod_pic": f"https://img.doppiocdn.net/thumbs/{stamp}/{id}",
"vod_remarks": remark
})
result['list'] = videos
return result
def playerContent(self, flag, id, vipFlags):
domain = f"https://edge-hls.doppiocdn.net/hls/{id}/master/{id}_auto.m3u8?playlistType=lowLatency"
rsp = requests.get(domain, headers=self.headers).text
lines = rsp.strip().split('\n')
psch = ''
pkey = ''
url = []
for i, line in enumerate(lines):
if line.startswith('#EXT-X-MOUFLON:'):
parts = line.split(':')
if len(parts) >= 4:
psch = parts[2]
pkey = parts[3]
if '#EXT-X-STREAM-INF' in line:
name_start = line.find('NAME="') + 6
name_end = line.find('"', name_start)
qn = line[name_start:name_end]
# URL在下一行
url_base = lines[i + 1]
# 组合最终的URL,并加上psch和pkey参数
full_url = f"{url_base}&psch={psch}&pkey={pkey}"
# 将画质和URL添加到列表中
url.append(qn)
url.append(full_url)
result = {}
result["url"] = url
result["parse"] = '0'
result["contentType"] = ''
result["header"] = self.headers
return result
def localProxy(self, param):
pass
def country_code_to_flag(self, country_code):
if len(country_code) != 2 or not country_code.isalpha():
return country_code
flag_emoji = ''.join([chr(ord(c.upper()) - ord('A') + 0x1F1E6) for c in country_code])
return flag_emoji