Sync all projects
This commit is contained in:
+182
-129
@@ -4,7 +4,7 @@
|
||||
"logo": "https://wkphoto.bj.bcebos.com/bba1cd11728b47106798119ad3cec3fdfc032335.jpg",
|
||||
"lives": [
|
||||
{
|
||||
"name": "📺 平台直播",
|
||||
"name": "📺电视┃直播",
|
||||
"type": 0,
|
||||
"ua": "okhttp/3.15"
|
||||
}
|
||||
@@ -12,7 +12,7 @@
|
||||
"sites": [
|
||||
{
|
||||
"key": "豆豆",
|
||||
"name": "🎬豆瓣┃精选 仅供测试 备用:https://zzzy.shop/tv/",
|
||||
"name": "🎬豆瓣┃精选推荐 仅供测试 备用:https://www.tangsan.fun/tv/",
|
||||
"type": 3,
|
||||
"quickSearch": 0,
|
||||
"filterable": 1,
|
||||
@@ -22,14 +22,14 @@
|
||||
},
|
||||
{
|
||||
"key": "config",
|
||||
"name": "⚙️Cookie┃配置 修了很多 偷窃贩卖后果自负",
|
||||
"name": "⚙️配置┃核心设置 接口免费公益 闲鱼购买都是傻子",
|
||||
"type": 3,
|
||||
"api": "csp_Config",
|
||||
"searchable": 0
|
||||
},
|
||||
{
|
||||
"key": "csp_Netfixtv",
|
||||
"name": "🚀🚀臻臻┃网盘4K",
|
||||
"name": "🚀臻臻┃网盘4K",
|
||||
"type": 3,
|
||||
"changeable": "0",
|
||||
"quickSearch": 1,
|
||||
@@ -40,7 +40,7 @@
|
||||
},
|
||||
{
|
||||
"key": "csp_Netfixtv2",
|
||||
"name": "🚀🛸指南┃网盘4K",
|
||||
"name": "🛸指南┃网盘4K",
|
||||
"type": 3,
|
||||
"changeable": "0",
|
||||
"quickSearch": 1,
|
||||
@@ -69,29 +69,118 @@
|
||||
"timeout": 15,
|
||||
"api": "csp_Duopan",
|
||||
"filterable": 1,
|
||||
"ext": "ewogICAgICAgICJzaXRlX3VybHMiOiBbCiAgICAgICAgICAiaHR0cDovL3R2cGFucGFuLnNpdGUiLAogICAgICAgICAgImh0dHA6Ly9mZWltby5mdW4iLAogICAgICAgICAgImh0dHA6Ly94aWFvY2dlZ2Uuc2hvcCIsCiAgICAgICAgICAiaHR0cHM6Ly93d3cubW1wYW5wYW4uc2l0ZSIsCiAgICAgICAgICAiaHR0cDovL3d3dy54aWFvY2dlZ2Uuc2hvcCIKICAgICAgICBdLAogICAgICAgICJ1cmxfa2V5IjogIkR1b3BhbjQiCiAgICAgIH0="
|
||||
"ext": "ewogICJzaXRlX3VybHMiOiBbCiAgICAiaHR0cDovL3R2cGFucGFuLnNpdGUiLAogICAgImh0dHA6Ly9mZWltby5mdW4iLAogICAgImh0dHA6Ly94aWFvY2dlZ2Uuc2hvcCIsCiAgICAiaHR0cHM6Ly93d3cubW1wYW5wYW4uc2l0ZSIsCiAgICAiaHR0cDovL3d3dy54aWFvY2dlZ2Uuc2hvcCIKICBdLAogICJ1cmxfa2V5IjogIkR1b3BhbjQiCn0="
|
||||
},
|
||||
{
|
||||
"key": "天天",
|
||||
"name": "🚀秒播┃1080P",
|
||||
"name": "🚀秒播┃高清影视",
|
||||
"type": 3,
|
||||
"quickSearch": 1,
|
||||
"searchable": 1,
|
||||
"api": "csp_AppRJ",
|
||||
"timeout": 12,
|
||||
"ext": "vxw35/hHSj07Q+maxQzOVMq1rjRCOTXpUCx8iKu5jIg="
|
||||
"ext": "http://v.rbotv.cn"
|
||||
},
|
||||
{
|
||||
"key": "csp_Wwys",
|
||||
"name": "🌾农民┃1080P",
|
||||
"name": "🌾农民┃高清影视",
|
||||
"type": 3,
|
||||
"api": "csp_Wwys",
|
||||
"timeout": 12,
|
||||
"ext": "https://vip.wwgz.cn:5200"
|
||||
},
|
||||
{
|
||||
"key": "csp_Gz360",
|
||||
"name": "🍉瓜子┃高清影视",
|
||||
"type": 3,
|
||||
"timeout": 12,
|
||||
"searchable": 1,
|
||||
"quickSearch": 0,
|
||||
"api": "csp_Gz360"
|
||||
},
|
||||
{
|
||||
"key": "3QQQ",
|
||||
"name": "🍅大鹅┃高清影视",
|
||||
"type": 3,
|
||||
"timeout": 15,
|
||||
"api": "csp_App3Q",
|
||||
"ext": "https://asd123sx23xdacsx.top"
|
||||
},
|
||||
{
|
||||
"key": "csp_PianKu8",
|
||||
"name": "🍬山楂┃热门4K",
|
||||
"type": 3,
|
||||
"api": "csp_PianKu8"
|
||||
},
|
||||
{
|
||||
"key": "爱营",
|
||||
"name": "💥爱影┃热门4K",
|
||||
"type": 3,
|
||||
"searchable": 1,
|
||||
"changeable": 1,
|
||||
"api": "csp_AppGet",
|
||||
"ext": "https://aysappto.oss-cn-chengdu.aliyuncs.com/q23.txt|nzEqOgYk3QzHuEP8|V122|okhttp/3.10.0"
|
||||
},
|
||||
{
|
||||
"key": "新首发",
|
||||
"name": "🏵️首发┃热门4K",
|
||||
"type": 3,
|
||||
"api": "csp_AppGet",
|
||||
"ext": "https://yun-1316442804.cos.ap-guangzhou.myqcloud.com/602.txt|FTgP4Gq8zPiqbt7M|V122|okhttp/3.10.0"
|
||||
},
|
||||
{
|
||||
"key": "枫叶影视",
|
||||
"name": "🍁枫叶┃热门4K",
|
||||
"type": 3,
|
||||
"api": "csp_FengYe",
|
||||
"searchable": 1,
|
||||
"quickSearch": 1,
|
||||
"filterable": 0,
|
||||
"ext": "https://www.vip1949.com/"
|
||||
},
|
||||
{
|
||||
"key": "双星99",
|
||||
"name": "🥪双星┃热门动漫",
|
||||
"type": 3,
|
||||
"api": "csp_App99",
|
||||
"ext": {
|
||||
"host": "http://175.178.65.250:19987/app/bn",
|
||||
"LoginPath": "/app/log",
|
||||
"appkey": "f66f65db127e48449f073c2c6eb0f993",
|
||||
"versionName": "6.4.5",
|
||||
"name": "双子星动漫",
|
||||
"package": "com.yingfu.mobile.android.pgsp",
|
||||
"buildNumber": "2003",
|
||||
"buildSignature": "054FA8DDA4319C6B6A9B954CA5777541C993F00B1B0BD4394F7EDE48184C4594"
|
||||
}
|
||||
},
|
||||
{
|
||||
"key": "咕咕动漫",
|
||||
"name": "🥖咕咕┃热门动漫",
|
||||
"type": 3,
|
||||
"searchable": 1,
|
||||
"api": "csp_AppGet",
|
||||
"ext": "https://www.gugu3.com|nKfZ8KX6JTNWRzTD|V119|okhttp/3.10"
|
||||
},
|
||||
{
|
||||
"key": "csp_duanju",
|
||||
"name": "🔥盒马┃精选短剧",
|
||||
"type": 3,
|
||||
"timeout": 12,
|
||||
"api": "csp_HeMa"
|
||||
},
|
||||
{
|
||||
"key": "csp_XY",
|
||||
"name": "🌟星丫┃精选短剧",
|
||||
"type": 3,
|
||||
"searchable": 1,
|
||||
"timeout": 12,
|
||||
"api": "csp_AppXY",
|
||||
"ext": ""
|
||||
},
|
||||
{
|
||||
"key": "88看球",
|
||||
"name": "🏀叭叭┃体育",
|
||||
"name": "⚽叭叭┃体育直播",
|
||||
"type": 3,
|
||||
"api": "csp_Kanqiu",
|
||||
"style": {
|
||||
@@ -107,7 +196,7 @@
|
||||
},
|
||||
{
|
||||
"key": "瓜子",
|
||||
"name": "🏀瓜子┃体育",
|
||||
"name": "🏀瓜子┃体育直播",
|
||||
"type": 3,
|
||||
"api": "csp_GuaziTY",
|
||||
"style": {
|
||||
@@ -123,7 +212,7 @@
|
||||
},
|
||||
{
|
||||
"key": "csp_Bili",
|
||||
"name": "📺哔哩┃哔哩",
|
||||
"name": "📺哔哩┃综合视频",
|
||||
"type": 3,
|
||||
"api": "csp_Bili",
|
||||
"quickSearch": 0,
|
||||
@@ -138,95 +227,65 @@
|
||||
"ratio": 1.333
|
||||
}
|
||||
},
|
||||
{
|
||||
"key": "新首发",
|
||||
"name": "👻标清┃1080P",
|
||||
"type": 3,
|
||||
"api": "csp_AppGet",
|
||||
"ext": "https://yun-1316442804.cos.ap-guangzhou.myqcloud.com/602.txt|FTgP4Gq8zPiqbt7M|V122|okhttp/3.10.0"
|
||||
},
|
||||
{
|
||||
"key": "四叶草",
|
||||
"name": "🍀幸运┃1080P",
|
||||
"type": 3,
|
||||
"api": "csp_AppGet",
|
||||
"ext": "https://yzysap.oss-cn-hangzhou.aliyuncs.com/kkk.txt|8eeObuwrmS3lRDEs|V122|okhttp/3.10.0"
|
||||
},
|
||||
{
|
||||
"key": "爱营",
|
||||
"name": "💥爱影┃1080P",
|
||||
"type": 3,
|
||||
"searchable": 1,
|
||||
"changeable": 1,
|
||||
"api": "csp_AppGet",
|
||||
"ext": "https://aysappto.oss-cn-chengdu.aliyuncs.com/q23.txt|nzEqOgYk3QzHuEP8|V122|okhttp/3.10.0"
|
||||
},
|
||||
{
|
||||
"key": "3QQQ",
|
||||
"name": "🍅大鹅┃1080P",
|
||||
"type": 3,
|
||||
"timeout": 15,
|
||||
"api": "csp_App3Q",
|
||||
"ext": "https://asd123sx23xdacsx.top"
|
||||
},
|
||||
{
|
||||
"key": "山楂",
|
||||
"name": "🔴山楂┃1080P",
|
||||
"type": 3,
|
||||
"timeout": 15,
|
||||
"api": "./api/shanzha.py",
|
||||
"ext": ""
|
||||
},
|
||||
{
|
||||
"key": "csp_SaoHuo",
|
||||
"name": "🔥火火┃1080P",
|
||||
"name": "🔥火火┃高清影视",
|
||||
"type": 3,
|
||||
"api": "csp_SaoHuo"
|
||||
},
|
||||
{
|
||||
"key": "枫叶影视",
|
||||
"name": "🍁枫叶┃影视",
|
||||
"type": 3,
|
||||
"api": "csp_FengYe",
|
||||
"searchable": 1,
|
||||
"quickSearch": 1,
|
||||
"filterable": 0,
|
||||
"ext": "https://www.vip1949.com/"
|
||||
},
|
||||
{
|
||||
"key": "csp_Czsapp",
|
||||
"name": "🏭厂长┃影视",
|
||||
"name": "🏭厂长┃高清影视",
|
||||
"type": 3,
|
||||
"api": "csp_Czsapp",
|
||||
"ext": "https://www.4kcz.com"
|
||||
},
|
||||
{
|
||||
"key": "麦田",
|
||||
"name": "🌾麦田┃1080P",
|
||||
"name": "🌾麦田┃高清影视",
|
||||
"type": 3,
|
||||
"api": "csp_AppV6",
|
||||
"ext": "http://172.247.227.203:25321/mtys.php"
|
||||
},
|
||||
{
|
||||
"key": "听心99",
|
||||
"name": "🦉欣欣┃1080P",
|
||||
"key": "feiyu_video",
|
||||
"name": "🥭飞娱┃高清影视",
|
||||
"type": 3,
|
||||
"api": "csp_Feiyu",
|
||||
"searchable": 1,
|
||||
"quickSearch": 1,
|
||||
"filterable": 1
|
||||
},
|
||||
{
|
||||
"key": "马猴影视",
|
||||
"name": "🐵马猴┃高清影视",
|
||||
"type": 3,
|
||||
"api": "csp_AppMH",
|
||||
"searchable": 1,
|
||||
"quickSearch": 1,
|
||||
"filterable": 1,
|
||||
"changeable": 1,
|
||||
"ext": "https://45.150.167.18:8000"
|
||||
},
|
||||
{
|
||||
"key": "橙子",
|
||||
"name": "🍊橙子┃高清影视",
|
||||
"type": 3,
|
||||
"api": "csp_App99",
|
||||
"ext": {
|
||||
"host": "https://api.12321app.com/api",
|
||||
"host": "http://113.31.180.218:19987/app/bn",
|
||||
"LoginPath": "/app/log",
|
||||
"version": "0b4328287a5d953e",
|
||||
"appkey": "a0a18659a9977a47e53442cd084b536c",
|
||||
"versionName": "2.8.1",
|
||||
"name": "听心视频",
|
||||
"package": "com.iksp.adsys.jjsp",
|
||||
"appkey": "6e8f3764a0644f3686ab5cdd57bcdf48",
|
||||
"versionName": "4.3.1",
|
||||
"name": "小橙子",
|
||||
"package": "com.xchengzix.app",
|
||||
"buildNumber": "2001",
|
||||
"buildSignature": "03DD38CE4C3D62D0F0DEFACC06768D14EB382C7BD77A05B2EBF4D66E154A0D47"
|
||||
"buildSignature": "99DA983CF878CEC016616175464A91A94775E20A489F07F76FCDEA1A0F2B6B45"
|
||||
}
|
||||
},
|
||||
{
|
||||
"key": "剧圈99",
|
||||
"name": "🫎剧圈丨1080P",
|
||||
"name": "🫎剧圈┃高清影视",
|
||||
"type": 3,
|
||||
"api": "csp_App99",
|
||||
"ext": {
|
||||
@@ -239,25 +298,9 @@
|
||||
"buildSignature": "054FA8DDA4319C6B6A9B954CA5777541C993F00B1B0BD4394F7EDE48184C4594"
|
||||
}
|
||||
},
|
||||
{
|
||||
"key": "顾我99",
|
||||
"name": "🖼️顾我丨1080P",
|
||||
"type": 3,
|
||||
"api": "csp_App99",
|
||||
"ext": {
|
||||
"host": "http://117.50.200.113:19987/app/bn",
|
||||
"LoginPath": "/app/log",
|
||||
"appkey": "040f9b1bc5e942569b5c3e63943306ab",
|
||||
"versionName": "4.3.1",
|
||||
"name": "顾我追剧",
|
||||
"package": "com.guwozhuijux.app",
|
||||
"buildNumber": "2001",
|
||||
"buildSignature": "5AD4436C4730FFE26910C86278B80F3E661C317FFC3616F702D20A729262624A"
|
||||
}
|
||||
},
|
||||
{
|
||||
"key": "天堂",
|
||||
"name": "👀天堂丨1080P",
|
||||
"name": "👀天堂┃高清影视",
|
||||
"type": 3,
|
||||
"api": "csp_AppDrama",
|
||||
"searchable": 1,
|
||||
@@ -277,7 +320,7 @@
|
||||
},
|
||||
{
|
||||
"key": "橘汁",
|
||||
"name": "👀橘汁丨1080P",
|
||||
"name": "👀橘汁┃高清影视",
|
||||
"type": 3,
|
||||
"api": "csp_AppDrama",
|
||||
"searchable": 1,
|
||||
@@ -297,7 +340,7 @@
|
||||
},
|
||||
{
|
||||
"key": "荐片",
|
||||
"name": "🧲荐片┃1080P",
|
||||
"name": "🧲荐片┃高清影视",
|
||||
"quickSearch": 0,
|
||||
"changeable": "0",
|
||||
"searchable": 1,
|
||||
@@ -310,42 +353,18 @@
|
||||
},
|
||||
"ext": "https://api.ztcgi.com"
|
||||
},
|
||||
{
|
||||
"key": "csp_duanju",
|
||||
"name": "🔥短剧1┃1080P",
|
||||
"type": 3,
|
||||
"timeout": 12,
|
||||
"api": "csp_HemaDJ"
|
||||
},
|
||||
{
|
||||
"key": "csp_XY",
|
||||
"name": "🔥短剧2┃1080P",
|
||||
"type": 3,
|
||||
"timeout": 12,
|
||||
"api": "csp_AppXY",
|
||||
"ext": ""
|
||||
},
|
||||
{
|
||||
"key": "csp_APPTe",
|
||||
"name": "🍉天鹅┃1080P",
|
||||
"name": "🍉天鹅┃高清影视",
|
||||
"type": 3,
|
||||
"timeout": 12,
|
||||
"searchable": 1,
|
||||
"quickSearch": 0,
|
||||
"api": "csp_AppTe"
|
||||
},
|
||||
{
|
||||
"key": "csp_Gz360",
|
||||
"name": "🍉瓜子┃1080P",
|
||||
"type": 3,
|
||||
"timeout": 12,
|
||||
"searchable": 1,
|
||||
"quickSearch": 0,
|
||||
"api": "csp_Gz360"
|
||||
},
|
||||
{
|
||||
"key": "csp_Jpys",
|
||||
"name": "🥇金牌┃1080P",
|
||||
"name": "🥇金牌┃高清影视",
|
||||
"type": 3,
|
||||
"timeout": 12,
|
||||
"searchable": 1,
|
||||
@@ -355,7 +374,7 @@
|
||||
},
|
||||
{
|
||||
"key": "csp_MiSou",
|
||||
"name": "🔍米搜┃盘搜",
|
||||
"name": "🔍米搜┃网盘搜索",
|
||||
"type": 3,
|
||||
"timeout": 12,
|
||||
"searchable": 1,
|
||||
@@ -363,14 +382,48 @@
|
||||
"api": "csp_MiSou"
|
||||
},
|
||||
{
|
||||
"key": "csp_TingBook",
|
||||
"name": "📖听书┃娱乐",
|
||||
"key": "六月有声",
|
||||
"name": "📻六月┃有声听书",
|
||||
"type": 3,
|
||||
"api": "csp_TingBook"
|
||||
"api": "csp_TingBook",
|
||||
"searchable": 1,
|
||||
"quickSearch": 1,
|
||||
"changeable": 0,
|
||||
"filterable": 1,
|
||||
"ext": "https://app.365ting.com",
|
||||
"style": {
|
||||
"type": "list"
|
||||
}
|
||||
},
|
||||
{
|
||||
"key": "酷酷",
|
||||
"name": "🎵酷酷┃在线音乐",
|
||||
"type": 3,
|
||||
"api": "csp_KuKuMusic",
|
||||
"searchable": 1,
|
||||
"quickSearch": 1,
|
||||
"filterable": 0,
|
||||
"changeable": 0,
|
||||
"style": {
|
||||
"type": "oval",
|
||||
"ratio": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"key": "Live",
|
||||
"name": "📡游戏┃在线直播",
|
||||
"type": 3,
|
||||
"api": "csp_YXZB",
|
||||
"searchable": 0,
|
||||
"quickSearch": 0,
|
||||
"style": {
|
||||
"type": "rect",
|
||||
"ratio": 3.8
|
||||
}
|
||||
},
|
||||
{
|
||||
"key": "Aid",
|
||||
"name": "🚑 急救┃知识",
|
||||
"name": "🚑急救┃医疗知识",
|
||||
"type": 3,
|
||||
"api": "csp_FirstAid",
|
||||
"searchable": 0,
|
||||
@@ -382,7 +435,7 @@
|
||||
},
|
||||
{
|
||||
"key": "push_agent",
|
||||
"name": "📤 推送┃播放",
|
||||
"name": "📤推送┃设备播放",
|
||||
"type": 3,
|
||||
"filterable": 0,
|
||||
"changeable": 0,
|
||||
@@ -394,17 +447,17 @@
|
||||
],
|
||||
"parses": [
|
||||
{
|
||||
"name": "📦 Json聚合",
|
||||
"name": "📦聚合┃Json解析",
|
||||
"type": 3,
|
||||
"url": "Demo"
|
||||
},
|
||||
{
|
||||
"name": "🎬 影视聚合",
|
||||
"name": "🎬聚合┃影视解析",
|
||||
"type": 3,
|
||||
"url": "影视"
|
||||
},
|
||||
{
|
||||
"name": "🐮 牛牛解析",
|
||||
"name": "🐮解析┃牛牛专线",
|
||||
"type": 1,
|
||||
"url": "",
|
||||
"ext": {
|
||||
@@ -424,7 +477,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "🌃 夜幕解析",
|
||||
"name": "🌃解析┃夜幕专线",
|
||||
"type": 0,
|
||||
"url": ""
|
||||
}
|
||||
|
||||
@@ -1,330 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# by @嗷呜
|
||||
import json
|
||||
import random
|
||||
import sys
|
||||
from base64 import b64encode, b64decode
|
||||
from concurrent.futures import ThreadPoolExecutor
|
||||
|
||||
# 引入 RSA 加解密所需模块
|
||||
from Crypto.PublicKey import RSA
|
||||
from Crypto.Cipher import PKCS1_v1_5
|
||||
|
||||
sys.path.append('..')
|
||||
from base.spider import Spider
|
||||
|
||||
class Spider(Spider):
|
||||
|
||||
def init(self, extend=""):
|
||||
did = self.getdid()
|
||||
self.headers.update({'deviceId': did})
|
||||
token = self.gettk()
|
||||
self.headers.update({'token': token})
|
||||
|
||||
def getName(self):
|
||||
pass
|
||||
|
||||
def isVideoFormat(self, url):
|
||||
pass
|
||||
|
||||
def manualVideoCheck(self):
|
||||
pass
|
||||
|
||||
def destroy(self):
|
||||
pass
|
||||
|
||||
# 1. 修改为主机域名
|
||||
host = 'http://qkys.qukanwh.com'
|
||||
|
||||
# 2. 同步原脚本的配置请求头
|
||||
headers = {
|
||||
'HOST': 'qkys.qukanwh.com',
|
||||
'User-Agent': 'okhttp/4.12.0',
|
||||
'client': 'app',
|
||||
'deviceType': 'Android',
|
||||
'Referer': ''
|
||||
}
|
||||
|
||||
# 3. 导入原脚本中的 RSA 密钥对与配置
|
||||
publicKey_str = "-----BEGIN PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCoYt0BP77U+DM08BiI/QbSRIfxijXo85BTPqIM1Ow8BNwhLETzRIZ+dEwdWDbydG/PspgBAfRpGaYVdJYtvaC2JnoO8+Ik6qMWojfEJxSFLa0Pb0A892tun4gsxoEMjcreZ+YGyaBxAfqX0BSMfdrOgIYaZQjYrw9TRLlUT31QoQIDAQAB\n-----END PUBLIC KEY-----"
|
||||
privateKey_str = "-----BEGIN PRIVATE KEY-----\nMIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCquQQ5r6+yJI8CDFkXRp8vUsdD45ov8EP12ooLs56ca2DQXaSNGS9910bAPVA9chkp0mKIvKqjAsHz5Tl9EeNPblarGEeJUIxpxZtiSqNTpvtiD/TjhpzuHYic7RAfQ/h7p/ypE8ymU42pYjsB5t26Mv6XgkLV+jzrSf73HlCuS0iMyLmt6zz3Mw9izM13EpB8iFLtfbbYymycKTx4RAmPQLwhNGex/AlUIYxXP4R2yyaa4W6mEtc6aME2QuzJFxPgP3HJ9NBx/LWVn4skxWjZ7zg+VRQRHnjyVaSLu3Z5gN5ITWCyE32qaHJa6WBahZj5jWhRyAG1bQ+xKJa8lBL5AgMBAAECggEAUwv9SjJ0PSwbhNuM2w23kcWquROWhYtTA91zGY4esehqB/IFgb2mpIh8Gje5OKqwIu/8jpd4SiOlRYdUF8sD0DfUYRZGdj2AkFNX6tBz8tVfo6wvbB6naA1lzzBij1L5JO3qsjS3cJFkb+kg2yP66AC2Z+0tpfk8eRhdtshAZwfcd1DEGt1uAvYL1eaUK9HRvpt9lPeGcHERDl2hBd4uyaF0K1O+zF9y59nYbTySWPxRZq3sFEE85xRMlstD7YZi7W2gKvMFRD4/FKmrZ3m7aKJRITtyKOyyPcYmepNv3Qv7kk59Pg38n2WWQ0Ra/bCH3E48YNCnQvZMpitkTfJhoQKBgQDbnROOYTP8OTJ6f/qhoGjxeO3x1VOaOp8l0x7b0SCfoqNGS0Cyiqj72BmJtPMPqSTjn6MmNzqbg1KOdhXyzNozs+i5ccW1M56j96mr5I/Z0FpE3oyIHNfDDBlf9M8YQqEF9oYxniYYft9oapO7cRQkHER6qpvnHTavwlv4m78CXwKBgQDHAjs2YlpKDdI1lcbZJCc7TwtH+Pd2bUki8YXafWNcPhITQHbOZjr310eK1QJC6GJncjkOqbX7yv3ivvTO35FZTQhuA1xEG1P00FG8bE0tHYPIwQHi9y0eA5cieMdo8E6XYria1mw/3fqSQEsfZyJlR32JQIoGAipM8iO1X2nZpwKBgDkMFIhnt5lNQk+P7wsNIDWZtDWdtJnboHuy29E+Abt2A/O+mI/IdRz2hau/1WO8DFkUnszOi+rZshhPlGP90rCbi1igtTrcrdjp/KkqNjPea5R4OwkgdOu1uOG0NheXNzzVTQaWjk7Opjn5dWa7eP/oV+GFb/oZHJuLYVizHGsBAoGADA7rjZEKDYCm4w5PPSr+oY5ZjaPdQrS+gLqHtMRyN82fBMGcMUdqfUfzEstzVqCEDeaS5HuOBlK3bXzKkppjUTjksN3NQmcxgBz7RuJ9DqXCLXDcb2cwuafYCYOt+YLOEEgwDVm+t2P44dG5e46hO+fICH/7nP+WlpD5buz4GfMCgYB57r3g/6hi9WUDnfc7ZAzWMqR0EhJVYKYy+KFEtdIPzhkkIHq5RASe88E9kzoGoZFdb3tIjvGZWcHerirrqWkMsuQtP/Qi0zjieid5tAPj+r4kbiCVTw0E0jnmPBzGInQi7lpeTTKnG1fbyS5lBS+WmHfIuzpECgCkxhaT+LJJkg==\n-----END PRIVATE KEY-----"
|
||||
|
||||
# RSA 公钥加密实现
|
||||
def rsa_encrypt(self, text):
|
||||
try:
|
||||
key = RSA.import_key(self.publicKey_str)
|
||||
cipher = PKCS1_v1_5.new(key)
|
||||
cipher_text = cipher.encrypt(text.encode('utf-8'))
|
||||
return b64encode(cipher_text).decode('utf-8')
|
||||
except Exception as e:
|
||||
print(f"RSA加密失败: {e}")
|
||||
return ""
|
||||
|
||||
# RSA 私钥解密实现
|
||||
def rsa_decrypt(self, text):
|
||||
try:
|
||||
key = RSA.import_key(self.privateKey_str)
|
||||
cipher = PKCS1_v1_5.new(key)
|
||||
raw_bytes = b64decode(text.encode('utf-8'))
|
||||
|
||||
decrypted = b""
|
||||
offset = 0
|
||||
while offset < len(raw_bytes):
|
||||
chunk = raw_bytes[offset:offset + 256]
|
||||
decrypted += cipher.decrypt(chunk, None)
|
||||
offset += 256
|
||||
return decrypted.decode('utf-8')
|
||||
except Exception as e:
|
||||
print(f"RSA解密失败: {e}")
|
||||
return ""
|
||||
|
||||
def homeContent(self, filter):
|
||||
data = self.post(f"{self.host}/api/v1/app/screen/screenType", headers=self.headers).json()
|
||||
result = {}
|
||||
cate = {
|
||||
"类型": "type",
|
||||
"地区": "area",
|
||||
"年份": "year"
|
||||
}
|
||||
sort = {
|
||||
'key': 'sort',
|
||||
'name': '排序',
|
||||
'value': [{'n': '最新', 'v': 'NEWEST'}, {'n': '热门', 'v': 'HOT'}, {'n': '收藏', 'v': 'COLLECT'}]
|
||||
}
|
||||
classes = []
|
||||
filters = {}
|
||||
for k in data.get('data', []):
|
||||
classes.append({
|
||||
'type_name': k['name'],
|
||||
'type_id': str(k['id'])
|
||||
})
|
||||
filters[str(k['id'])] = []
|
||||
for v in k.get('children', []):
|
||||
if v['name'] in cate:
|
||||
filters[str(k['id'])].append({
|
||||
'name': v['name'],
|
||||
'key': cate[v['name']],
|
||||
'value': [{'n': i['name'], 'v': i['name']} for i in v.get('children', [])]
|
||||
})
|
||||
filters[str(k['id'])].append(sort)
|
||||
result['class'] = classes
|
||||
result['filters'] = filters
|
||||
return result
|
||||
|
||||
def homeVideoContent(self):
|
||||
jdata = {
|
||||
"condition": {
|
||||
"sreecnTypeEnum": "NEWEST"
|
||||
},
|
||||
"pageNum": 1,
|
||||
"pageSize": 40
|
||||
}
|
||||
data = self.post(f"{self.host}/api/v1/app/screen/screenMovie", headers=self.headers, json=jdata).json()
|
||||
return {'list': self.getlist(data.get('data', {}).get('records', []))}
|
||||
|
||||
def categoryContent(self, tid, pg, filter, extend):
|
||||
# 保持最纯粹的条件字段,移除任何空字符串占位
|
||||
condition = {
|
||||
'sreecnTypeEnum': 'NEWEST',
|
||||
'typeId': int(tid) if str(tid).isdigit() else tid
|
||||
}
|
||||
|
||||
if extend:
|
||||
if 'sort' in extend:
|
||||
condition['sreecnTypeEnum'] = extend.pop('sort')
|
||||
condition.update(extend)
|
||||
|
||||
jdata = {
|
||||
'condition': condition,
|
||||
'pageNum': int(pg),
|
||||
'pageSize': 40,
|
||||
}
|
||||
|
||||
try:
|
||||
data = self.post(f"{self.host}/api/v1/app/screen/screenMovie", headers=self.headers, json=jdata).json()
|
||||
result = {}
|
||||
if data and data.get('data') and 'records' in data['data']:
|
||||
result['list'] = self.getlist(data['data']['records'])
|
||||
else:
|
||||
result['list'] = []
|
||||
result['page'] = pg
|
||||
result['pagecount'] = 9999
|
||||
result['limit'] = 40
|
||||
result['total'] = 999999
|
||||
return result
|
||||
except Exception as e:
|
||||
print(f"分类获取错误: {e}")
|
||||
return {'list': [], 'page': pg}
|
||||
|
||||
def detailContent(self, ids):
|
||||
ids = ids[0].split('@@')
|
||||
jdata = {"id": int(ids[0]), "typeId": ids[-1]}
|
||||
v = self.post(f"{self.host}/api/v1/app/play/movieDesc", headers=self.headers, json=jdata).json()
|
||||
v = v.get('data', {})
|
||||
vod = {
|
||||
'type_name': v.get('typeId', ''),
|
||||
'vod_year': v.get('year', ''),
|
||||
'vod_area': v.get('area', ''),
|
||||
'vod_actor': v.get('star', ''),
|
||||
'vod_director': v.get('director', ''),
|
||||
'vod_content': v.get('introduce', ''),
|
||||
'vod_play_from': '',
|
||||
'vod_play_url': ''
|
||||
}
|
||||
|
||||
play_params = {
|
||||
"id": int(ids[0]),
|
||||
"source": 0,
|
||||
"typeId": ids[-1]
|
||||
}
|
||||
encrypt_payload = {"key": self.rsa_encrypt(json.dumps(play_params))}
|
||||
|
||||
c_res = self.post(f"{self.host}/api/v1/app/play/movieDetails", headers=self.headers, json=encrypt_payload).json()
|
||||
decrypted_play_str = self.rsa_decrypt(c_res.get('data', ''))
|
||||
if not decrypted_play_str:
|
||||
return {'list': [vod]}
|
||||
|
||||
decrypted_play_data = json.loads(decrypted_play_str)
|
||||
l = decrypted_play_data.get('moviePlayerList', [])
|
||||
if not l:
|
||||
return {'list': [vod]}
|
||||
|
||||
n = {str(i['id']): i['moviePlayerName'] for i in l}
|
||||
|
||||
m = play_params.copy()
|
||||
m.update({'playerId': l[0]['id']})
|
||||
|
||||
first_source_payload = {"key": self.rsa_encrypt(json.dumps(m))}
|
||||
first_res = self.post(f"{self.host}/api/v1/app/play/movieDetails", headers=self.headers, json=first_source_payload).json()
|
||||
|
||||
decrypted_first_str = self.rsa_decrypt(first_res.get('data', ''))
|
||||
if decrypted_first_str:
|
||||
decrypted_first_episode = json.loads(decrypted_first_str)
|
||||
pd = self.getv(m, decrypted_first_episode.get('episodeList', []))
|
||||
else:
|
||||
pd = {}
|
||||
|
||||
if len(l) > 1:
|
||||
with ThreadPoolExecutor(max_workers=len(l)-1) as executor:
|
||||
future_to_player = {executor.submit(self.getd, play_params, player): player for player in l[1:]}
|
||||
for future in future_to_player:
|
||||
try:
|
||||
o, p = future.result()
|
||||
if p:
|
||||
pd.update(self.getv(o, p))
|
||||
except Exception as e:
|
||||
print(f"多线路请求失败: {e}")
|
||||
w, e = [], []
|
||||
for i, x in pd.items():
|
||||
if x:
|
||||
w.append(n.get(i, '未知线路'))
|
||||
e.append(x)
|
||||
vod['vod_play_from'] = '$$$'.join(w)
|
||||
vod['vod_play_url'] = '$$$'.join(e)
|
||||
return {'list': [vod]}
|
||||
|
||||
def searchContent(self, key, quick, pg="1"):
|
||||
jdata = {
|
||||
"condition": {
|
||||
"value": str(key)
|
||||
},
|
||||
"pageNum": int(pg),
|
||||
"pageSize": 40
|
||||
}
|
||||
try:
|
||||
data = self.post(f"{self.host}/api/v1/app/search/searchMovie", headers=self.headers, json=jdata).json()
|
||||
return {'list': self.getlist(data.get('data', {}).get('records', [])), 'page': pg}
|
||||
except Exception as e:
|
||||
print(f"搜索请求失败: {e}")
|
||||
return {'list': [], 'page': pg}
|
||||
|
||||
def playerContent(self, flag, id, vipFlags):
|
||||
raw_id_str = self.d64(id)
|
||||
if not raw_id_str:
|
||||
return {'parse': 0, 'url': ''}
|
||||
jdata = json.loads(raw_id_str)
|
||||
encrypt_payload = {"key": self.rsa_encrypt(json.dumps(jdata))}
|
||||
data = self.post(f"{self.host}/api/v1/app/play/movieDetails", headers=self.headers, json=encrypt_payload).json()
|
||||
|
||||
try:
|
||||
decrypted_url_data = json.loads(self.rsa_decrypt(data.get('data', '')))
|
||||
playerUrl = decrypted_url_data.get('url', '')
|
||||
if not playerUrl:
|
||||
return {'parse': 0, 'url': ''}
|
||||
|
||||
params = {'playerUrl': playerUrl, 'playerId': jdata['playerId']}
|
||||
pd = self.fetch(f"{self.host}/api/v1/app/play/analysisMovieUrl", headers=self.headers, params=params).json()
|
||||
url, p = pd.get('data', ''), 0
|
||||
except Exception as e:
|
||||
print(f"解析流媒体直链失败: {e}")
|
||||
url, p = "", 0
|
||||
return {'parse': p, 'url': url, 'header': {'User-Agent': 'okhttp/4.12.0'}}
|
||||
|
||||
def localProxy(self, param):
|
||||
pass
|
||||
|
||||
def liveContent(self, url):
|
||||
pass
|
||||
|
||||
def gettk(self):
|
||||
self.headers.update({'deviceId': self.getdid()})
|
||||
try:
|
||||
data = self.fetch(f"{self.host}/api/v1/app/user/visitorInfo", headers=self.headers).json()
|
||||
return data.get('data', {}).get('token', '')
|
||||
except:
|
||||
return ""
|
||||
|
||||
def getdid(self):
|
||||
did = self.getCache('ldid')
|
||||
if not did:
|
||||
hex_chars = '0123456789abcdef'
|
||||
did = ''.join(random.choice(hex_chars) for _ in range(16))
|
||||
self.setCache('ldid', did)
|
||||
return did
|
||||
|
||||
def getd(self, jdata, player):
|
||||
x = jdata.copy()
|
||||
x.update({'playerId': player['id']})
|
||||
encrypt_payload = {"key": self.rsa_encrypt(json.dumps(x))}
|
||||
response = self.post(f"{self.host}/api/v1/app/play/movieDetails", headers=self.headers, json=encrypt_payload).json()
|
||||
decrypted_str = self.rsa_decrypt(response.get('data', ''))
|
||||
if decrypted_str:
|
||||
decrypted_episode = json.loads(decrypted_str)
|
||||
return x, decrypted_episode.get('episodeList', [])
|
||||
return x, []
|
||||
|
||||
def getv(self, d, c):
|
||||
f = {str(d['playerId']): ''}
|
||||
g = []
|
||||
for i in c:
|
||||
j = d.copy()
|
||||
j.update({'episodeId': i['id']})
|
||||
g.append(f"{i['episode']}${self.e64(json.dumps(j))}")
|
||||
f[str(d['playerId'])] = '#'.join(g)
|
||||
return f
|
||||
|
||||
def getlist(self, data):
|
||||
videos = []
|
||||
for i in data:
|
||||
if not i.get('id'):
|
||||
continue
|
||||
videos.append({
|
||||
'vod_id': f"{i['id']}@@{i.get('typeId', '')}",
|
||||
'vod_name': i.get('name', ''),
|
||||
'vod_pic': i.get('cover', ''),
|
||||
'vod_year': i.get('year', ''),
|
||||
'vod_remarks': i.get('totalEpisode', '')
|
||||
})
|
||||
return videos
|
||||
|
||||
def e64(self, text):
|
||||
try:
|
||||
return b64encode(text.encode('utf-8')).decode('utf-8')
|
||||
except:
|
||||
return ""
|
||||
|
||||
def d64(self, encoded_text):
|
||||
try:
|
||||
return b64decode(encoded_text.encode('utf-8')).decode('utf-8')
|
||||
except:
|
||||
return ""
|
||||
Binary file not shown.
Reference in New Issue
Block a user