diff --git a/XBPQ/骚火影视.json b/XBPQ/骚火影视.json index 1616fa5..4ab6048 100644 --- a/XBPQ/骚火影视.json +++ b/XBPQ/骚火影视.json @@ -1,6 +1,16 @@ { - "简介": "p_txt show_part\">&&

", - "副标题": "v_note\">&&", - "分类url": "https://saohuody.com/list/{cateId}-{catePg}.html", - "分类": "国产剧$12#港剧$13#台剧$14#日剧$15#韩剧$16#美剧$17#海外$18#泰剧$19#动作$5#喜剧$6#爱情$7#科幻$8#恐怖$9#剧情$10#战争$11#动画$33#福利$20" + "首页": "0", + "请求头": "User-Agent$MOBILE_UA#Accept$text/html,application/xhtml+xml,application/xml;;q=0.9,image/avif,image/webp,image/apng,*/*;;q=0.8,application/signed-exchange;;v=b3;;q=0.7&&Accept-Language@zh-CN,zh;;q=0.9", + "分类url": "https://shdy2.com/list/{cateId}-{catePg}.html", + "分类": "剧集$2#电影$1#港剧$21#台剧$26#日剧$24#韩剧$22#美剧$23", + "数组": "class=\"v_img&&/li>", + "标题": "alt=\"&&\"", + "图片": "original=\"&&\"", + "链接": "href=\"&&\"", + "简介": "show_part\">&&", + "播放数组": "", + "倒序": "1" } \ No newline at end of file diff --git a/api.json b/api.json index c3b07ef..01f4d57 100644 --- a/api.json +++ b/api.json @@ -251,6 +251,22 @@ "ua": "" } }, + { + "key": "奈飞", + "name": "奈飞丨APP", + "type": 3, + "quickSearch": 1, + "api": "csp_AppGet", + "ext": { + "url": "https://movier.ink", + "site": "", + "dataKey": "moviermovierink9", + "dataIv": "moviermovierink9", + "deviceId": "", + "version": "", + "ua": "" + } + }, { "key": "迪吧", "name": "迪吧丨APP", @@ -1011,49 +1027,62 @@ "api": "csp_MiSou" }, { - "key": "短剧大全", - "name": "短剧|大全", + "key": "酷乐搜索", + "name": "酷乐|搜索", "type": 3, - "api": "csp_DuanjuDQ" + "api": "csp_KuLe" }, { - "key": "短剧合集", - "name": "短剧|合集", + "key": "爱看搜索", + "name": "爱看|搜索", "type": 3, - "api": "csp_DuanjuHJ" + "api": "csp_AiKan" }, { - "key": "短剧鬼鬼", - "name": "短剧|鬼鬼", + "key": "鬼鬼搜索", + "name": "鬼鬼|搜索", "type": 3, - "api": "csp_DuanjuGG" + "api": "csp_GuiGui" }, { "key": "夸克推送", "name": "夸克|推送", "type": 4, - "api": "http://zling.online:12331/api.php?type=quark" + "api": "https://so.yinpai.xyz/api.php?type=quark" }, { "key": "UC推送", "name": "UC|推送", "type": 4, - "api": "http://zling.online:12331/api.php?type=uc" + "api": "https://so.yinpai.xyz/api.php?type=uc" + }, + { + "key": "天翼推送", + "name": "天翼|推送", + "type": 4, + "api": "https://so.yinpai.xyz/api.php?type=tianyi" + }, + { + "key": "123推送", + "name": "123|推送", + "type": 4, + "api": "https://so.yinpai.xyz/api.php?type=123" }, { "key": "百度推送", "name": "百度|推送", "type": 4, - "api": "http://zling.online:12331/api.php?type=baidu" + "api": "https://so.yinpai.xyz/api.php?type=baidu" }, { "key": "星芽短剧", "name": "星芽|短剧", "type": 3, - "api": "csp_AppXY", + "api": "./py/星芽短剧.py", "searchable": 1, - "quickSearch": 0, - "filterable": 0 + "changeable": 1, + "quickSearch": 1, + "filterable": 1 }, { "key": "甜圈短剧", diff --git a/py/星芽短剧.py b/py/星芽短剧.py new file mode 100644 index 0000000..1accc9a --- /dev/null +++ b/py/星芽短剧.py @@ -0,0 +1,343 @@ +# coding = utf-8 +# !/usr/bin/python + +""" +""" + +from Crypto.Util.Padding import unpad +from Crypto.Util.Padding import pad +from urllib.parse import unquote +from Crypto.Cipher import ARC4 +from urllib.parse import quote +from base.spider import Spider +from Crypto.Cipher import AES +from bs4 import BeautifulSoup +from base64 import b64decode +import urllib.request +import urllib.parse +import binascii +import requests +import base64 +import json +import time +import sys +import re +import os + +sys.path.append('..') + +xurl = "https://app.whjzjx.cn" + +headers = { + 'User-Agent': 'Linux; Android 12; Pixel 3 XL) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.101 Mobile Safari/537.36' + } + +headerf = { + "platform": "1", + "user_agent": "Mozilla/5.0 (Linux; Android 9; V1938T Build/PQ3A.190705.08211809; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/91.0.4472.114 Safari/537.36", + "content-type": "application/json; charset=utf-8" + } + +times = int(time.time() * 1000) + +data = { + "device": "2a50580e69d38388c94c93605241fb306", + "package_name": "com.jz.xydj", + "android_id": "ec1280db12795506", + "install_first_open": True, + "first_install_time": 1752505243345, + "last_update_time": 1752505243345, + "report_link_url": "", + "authorization": "", + "timestamp": times + } + +plain_text = json.dumps(data, separators=(',', ':'), ensure_ascii=False) + +key = "B@ecf920Od8A4df7" +key_bytes = key.encode('utf-8') +plain_bytes = plain_text.encode('utf-8') +cipher = AES.new(key_bytes, AES.MODE_ECB) +padded_data = pad(plain_bytes, AES.block_size) +ciphertext = cipher.encrypt(padded_data) +encrypted = base64.b64encode(ciphertext).decode('utf-8') + +response = requests.post("https://u.shytkjgs.com/user/v3/account/login", headers=headerf, data=encrypted) +response_data = response.json() +Authorization = response_data['data']['token'] + +headerx = { + 'authorization': Authorization, + 'platform': '1', + 'version_name': '3.8.3.1' + } + +class Spider(Spider): + global xurl + global headerx + global headers + + def getName(self): + return "首页" + + def init(self, extend): + pass + + def isVideoFormat(self, url): + pass + + def manualVideoCheck(self): + pass + + def extract_middle_text(self, text, start_str, end_str, pl, start_index1: str = '', end_index2: str = ''): + if pl == 3: + plx = [] + while True: + start_index = text.find(start_str) + if start_index == -1: + break + end_index = text.find(end_str, start_index + len(start_str)) + if end_index == -1: + break + middle_text = text[start_index + len(start_str):end_index] + plx.append(middle_text) + text = text.replace(start_str + middle_text + end_str, '') + if len(plx) > 0: + purl = '' + for i in range(len(plx)): + matches = re.findall(start_index1, plx[i]) + output = "" + for match in matches: + match3 = re.search(r'(?:^|[^0-9])(\d+)(?:[^0-9]|$)', match[1]) + if match3: + number = match3.group(1) + else: + number = 0 + if 'http' not in match[0]: + output += f"#{match[1]}${number}{xurl}{match[0]}" + else: + output += f"#{match[1]}${number}{match[0]}" + output = output[1:] + purl = purl + output + "$$$" + purl = purl[:-3] + return purl + else: + return "" + else: + start_index = text.find(start_str) + if start_index == -1: + return "" + end_index = text.find(end_str, start_index + len(start_str)) + if end_index == -1: + return "" + + if pl == 0: + middle_text = text[start_index + len(start_str):end_index] + return middle_text.replace("\\", "") + + if pl == 1: + middle_text = text[start_index + len(start_str):end_index] + matches = re.findall(start_index1, middle_text) + if matches: + jg = ' '.join(matches) + return jg + + if pl == 2: + middle_text = text[start_index + len(start_str):end_index] + matches = re.findall(start_index1, middle_text) + if matches: + new_list = [f'{item}' for item in matches] + jg = '$$$'.join(new_list) + return jg + + def homeContent(self, filter): + result = {} + result = {"class": [{"type_id": "1", "type_name": "剧场"}, + {"type_id": "3", "type_name": "新剧"}, + {"type_id": "2", "type_name": "热播"}, + {"type_id": "7", "type_name": "星选"}, + {"type_id": "5", "type_name": "阳光"}], + } + + return result + + def homeVideoContent(self): + videos = [] + + url= f'{xurl}/v1/theater/home_page?theater_class_id=1&class2_id=4&page_num=1&page_size=24' + detail = requests.get(url=url, headers=headerx) + detail.encoding = "utf-8" + if detail.status_code == 200: + data = detail.json() + + for vod in data['data']['list']: + + name = vod['theater']['title'] + + id = vod['theater']['id'] + + pic = vod['theater']['cover_url'] + + remark = vod['theater']['play_amount_str'] + + video = { + "vod_id": id, + "vod_name": name, + "vod_pic": pic, + "vod_remarks": remark + } + videos.append(video) + + result = {'list': videos} + return result + + def categoryContent(self, cid, pg, filter, ext): + result = {} + videos = [] + + url = f'{xurl}/v1/theater/home_page?theater_class_id={cid}&page_num={pg}&page_size=24' + detail = requests.get(url=url,headers=headerx) + detail.encoding = "utf-8" + if detail.status_code == 200: + data = detail.json() + + for vod in data['data']['list']: + + name = vod['theater']['title'] + + id = vod['theater']['id'] + + pic = vod['theater']['cover_url'] + + remark = vod['theater']['theme'] + + video = { + "vod_id": id, + "vod_name": name, + "vod_pic": pic, + "vod_remarks": remark + } + videos.append(video) + + result = {'list': videos} + result['page'] = pg + result['pagecount'] = 9999 + result['limit'] = 90 + result['total'] = 999999 + return result + + def detailContent(self, ids): + did = ids[0] + result = {} + videos = [] + xianlu = '' + bofang = '' + + url = f'{xurl}/v2/theater_parent/detail?theater_parent_id={did}' + detail = requests.get(url=url, headers=headerx) + detail.encoding = "utf-8" + if detail.status_code == 200: + data = detail.json() + + url = 'https://fs-im-kefu.7moor-fs1.com/ly/4d2c3f00-7d4c-11e5-af15-41bf63ae4ea0/1732707176882/jiduo.txt' + response = requests.get(url) + response.encoding = 'utf-8' + code = response.text + name = self.extract_middle_text(code, "s1='", "'", 0) + Jumps = self.extract_middle_text(code, "s2='", "'", 0) + + content = '剧情:' + data['data']['introduction'] + + area = data['data']['desc_tags'][0] + + remarks = data['data']['filing'] + + # 修复剧集只有一集的问题 - 检查theaters数据是否存在且不为空 + if 'theaters' in data['data'] and data['data']['theaters']: + for sou in data['data']['theaters']: + id = sou['son_video_url'] + name = sou['num'] + bofang = bofang + str(name) + '$' + id + '#' + + bofang = bofang[:-1] if bofang.endswith('#') else bofang + xianlu = '星芽' + else: + # 如果没有theaters数据,检查是否有单个视频URL + if 'video_url' in data['data'] and data['data']['video_url']: + bofang = '1$' + data['data']['video_url'] + xianlu = '星芽' + else: + bofang = Jumps + xianlu = '1' + + videos.append({ + "vod_id": did, + "vod_content": content, + "vod_remarks": remarks, + "vod_area": area, + "vod_play_from": xianlu, + "vod_play_url": bofang + }) + + result['list'] = videos + return result + + def playerContent(self, flag, id, vipFlags): + + result = {} + result["parse"] = 0 + result["playUrl"] = '' + result["url"] = id + result["header"] = headers + return result + + def searchContentPage(self, key, quick, page): + result = {} + videos = [] + + payload = { + "text": key + } + + url = f"{xurl}/v3/search" + detail = requests.post(url=url, headers=headerx, json=payload) + if detail.status_code == 200: + detail.encoding = "utf-8" + data = detail.json() + + for vod in data['data']['theater']['search_data']: + + name = vod['title'] + + id = vod['id'] + + pic = vod['cover_url'] + + remark = vod['score_str'] + + video = { + "vod_id": id, + "vod_name": name, + "vod_pic": pic, + "vod_remarks": remark + } + videos.append(video) + + result['list'] = videos + result['page'] = page + result['pagecount'] = 9999 + result['limit'] = 90 + result['total'] = 999999 + return result + + def searchContent(self, key, quick, pg="1"): + return self.searchContentPage(key, quick, '1') + + def localProxy(self, params): + if params['type'] == "m3u8": + return self.proxyM3u8(params) + elif params['type'] == "media": + return self.proxyMedia(params) + elif params['type'] == "ts": + return self.proxyTs(params) + return None \ No newline at end of file diff --git a/spider.jar b/spider.jar index 08e9dd3..5821063 100644 Binary files a/spider.jar and b/spider.jar differ