From 33375c79282ee43ddfd1f4e3f15dba9301d05563 Mon Sep 17 00:00:00 2001
From: cluntop <85211716+cluntop@users.noreply.github.com>
Date: Sat, 21 Mar 2026 12:46:20 +0800
Subject: [PATCH 01/10] Update Up
---
_headers | 4 +---
index.html | 2 +-
2 files changed, 2 insertions(+), 4 deletions(-)
diff --git a/_headers b/_headers
index 45f9b664a..72561931f 100644
--- a/_headers
+++ b/_headers
@@ -1,3 +1 @@
-/*
- ! Nel
- ! Report-To
+# None yet.
diff --git a/index.html b/index.html
index 4e5dbe5e5..0e86e397f 100755
--- a/index.html
+++ b/index.html
@@ -6,7 +6,7 @@
雨呢主页,TVBox,接口
-
+
From 4bf2e8a4fa592f83be6faa2fe5967a3068597ae3 Mon Sep 17 00:00:00 2001
From: cluntop <85211716+cluntop@users.noreply.github.com>
Date: Sat, 21 Mar 2026 17:51:30 +0800
Subject: [PATCH 02/10] Update Up
---
py/爱瓜.py | 537 ------------------------------------------------
py/爱瓜TVAPP.py | 165 ---------------
2 files changed, 702 deletions(-)
delete mode 100755 py/爱瓜.py
delete mode 100755 py/爱瓜TVAPP.py
diff --git a/py/爱瓜.py b/py/爱瓜.py
deleted file mode 100755
index 34fa92984..000000000
--- a/py/爱瓜.py
+++ /dev/null
@@ -1,537 +0,0 @@
-# -*- coding: utf-8 -*-
-# @Author : Doubebly
-# @Time : 2025/3/22 21:03
-import json
-import sys
-import requests
-from lxml import etree, html
-import re
-sys.path.append('..')
-from base.spider import Spider
-
-
-class Spider(Spider):
- def getName(self):
- return "爱瓜TV"
-
- def init(self, extend):
- self.home_url = 'https://aigua1.com'
- self.headers = {
- "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36",
- "Referer": "https://aigua1.com/",
- }
- self.image_domain = "https://vres.wbadl.cn" # 圖片域名
-
- self.default_play_url = 'https://sf1-cdn-tos.huoshanstatic.com/obj/media-fe/xgplayer_doc_video/mp4/xgplayer-demo-720p.mp4'
-
- def getDependence(self):
- return []
-
- def isVideoFormat(self, url):
- pass
-
- def manualVideoCheck(self):
- pass
-
- def homeContent(self, filter):
- result = {
- 'class': [
- {'type_id': '2', 'type_name': '电视剧'},
- {'type_id': '1', 'type_name': '电影'},
- {'type_id': '3', 'type_name': '综艺'},
- {'type_id': '4', 'type_name': '动漫'},
- {'type_id': '32', 'type_name': '纪录片'}
- ],
- 'filters': {
- '1': [ # 电影筛选条件
- {'name': '剧情', 'key': 'class', 'value': [
- {'n': '全部', 'v': '0'},
- {'n': '魔幻', 'v': '179'},
- {'n': '动作', 'v': '154'},
- {'n': '科幻', 'v': '159'},
- {'n': '惊悚', 'v': '156'},
- {'n': '犯罪', 'v': '157'},
- {'n': '剧情', 'v': '161'},
- {'n': '悬疑', 'v': '160'},
- {'n': '奇幻', 'v': '226'},
- {'n': '爱情', 'v': '155'},
- {'n': '战争', 'v': '164'},
- {'n': '恐怖', 'v': '169'},
- {'n': '喜剧', 'v': '153'},
- {'n': '冒险', 'v': '280'},
- {'n': '灾难', 'v': '281'},
- {'n': '歌舞', 'v': '282'},
- {'n': '动画', 'v': '283'},
- {'n': '经典', 'v': '284'},
- {'n': '同性', 'v': '285'},
- {'n': '网络电影', 'v': '286'},
- {'n': '其他', 'v': '178'}
- ]},
- {'name': '地区', 'key': 'area', 'value': [
- {'n': '全部', 'v': '0'},
- {'n': '大陆', 'v': '18'},
- {'n': '日本', 'v': '24'},
- {'n': '香港', 'v': '20'},
- {'n': '韩国', 'v': '21'},
- {'n': '台湾', 'v': '23'},
- {'n': '英国', 'v': '22'},
- {'n': '东南亚', 'v': '29'},
- {'n': '欧美', 'v': '19'},
- {'n': '其它', 'v': '30'}
- ]},
- {'name': '年份', 'key': 'year', 'value': [
- {'n': '全部', 'v': '0'},
- {'n': '2025', 'v': '131'},
- {'n': '2024', 'v': '130'},
- {'n': '2023', 'v': '129'},
- {'n': '2022', 'v': '21'},
- {'n': '2021', 'v': '22'},
- {'n': '2020', 'v': '23'},
- {'n': '2019', 'v': '24'},
- {'n': '2018', 'v': '25'},
- {'n': '2017', 'v': '26'},
- {'n': '2016', 'v': '27'},
- {'n': '2015', 'v': '28'},
- {'n': '2014', 'v': '29'},
- {'n': '2013', 'v': '30'},
- {'n': '2012', 'v': '31'},
- {'n': '2011', 'v': '32'},
- {'n': '2010', 'v': '33'},
- {'n': '2009', 'v': '34'},
- {'n': '2008', 'v': '35'},
- {'n': '更早', 'v': '127'}
- ]},
- {'name': '状态', 'key': 'status', 'value': [
- {'n': '全部', 'v': '0'},
- {'n': '完结', 'v': '1'},
- {'n': '更新中', 'v': '2'}
- ]},
- {'name': '排序', 'key': 'by', 'value': [
- {'n': '添加时间', 'v': 'new'},
- {'n': '人气高低', 'v': 'hot'},
- {'n': '评分高低', 'v': 'score'}
- ]}
- ],
- '2': [ # 电视剧筛选条件
- {'name': '剧情', 'key': 'class', 'value': [
- {'n': '全部', 'v': '0'},
- {'n': '短剧', 'v': '364'},
- {'n': '偶像', 'v': '251'},
- {'n': '爱情', 'v': '252'},
- {'n': '言情', 'v': '253'},
- {'n': '古装', 'v': '254'},
- {'n': '历史', 'v': '255'},
- {'n': '玄幻', 'v': '256'},
- {'n': '谍战', 'v': '257'},
- {'n': '历险', 'v': '258'},
- {'n': '都市', 'v': '259'},
- {'n': '科幻', 'v': '260'},
- {'n': '军旅', 'v': '261'},
- {'n': '喜剧', 'v': '262'},
- {'n': '武侠', 'v': '263'},
- {'n': '江湖', 'v': '264'},
- {'n': '罪案', 'v': '265'},
- {'n': '青春', 'v': '266'},
- {'n': '家庭', 'v': '267'},
- {'n': '战争', 'v': '268'},
- {'n': '悬疑', 'v': '269'},
- {'n': '穿越', 'v': '270'},
- {'n': '宫廷', 'v': '271'},
- {'n': '神话', 'v': '272'},
- {'n': '商战', 'v': '273'},
- {'n': '警匪', 'v': '274'},
- {'n': '动作', 'v': '275'},
- {'n': '惊悚', 'v': '276'},
- {'n': '剧情', 'v': '277'},
- {'n': '同性', 'v': '278'},
- {'n': '奇幻', 'v': '279'},
- {'n': '其他', 'v': '231'}
- ]},
- {'name': '地区', 'key': 'area', 'value': [
- {'n': '全部', 'v': '0'},
- {'n': '大陆', 'v': '18'},
- {'n': '日本', 'v': '24'},
- {'n': '香港', 'v': '20'},
- {'n': '韩国', 'v': '21'},
- {'n': '台湾', 'v': '23'},
- {'n': '英国', 'v': '22'},
- {'n': '东南亚', 'v': '29'},
- {'n': '欧美', 'v': '19'},
- {'n': '其它', 'v': '30'}
- ]},
- {'name': '年份', 'key': 'year', 'value': [
- {'n': '全部', 'v': '0'},
- {'n': '2025', 'v': '131'},
- {'n': '2024', 'v': '130'},
- {'n': '2023', 'v': '129'},
- {'n': '2022', 'v': '21'},
- {'n': '2021', 'v': '22'},
- {'n': '2020', 'v': '23'},
- {'n': '2019', 'v': '24'},
- {'n': '2018', 'v': '25'},
- {'n': '2017', 'v': '26'},
- {'n': '2016', 'v': '27'},
- {'n': '2015', 'v': '28'},
- {'n': '2014', 'v': '29'},
- {'n': '2013', 'v': '30'},
- {'n': '2012', 'v': '31'},
- {'n': '2011', 'v': '32'},
- {'n': '2010', 'v': '33'},
- {'n': '2009', 'v': '34'},
- {'n': '2008', 'v': '35'},
- {'n': '更早', 'v': '127'}
- ]},
- {'name': '状态', 'key': 'status', 'value': [
- {'n': '全部', 'v': '0'},
- {'n': '完结', 'v': '1'},
- {'n': '更新中', 'v': '2'}
- ]},
- {'name': '排序', 'key': 'by', 'value': [
- {'n': '添加时间', 'v': 'new'},
- {'n': '人气高低', 'v': 'hot'},
- {'n': '评分高低', 'v': 'score'}
- ]}
- ],
- '3': [ # 综艺筛选条件
- {'name': '类型', 'key': 'class', 'value': [
- {'n': '全部', 'v': '0'},
- {'n': '生活', 'v': '229'},
- {'n': '脱口秀', 'v': '228'},
- {'n': '真人秀', 'v': '227'},
- {'n': '访谈', 'v': '168'},
- {'n': '选秀', 'v': '287'},
- {'n': '网综', 'v': '288'},
- {'n': '搞笑', 'v': '289'},
- {'n': '竞技', 'v': '290'},
- {'n': '情感', 'v': '291'},
- {'n': '演唱会', 'v': '292'},
- {'n': '晚会', 'v': '293'},
- {'n': '其他', 'v': '232'}
- ]},
- {'name': '地区', 'key': 'area', 'value': [
- {'n': '全部', 'v': '0'},
- {'n': '大陆', 'v': '18'},
- {'n': '日本', 'v': '24'},
- {'n': '香港', 'v': '20'},
- {'n': '韩国', 'v': '21'},
- {'n': '台湾', 'v': '23'},
- {'n': '东南亚', 'v': '29'},
- {'n': '欧美', 'v': '19'},
- {'n': '其它', 'v': '30'}
- ]},
- {'name': '年份', 'key': 'year', 'value': [
- {'n': '全部', 'v': '0'},
- {'n': '2025', 'v': '131'},
- {'n': '2024', 'v': '130'},
- {'n': '2023', 'v': '129'},
- {'n': '2022', 'v': '21'},
- {'n': '2021', 'v': '22'},
- {'n': '2020', 'v': '23'},
- {'n': '2019', 'v': '24'},
- {'n': '2018', 'v': '25'},
- {'n': '2017', 'v': '26'},
- {'n': '2016', 'v': '27'},
- {'n': '2015', 'v': '28'},
- {'n': '2014', 'v': '29'},
- {'n': '2013', 'v': '30'},
- {'n': '2012', 'v': '31'},
- {'n': '2011', 'v': '32'},
- {'n': '2010', 'v': '33'},
- {'n': '2009', 'v': '34'},
- {'n': '2008', 'v': '35'},
- {'n': '更早', 'v': '127'}
- ]},
- {'name': '状态', 'key': 'status', 'value': [
- {'n': '全部', 'v': '0'},
- {'n': '完结', 'v': '1'},
- {'n': '更新中', 'v': '2'}
- ]},
- {'name': '排序', 'key': 'by', 'value': [
- {'n': '添加时间', 'v': 'new'},
- {'n': '人气高低', 'v': 'hot'},
- {'n': '评分高低', 'v': 'score'}
- ]}
- ],
- '4': [ # 动漫筛选条件
- {'name': '类型', 'key': 'class', 'value': [
- {'n': '全部', 'v': '0'},
- {'n': '儿童', 'v': '363'},
- {'n': '格斗', 'v': '167'},
- {'n': '热血', 'v': '165'},
- {'n': '机战', 'v': '166'},
- {'n': '少女', 'v': '294'},
- {'n': '竞技', 'v': '295'},
- {'n': '科幻', 'v': '296'},
- {'n': '爆笑', 'v': '297'},
- {'n': '推理', 'v': '298'},
- {'n': '魔幻', 'v': '299'},
- {'n': '冒险', 'v': '300'},
- {'n': '恋爱', 'v': '301'},
- {'n': '校园', 'v': '302'},
- {'n': '治愈', 'v': '303'},
- {'n': '泡面', 'v': '304'},
- {'n': '穿越', 'v': '305'},
- {'n': '灵异', 'v': '306'},
- {'n': '耽美', 'v': '307'},
- {'n': '剧场版', 'v': '308'},
- {'n': '其他', 'v': '170'}
- ]},
- {'name': '地区', 'key': 'area', 'value': [
- {'n': '全部', 'v': '0'},
- {'n': '大陆', 'v': '18'},
- {'n': '日本', 'v': '24'},
- {'n': '香港', 'v': '20'},
- {'n': '韩国', 'v': '21'},
- {'n': '台湾', 'v': '23'},
- {'n': '英国', 'v': '22'},
- {'n': '东南亚', 'v': '29'},
- {'n': '欧美', 'v': '19'},
- {'n': '其它', 'v': '30'}
- ]},
- {'name': '年份', 'key': 'year', 'value': [
- {'n': '全部', 'v': '0'},
- {'n': '2025', 'v': '131'},
- {'n': '2024', 'v': '130'},
- {'n': '2023', 'v': '129'},
- {'n': '2022', 'v': '21'},
- {'n': '2021', 'v': '22'},
- {'n': '2020', 'v': '23'},
- {'n': '2019', 'v': '24'},
- {'n': '2018', 'v': '25'},
- {'n': '2017', 'v': '26'},
- {'n': '2016', 'v': '27'},
- {'n': '2015', 'v': '28'},
- {'n': '2014', 'v': '29'},
- {'n': '2013', 'v': '30'},
- {'n': '2012', 'v': '31'},
- {'n': '2011', 'v': '32'},
- {'n': '2010', 'v': '33'},
- {'n': '2009', 'v': '34'},
- {'n': '2008', 'v': '35'},
- {'n': '更早', 'v': '127'}
- ]},
- {'name': '状态', 'key': 'status', 'value': [
- {'n': '全部', 'v': '0'},
- {'n': '完结', 'v': '1'},
- {'n': '更新中', 'v': '2'}
- ]},
- {'name': '排序', 'key': 'by', 'value': [
- {'n': '添加时间', 'v': 'new'},
- {'n': '人气高低', 'v': 'hot'},
- {'n': '评分高低', 'v': 'score'}
- ]}
- ],
- '32': [ # 纪录片筛选条件
- {'name': '类型', 'key': 'class', 'value': [
- {'n': '全部', 'v': '0'} # HTML未提供具体类型,仅保留“全部”
- ]},
- {'name': '地区', 'key': 'area', 'value': [
- {'n': '全部', 'v': '0'} # HTML未提供具体地区,仅保留“全部”
- ]},
- {'name': '年份', 'key': 'year', 'value': [
- {'n': '全部', 'v': '0'},
- {'n': '2025', 'v': '131'},
- {'n': '2024', 'v': '130'},
- {'n': '2023', 'v': '129'},
- {'n': '2022', 'v': '21'},
- {'n': '2021', 'v': '22'},
- {'n': '2020', 'v': '23'},
- {'n': '2019', 'v': '24'},
- {'n': '2018', 'v': '25'},
- {'n': '2017', 'v': '26'},
- {'n': '2016', 'v': '27'},
- {'n': '2015', 'v': '28'},
- {'n': '2014', 'v': '29'},
- {'n': '2013', 'v': '30'},
- {'n': '2012', 'v': '31'},
- {'n': '2011', 'v': '32'},
- {'n': '2010', 'v': '33'},
- {'n': '2009', 'v': '34'},
- {'n': '2008', 'v': '35'},
- {'n': '更早', 'v': '127'}
- ]},
- {'name': '状态', 'key': 'status', 'value': [
- {'n': '全部', 'v': '0'},
- {'n': '完结', 'v': '1'},
- {'n': '更新中', 'v': '2'}
- ]},
- {'name': '排序', 'key': 'by', 'value': [
- {'n': '添加时间', 'v': 'new'},
- {'n': '人气高低', 'v': 'hot'},
- {'n': '评分高低', 'v': 'score'}
- ]}
- ]
- }
- }
- # print(f"Debug homeContent: {result}")
- return result
-
- def homeVideoContent(self):
- d = []
- try:
- res = requests.get(self.home_url, headers=self.headers)
- res.encoding = 'utf-8' # 根据实际情况设置编码
- root = etree.HTML(res.text.encode('utf-8'))
- data_list = root.xpath('//div[@class="video-box-new"]/div[@class="Movie-list"]')
- for i in data_list:
- d.append(
- {
- 'vod_id': i.xpath('./a[@class="Movie movie-height"]/@href')[0].split('=')[-1],
- 'vod_name': i.xpath('./a[2]/text()')[0].strip(),
- 'vod_pic': i.xpath('./a[1]/img/@originalsrc')[0],
- 'vod_remarks': i.xpath('./div[@class="Movie-type02"]/div[2]/text()')[0].strip()
- }
- )
- return {'list': d, 'parse': 0, 'jx': 0}
- except Exception as e:
- print(e)
- return {'list': d, 'parse': 0, 'jx': 0}
-
- def categoryContent(self, cid, page, filter, ext):
- _class = ext.get('class', '0') # 剧情/类型
- _area = ext.get('area', '0') # 地区
- _year = ext.get('year', '0') # 年份
- _status = ext.get('status', '0') # 状态
- _by = ext.get('by', 'new') # 排序
-
- url = self.home_url + f'/video/refresh-cate?page_num={page}&sorttype=desc&channel_id={cid}&tag={_class}&area={_area}&year={_year}&status={_status}&sort={_by}&page_size=28'
- d = []
- try:
- res = requests.get(url, headers=self.headers)
- data_list = res.json()['data']['list']
- for i in data_list:
- d.append(
- {
- 'vod_id': i['video_id'],
- 'vod_name': i['video_name'],
- 'vod_pic': i['cover'],
- 'vod_remarks': i['flag'],
- }
- )
- return {'list': d, 'parse': 0, 'jx': 0}
- except Exception as e:
- print(e)
- return {'list': d, 'parse': 0, 'jx': 0}
-
- def detailContent(self, did):
- ids = did[0]
- video_list = []
- url = self.home_url + f'/video/detail?video_id={ids}'
- try:
- res = requests.get(url, headers=self.headers)
- root = etree.HTML(res.text.encode('utf-8'))
- # vod_play_from_list = root.xpath('//span[@class="source-item-label"]/text()')
- vod_play_from = '$$$'.join(['书生玩剣ⁱ·*₁'', '名妓读经ⁱ·*₁'', '将军作文ⁱ·*₁''])
- # 电视剧
- play_list1 = root.xpath('//ul[contains(@class, "qy-episode-num")]')
- # print(play_list1)
- # 电影
- # play_list2 = root.xpath('//ul[contains(@class, "qy-play-list")]')
- play_list2 = root.xpath('//ul[@id="srctab-1"]')
- # print(play_list2)
- vod_play_url_list = []
- if len(play_list1) > 0:
- play_list = play_list1[:-1]
- # print(play_list)
-
- elif len(play_list2) > 0:
- play_list = play_list2
- # print(play_list)
- else:
- play_list = []
-
- for i in play_list:
- name_list1 = i.xpath('.//div[@class="select-link"]/text()')
- name_list2 = i.xpath('.//span[@class="title-link"]/text()')
- name_list3 = i.xpath('./li/text()')
- # print(name_list1)
- # print(name_list2)
- # print(name_list3)
- # print(name_list1 + name_list2 + name_list3)
- name_list = name_list1 + name_list2 + name_list3
- url_list = i.xpath('./li/@data-chapter-id')
- vod_play_url_list.append(
- '#'.join([_name.strip() + '$' + f'{ids}-{_url}' for _name, _url in zip(name_list, url_list)])
- )
-
-
- # print(vod_play_url_list*3)
- vod_play_url = '$$$'.join(vod_play_url_list*3)
- # print(vod_play_url_list)
- video_list.append({
- 'type_name': '',
- 'vod_id': ids,
- 'vod_name': '',
- 'vod_remarks': '',
- 'vod_year': '',
- 'vod_area': '',
- 'vod_actor': '',
- 'vod_director': '',
- 'vod_content': '',
- 'vod_play_from': vod_play_from,
- 'vod_play_url': vod_play_url
- })
- return {"list": video_list, 'parse': 0, 'jx': 0}
-
- except Exception as e:
- print(f"Error in detailContent: {e}")
- return {'list': [], 'msg': str(e)}
-
- def searchContent(self, key, quick, page='1'):
- if str(page) != '1':
- return {'list': [], 'parse': 0, 'jx': 0}
- url = f'{self.home_url}/video/refresh-video?page_num=1&sorttype=desc&page_size=28&tvNum=7&sort=new&keyword={key}'
- d = []
- try:
- res = requests.get(url, headers=self.headers)
- res.encoding = 'utf-8'
- root = etree.HTML(res.text)
- data_list = root.xpath('//div[@class="SSbox"]')
- for i in data_list:
- d.append(
- {
- 'vod_id': i.xpath('./a/@href')[0].split('=')[-1],
- 'vod_name': ''.join(i.xpath('.//span/text()')),
- 'vod_pic': i.xpath('./a/img/@originalsrc')[0],
- 'vod_remarks': i.xpath('.//div[@class="SSjgTitle"]/text()')[0],
- }
- )
- return {'list': d, 'parse': 0, 'jx': 0}
- except Exception as e:
- print(f"Error in searchContent: {e}")
- return {'list': [], 'parse': 0, 'jx': 0}
-
- def playerContent(self, flag, pid, vipFlags):
- url = 'https://aigua1.com/video/play-url?videoId=230907&sourceId=0&citycode=HKG&chapterId=2916522'
- a = pid.split('-')
- videoId = a[0]
- chapterId = a[1]
- url = self.home_url + f'/video/play-url?videoId={videoId}&sourceId=0&citycode=HKG&chapterId={chapterId}'
- try:
- res = requests.get(url, headers=self.headers)
- play_url_list = res.json()['data']['urlinfo']['resource_url']
- if flag == '线路一':
- play_url = play_url_list['1']
- pass
- elif flag == '线路二':
- play_url = play_url_list['16']
- else:
- play_url = play_url_list['21']
- return {'url': play_url, 'parse': 0, 'jx': 0, 'header': self.headers}
- except Exception as e:
- print(f"Error in playerContent: {e}")
- return {'url': self.default_play_url, 'parse': 0, 'jx': 0}
-
- def localProxy(self, params):
- pass
-
- def destroy(self):
- return '正在Destroy'
-
- def get_data(self):
- url = self.home_url + 'https://aigua1.com/video/refresh-cate?page_num=1&sorttype=desc&channel_id=0&tag=0&area=0&year=0&page_size=28&sort=new'
- pass
-
-if __name__ == '__main__':
- pass
-
diff --git a/py/爱瓜TVAPP.py b/py/爱瓜TVAPP.py
deleted file mode 100755
index 5432413f3..000000000
--- a/py/爱瓜TVAPP.py
+++ /dev/null
@@ -1,165 +0,0 @@
-# -*- coding: utf-8 -*-
-# by @嗷呜
-# 温馨提示:搜索只能搜拼音联想
-import sys
-import time
-import uuid
-from Crypto.Hash import MD5
-sys.path.append('..')
-from base.spider import Spider
-
-
-class Spider(Spider):
-
- def init(self, extend=""):
- self.uid = self.getuid()
- self.token, self.code = self.getuserinfo()
- pass
-
- def getName(self):
- pass
-
- def isVideoFormat(self, url):
- pass
-
- def manualVideoCheck(self):
- pass
-
- def destroy(self):
- pass
-
- host = 'https://tvapi211.magicetech.com'
-
- headers = {'User-Agent': 'okhttp/3.11.0'}
-
- def homeContent(self, filter):
- body = {'token': self.token, 'authcode': self.code}
- data = self.post(f'{self.host}/hr_1_1_0/apptvapi/web/index.php/video/filter-header', json=self.getbody(body),
- headers=self.headers).json()
- result = {}
- classes = []
- filters = {}
- for k in data['data']:
- classes.append({
- 'type_name': k['channel_name'],
- 'type_id': str(k['channel_id']),
- })
- filters[str(k['channel_id'])] = []
- for i in k['search_box']:
- if len(i['list']):
- filters[str(k['channel_id'])].append({
- 'key': i['field'],
- 'name': i['label'],
- 'value': [{'n': j['display'], 'v': str(j['value'])} for j in i['list'] if j['value']]
- })
- result['class'] = classes
- result['filters'] = filters
- return result
-
- def homeVideoContent(self):
- body = {'token': self.token, 'authcode': self.code}
- data = self.post(f'{self.host}/hr_1_1_0/apptvapi/web/index.php/video/index-tv', json=self.getbody(body),
- headers=self.headers).json()
- return {'list': self.getlist(data['data'][0]['banner'])}
-
- def categoryContent(self, tid, pg, filter, extend):
- body = {'token': self.token, 'authcode': self.code, 'channel_id': tid, 'area': extend.get('area', '0'),
- 'year': extend.get('year', '0'), 'sort': extend.get('sort', '0'), 'tag': extend.get('tag', 'hot'),
- 'status': extend.get('status', '0'), 'page_num': pg, 'page_size': '24'}
- data = self.post(f'{self.host}/hr_1_1_0/apptvapi/web/index.php/video/filter-video', json=self.getbody(body),
- headers=self.headers).json()
- result = {}
- result['list'] = self.getlist(data['data']['list'])
- result['page'] = pg
- result['pagecount'] = 9999
- result['limit'] = 90
- result['total'] = 999999
- return result
-
- def detailContent(self, ids):
- ids = ids[0].split('@')
- body = {'token': self.token, 'authcode': self.code, 'channel_id': ids[0], 'video_id': ids[1]}
- data = self.post(f'{self.host}/hr_1_1_0/apptvapi/web/index.php/video/detail', json=self.getbody(body),
- headers=self.headers).json()
- vdata = {}
- for k in data['data']['chapters']:
- i = k['sourcelist']
- for j in i:
- if j['source_name'] not in vdata: vdata[j['source_name']] = []
- vdata[j['source_name']].append(f"{k['title']}${j['source_url']}")
- plist, names = [], []
- for key, value in vdata.items():
- names.append(key)
- plist.append('#'.join(value))
- vod = {
- 'vod_play_from': '$$$'.join(names),
- 'vod_play_url': '$$$'.join(plist),
- }
- return {'list': [vod]}
-
- def searchContent(self, key, quick, pg="1"):
- body = {'token': self.token, 'authcode': self.code, 'keyword': key, 'page_num': pg}
- data = self.post(f'{self.host}/hr_1_1_0/apptvapi/web/index.php/search/letter-result', json=self.getbody(body),
- headers=self.headers).json()
- return {'list': self.getlist(data['data']['list'])}
-
- def playerContent(self, flag, id, vipFlags):
- # https://rysp.tv
- # https://aigua.tv
- result = {
- "parse": 0,
- "url": "id",
- "header": {
- "User-Agent": "Dalvik/2.1.0 (Linux; U; Android 11; M2012K10C Build/RP1A.200720.011)",
- "Origin": "https://aigua.tv",
- "Referer": "https://aigua.tv/"
- }
- }
- return result
-
- def localProxy(self, param):
- pass
-
- def getuserinfo(self):
- data = self.post(f'{self.host}/hr_1_1_0/apptvapi/web/index.php/user/auth-login', json=self.getbody(),
- headers=self.headers).json()
- v = data['data']
- return v['user_token'], v['authcode']
-
- def getuid(self):
- uid = self.getCache('uid')
- if not uid:
- uid = str(uuid.uuid4())
- self.setCache('uid', uid)
- return uid
-
- def getbody(self, json_data=None):
- if json_data is None: json_data = {}
- params = {"product": "4", "ver": "1.1.0", "debug": "1", "appId": "1", "osType": "3", "marketChannel": "tv",
- "sysVer": "11", "time": str(int(time.time())), "packageName": "com.gzsptv.gztvvideo",
- "udid": self.uid, }
- json_data.update(params)
- sorted_json = dict(sorted(json_data.items(), key=lambda item: item[0]))
- text = '&'.join(f"{k}={v}" for k, v in sorted_json.items() if v != '')
- md5_hash = self.md5(f"jI7POOBbmiUZ0lmi{text}D9ShYdN51ksWptpkTu11yenAJu7Zu3cR").upper()
- json_data.update({'sign': md5_hash})
- return json_data
-
- def md5(self, text):
- h = MD5.new()
- h.update(text.encode('utf-8'))
- return h.hexdigest()
-
- def getlist(self, data):
- videos = []
- for i in data:
- if type(i.get('video')) == dict: i = i['video']
- videos.append({
- 'vod_id': f"{i.get('channel_id')}@{i.get('video_id')}",
- 'vod_name': i.get('video_name'),
- 'vod_pic': i.get('cover'),
- 'vod_year': i.get('score'),
- 'vod_remarks': i.get('flag'),
- })
- return videos
-
From 714c0f961bbf8b72115600b7437e3905aab0c867 Mon Sep 17 00:00:00 2001
From: cluntop <85211716+cluntop@users.noreply.github.com>
Date: Sat, 21 Mar 2026 18:07:50 +0800
Subject: [PATCH 03/10] Update Up
---
index.html | 18 ++++--------------
1 file changed, 4 insertions(+), 14 deletions(-)
diff --git a/index.html b/index.html
index 0e86e397f..878a7b5ff 100755
--- a/index.html
+++ b/index.html
@@ -32,23 +32,13 @@
自用 https://clun.top/box.json
FongMi leanback:
- v7a |
- v8a
-
-
- okjack leanback:
- v7a |
- v8a
+ v7a |
+ v8a
FongMi mobile:
- v7a |
- v8a
-
-
- okjack mobile:
- v7a |
- v8a
+ v7a |
+ v8a
From 1210be41f7318864bdca9265993bdd8968386319 Mon Sep 17 00:00:00 2001
From: cluntop <85211716+cluntop@users.noreply.github.com>
Date: Sat, 21 Mar 2026 18:26:24 +0800
Subject: [PATCH 04/10] Update Up
---
.github/workflows/zip.yml | 24 ++++++++++++------------
1 file changed, 12 insertions(+), 12 deletions(-)
diff --git a/.github/workflows/zip.yml b/.github/workflows/zip.yml
index 42346d23f..a6cea6e6c 100755
--- a/.github/workflows/zip.yml
+++ b/.github/workflows/zip.yml
@@ -54,21 +54,21 @@ jobs:
cd ..
rm -rf temp_xiaosa
- - name: Process Source Repo
- run: |
- git clone --depth 1 https://github.com/fish2018/PG.git source-repo
+ # - name: Process Source Repo
+ # run: |
+ # git clone --depth 1 https://github.com/fish2018/PG.git source-repo
- cd source-repo
- ZIP_FILE=$(find . -type f -name "pg.[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]-[0-9][0-9][0-9][0-9].zip" | sort -r | head -n 1)
+ # cd source-repo
+ # ZIP_FILE=$(find . -type f -name "pg.[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]-[0-9][0-9][0-9][0-9].zip" | sort -r | head -n 1)
- if [ -z "$ZIP_FILE" ]; then
- echo "Warning: No matching zip file found in Source Repo."
- else
- echo "Found zip file: $ZIP_FILE"
+ # if [ -z "$ZIP_FILE" ]; then
+ # echo "Warning: No matching zip file found in Source Repo."
+ # else
+ # echo "Found zip file: $ZIP_FILE"
- unzip -o "$ZIP_FILE" -x "README.txt" -d ../target-repo/
- echo "PG zip extracted to target repo."
- fi
+ # unzip -o "$ZIP_FILE" -x "README.txt" -d ../target-repo/
+ # echo "PG zip extracted to target repo."
+ # fi
- name: Commit and push changes
working-directory: target-repo
From 06e814560a07eccb452608ef6f95676f751d2006 Mon Sep 17 00:00:00 2001
From: GitHub Actions Bot
Date: Sat, 21 Mar 2026 18:27:22 +0800
Subject: [PATCH 05/10] Update zip
---
js/xiaosa/api.json | 637 +++++++++-------
js/xiaosa/js/爱奇艺.js | 1386 +++++++++++-----------------------
js/xiaosa/json/aliShare.json | 8 -
js/xiaosa/json/ucShare.json | 9 -
js/xiaosa/py/网络直播.py | 1169 +++++++++++++++++++---------
js/xiaosa/spider.jar | Bin 1573140 -> 1560852 bytes
6 files changed, 1626 insertions(+), 1583 deletions(-)
diff --git a/js/xiaosa/api.json b/js/xiaosa/api.json
index 3c0f7a6ae..31b72f2b0 100755
--- a/js/xiaosa/api.json
+++ b/js/xiaosa/api.json
@@ -48,6 +48,18 @@
"url": "http://v.rbotv.cn"
}
},
+ {
+ "key": "三秋影视",
+ "name": "三秋|APP",
+ "type": 3,
+ "api": "csp_App3Q"
+ },
+ {
+ "key": "坚果影视",
+ "name": "坚果|APP",
+ "type": 3,
+ "api": "csp_AppJg"
+ },
{
"key": "韩圈",
"name": "韩圈|APP",
@@ -66,64 +78,138 @@
"ext": "https://www.nntv.in/api.php/v1.vod"
},
{
- "key": "花柳",
- "name": "花柳|APP",
+ "key": "闪影",
+ "name": "闪影|APP",
+ "type": 3,
+ "api": "csp_AppYsV2",
+ "searchable": 1,
+ "quickSearch": 1,
+ "filterable": 1,
+ "ext": "http://38.47.213.61:41271/mogai_api.php/v1.vod"
+ },
+ {
+ "key": "恋鱼",
+ "name": "恋鱼|APP",
"type": 3,
- "api": "csp_AppFox",
"searchable": 1,
"changeable": 1,
+ "api": "csp_AppFox",
"ext": {
- "host": "http://nico.oiio.fun",
+ "host": "http://103.117.137.33:2443",
"ver": 2
}
},
{
- "key": "麒麟",
- "name": "麒麟|APP",
+ "key": "云播",
+ "name": "云播|APP",
"type": 3,
- "api": "csp_AppFox",
"searchable": 1,
"changeable": 1,
+ "api": "csp_AppFox",
"ext": {
- "host": "https://qh.70qh.top",
- "ver": 2
+ "host": "http://app.hktvyb.cc"
}
},
{
- "key": "搜搜",
- "name": "搜搜|APP",
+ "key": "火猫",
+ "name": "火猫|APP",
"type": 3,
- "api": "csp_AppFox",
"searchable": 1,
"changeable": 1,
- "ext": "https://www.zjcvod.com"
- },
- {
- "key": "火花",
- "name": "火花|APP",
- "type": 3,
"api": "csp_AppFox",
- "searchable": 1,
- "changeable": 1,
"ext": {
- "host": "http://huohua.itcxo.cn"
+ "host": "https://cunchu8.obs.cn-north-4.myhuaweicloud.com/fox.json"
}
},
{
- "key": "顾我",
- "name": "顾我|APP",
+ "key": "云朵",
+ "name": "云朵|APP",
+ "type": 3,
+ "api": "csp_AppGet",
+ "searchable": 1,
+ "changeable": 1,
+ "ext": {
+ "url": "https://yd4kcms.yd4k.top",
+ "dataKey": "Tpmm9FD99lJ8Dexa",
+ "dataIv": "Tpmm9FD99lJ8Dexa"
+ }
+ },
+ {
+ "key": "爱影",
+ "name": "爱影|APP",
"type": 3,
"api": "csp_AppQi",
"searchable": 1,
"changeable": 1,
"ext": {
- "site": "https://daen-1256234123.cos.ap-shanghai.myqcloud.com/MuQi/pgqj.json",
+ "site": "https://aysappto.oss-cn-chengdu.aliyuncs.com/q20.txt",
+ "dataKey": "ada211sdfsff3261",
+ "dataIv": "ada211sdfsff3261",
+ "init": "initV122",
+ "search": "mineInfo",
+ "ua": "okhttp/3.10.0"
+ }
+ },
+ {
+ "key": "星河",
+ "name": "星河|APP",
+ "type": 3,
+ "api": "csp_AppQi",
+ "searchable": 1,
+ "changeable": 1,
+ "ext": {
+ "site": "https://daen-1256234123.cos.ap-shanghai.myqcloud.com/MuQi/mqxhqj.txt",
"dataKey": "kj37zs29q22jk96t",
"dataIv": "kj37zs29q22jk96t",
"init": "initV122",
"ua": "okhttp/3.10.0"
}
},
+ {
+ "key": "金牌",
+ "name": "金牌|APP",
+ "type": 3,
+ "api": "csp_AppQi",
+ "searchable": 1,
+ "changeable": 1,
+ "ext": {
+ "url": "https://qj3.ggtvb.cc",
+ "dataKey": "eecbio48dsq13kkk",
+ "dataIv": "eecbio48dsq13kkk",
+ "search": "searchList4",
+ "init": "initV122",
+ "ua": "okhttp/3.10.0"
+ }
+ },
+ {
+ "key": "奇奇",
+ "name": "奇奇|APP",
+ "type": 3,
+ "api": "csp_AppQi",
+ "searchable": 1,
+ "changeable": 1,
+ "ext": {
+ "url": "http://110.42.67.221:8009",
+ "dataKey": "123456789abcdefg",
+ "dataIv": "123456789abcdefg",
+ "init": "initV122",
+ "ua": "okhttp/3.10.0"
+ }
+ },
+ {
+ "key": "老鹰",
+ "name": "老鹰|APP",
+ "type": 3,
+ "api": "csp_AppQi",
+ "searchable": 1,
+ "changeable": 1,
+ "ext": {
+ "site": "https://maotouyinghubei.oss-cn-wuhan-lr.aliyuncs.com/maotouyinghb.txt",
+ "dataKey": "zxPtEUDGVllIUhDB",
+ "dataIv": "zxPtEUDGVllIUhDB",
+ "ua": "okhttp/3.10.0"
+ }
+ },
{
"key": "爱盈",
"name": "爱盈|APP",
@@ -140,52 +226,35 @@
}
},
{
- "key": "金牌",
- "name": "金牌|APP",
+ "key": "花猪",
+ "name": "花猪|APP",
"type": 3,
"api": "csp_AppQi",
"searchable": 1,
"changeable": 1,
"ext": {
- "site": "https://dtqj.ggtvb.cc/dtjp.txt",
- "dataKey": "eecbio48dsq131ee",
- "dataIv": "eecbio48dsq131ee",
- "search": "searchList4",
+ "site": "https://tiantangyoulu.oss-cn-beijing.aliyuncs.com/wenxintishi.txt",
+ "dataKey": "h2t8fjo964j2sl6a",
+ "dataIv": "h2t8fjo964j2sl6a",
+ "ua": "okhttp/3.10.0"
+ }
+ },
+ {
+ "key": "橘子",
+ "name": "橘子|APP",
+ "type": 3,
+ "api": "csp_AppQi",
+ "searchable": 1,
+ "changeable": 1,
+ "ext": {
+ "site": "https://juziapp-1319209748.cos.ap-chengdu.myqcloud.com/juzi.txt",
+ "dataKey": "jasaFBcdV3zrUDf2",
+ "dataIv": "jasaFBcdV3zrUDf2",
"version": "305",
"init": "initV122",
"ua": "okhttp/3.10.0"
}
},
- {
- "key": "小猪",
- "name": "小猪|APP",
- "type": 3,
- "api": "csp_AppQi",
- "searchable": 1,
- "changeable": 1,
- "ext": {
- "site": "https://tiantangwulu.oss-cn-shanghai.aliyuncs.com/zhuzhuxia.txt",
- "dataKey": "j8sr6d93yp49db3p",
- "dataIv": "j8sr6d93yp49db3p",
- "init": "initV122",
- "ua": "okhttp/3.10.0"
- }
- },
- {
- "key": "鲸鱼",
- "name": "鲸鱼|APP",
- "type": 3,
- "api": "csp_AppQi",
- "searchable": 1,
- "changeable": 1,
- "ext": {
- "site": "https://jingyu4k-1312635929.cos.ap-nanjing.myqcloud.com/juyu3.json",
- "dataKey": "AAdgrdghjfgsABC1",
- "dataIv": "AAdgrdghjfgsABC1",
- "init": "initV122",
- "ua": "okhttp/3.10.0"
- }
- },
{
"key": "优兔",
"name": "优兔|APP",
@@ -196,173 +265,109 @@
"ext": {
"site": "https://uututv-1319209748.cos.ap-shanghai.myqcloud.com/uutuv4.txt",
"dataKey": "UrWKPnmQWJA8AQzd",
- "dataIv": "UrWKPnmQWJA8AQzd"
+ "dataIv": "UrWKPnmQWJA8AQzd",
+ "ua": "okhttp/3.10.0"
}
},
{
- "key": "小鸟",
- "name": "小鸟|APP",
+ "key": "蓝鹰",
+ "name": "蓝鹰|APP",
+ "type": 3,
+ "api": "csp_AppQi",
+ "searchable": 1,
+ "changeable": 1,
+ "ext": {
+ "site": "https://lanyinghz.oss-cn-hangzhou.aliyuncs.com/lanyingxmy.txt",
+ "dataKey": "ca94b06ca359d80e",
+ "dataIv": "ca94b06ca359d80e",
+ "init": "initV120",
+ "ua": "okhttp/3.10.0"
+ }
+ },
+ {
+ "key": "小羊",
+ "name": "小羊|APP",
+ "type": 3,
+ "api": "csp_AppQi",
+ "ext": {
+ "url": "https://qjappcms410.xy4k.com",
+ "dataKey": "mC6kG4mI1uM8tS4o",
+ "dataIv": "mC6kG4mI1uM8tS4o"
+ }
+ },
+ {
+ "key": "不错",
+ "name": "不错|APP",
"type": 3,
"searchable": 1,
"changeable": 1,
"api": "csp_AppGet",
"ext": {
- "url": "http://154.222.26.58:7788",
- "dataKey": "guodan2004031600",
- "dataIv": "guodan2004031600",
- "token": "fd035ffa03d62775add295bfbb7d99c131e0bb49bb9451309b0ffc4df1631146"
+ "url": "https://zbc4kmcs.zbc4k.app",
+ "dataKey": "vE4kR7cF6jS6jH7a",
+ "dataIv": "vE4kR7cF6jS6jH7a"
}
},
{
- "key": "方源",
- "name": "方源|APP",
+ "key": "星空",
+ "name": "星空|APP",
"type": 3,
"searchable": 1,
"changeable": 1,
"api": "csp_AppGet",
"ext": {
- "site": "https://fyys9.fytd.top/1.txt",
- "dataKey": "0ef6fc92a64b4e74",
- "dataIv": "0ef6fc92a64b4e74"
+ "url": "http://xkos1.xkgzs.xyz",
+ "dataKey": "77jkcdvdodfcdkjk",
+ "dataIv": "77jkcdvdodfcdkjk"
}
},
{
- "key": "七月",
- "name": "七月|APP",
+ "key": "火狐",
+ "name": "火狐|APP",
"type": 3,
+ "api": "csp_AppGet",
"searchable": 1,
"changeable": 1,
- "api": "csp_AppGet",
"ext": {
- "site": "https://99.jl8.top/1.txt",
- "dataKey": "xnybssspqtwotuwj",
- "dataIv": "xnybssspqtwotuwj"
+ "url": "http://huohu.yihn.cc",
+ "dataKey": "huohushipingetap",
+ "dataIv": "huohushipingetap"
}
},
{
- "key": "芬奇",
- "name": "芬奇|APP",
+ "key": "秒看",
+ "name": "秒看|APP",
"type": 3,
+ "api": "csp_AppGet",
"searchable": 1,
"changeable": 1,
- "api": "csp_AppGet",
"ext": {
- "site": "https://wsapi.dafenqi.mom/yuming.txt",
- "dataKey": "bH5mI8iK0tK7aQ5x",
- "dataIv": "bH5mI8iK0tK7aQ5x"
+ "site": "https://mk1080.top/get.txt",
+ "dataKey": "c60d88b2eep53za8",
+ "dataIv": "c60d88b2eep53za8",
+ "token": "4181e508e7a17657d6a6246e70b1b13553e5ae9d8d287dc47000fb2df638dffa"
}
},
{
- "key": "缘梦",
- "name": "缘梦|APP",
+ "key": "仓鼠",
+ "name": "仓鼠|APP",
"type": 3,
+ "api": "csp_AppGet",
"searchable": 1,
"changeable": 1,
- "api": "csp_AppGet",
"ext": {
- "url": "http://165.99.42.137:5432",
- "dataKey": "1234567890987654",
- "dataIv": "1234567890987654"
- }
- },
- {
- "key": "王子",
- "name": "王子|APP",
- "type": 3,
- "searchable": 1,
- "changeable": 1,
- "api": "csp_AppGet",
- "ext": {
- "url": "https://app.95112475.xyz",
- "dataKey": "5a9w6x58dsq6z3a6",
- "dataIv": "5a9w6x58dsq6z3a6"
- }
- },
- {
- "key": "小猫",
- "name": "小猫|APP",
- "type": 3,
- "searchable": 1,
- "changeable": 1,
- "api": "csp_AppGet",
- "ext": {
- "site": "http://xywlkj.oss-cn-beijing.aliyuncs.com/wp-content/uploads/2024/12/1.txt",
- "dataKey": "xmyxmyxywlkjxywl",
- "dataIv": "xmyxmyxywlkjxywl"
- }
- },
- {
- "key": "小白",
- "name": "小白|APP",
- "type": 3,
- "searchable": 1,
- "changeable": 1,
- "api": "csp_AppGet",
- "ext": {
- "url": "https://uutu.efjhl.cn",
- "dataKey": "uXVVRRuaPnjEfsX5",
- "dataIv": "uXVVRRuaPnjEfsX5"
- }
- },
- {
- "key": "气球",
- "name": "气球|APP",
- "type": 3,
- "searchable": 1,
- "changeable": 1,
- "api": "csp_AppGet",
- "ext": {
- "url": "https://vv.229d.cn",
- "dataKey": "8888888888888888",
- "dataIv": "8888888888888888"
- }
- },
- {
- "key": "白鸽",
- "name": "白鸽|APP",
- "type": 3,
- "searchable": 1,
- "changeable": 1,
- "api": "csp_AppGet",
- "ext": {
- "url": "https://cy.baige.asia",
- "dataKey": "599D0FE5178642FD",
- "dataIv": "599D0FE5178642FD"
- }
- },
- {
- "key": "魔方",
- "name": "魔方|APP",
- "type": 3,
- "searchable": 1,
- "changeable": 1,
- "api": "csp_AppGet",
- "ext": {
- "url": "http://www.613mf4k12.top",
- "dataKey": "1234567887654321",
- "dataIv": "1234567887654321"
- }
- },
- {
- "key": "瑞奇",
- "name": "瑞奇|APP",
- "type": 3,
- "searchable": 1,
- "changeable": 1,
- "api": "csp_AppGet",
- "ext": {
- "url": "http://rqxk.gdata.fun",
- "dataKey": "yangruiqiYsapp00",
- "dataIv": "yangruiqiYsapp00"
+ "url": "https://cs450appcms.cs4k.top",
+ "dataKey": "cD7wZ7iY6qN3sU1z",
+ "dataIv": "cD7wZ7iY6qN3sU1z"
}
},
{
"key": "茉莉",
"name": "茉莉|APP",
"type": 3,
+ "api": "csp_AppGet",
"searchable": 1,
"changeable": 1,
- "api": "csp_AppGet",
"ext": {
"site": "https://gitee.com/wmmoliill/wimg/raw/master/img/bk/9.txt",
"dataKey": "88689667dce61725",
@@ -370,12 +375,51 @@
}
},
{
- "key": "驿站",
- "name": "驿站丨APP",
+ "key": "段友",
+ "name": "段友|APP",
"type": 3,
+ "api": "csp_AppGet",
"searchable": 1,
"changeable": 1,
+ "ext": {
+ "url": "https://shangjihuoke.com",
+ "dataKey": "8E2DC386FD452D05",
+ "dataIv": "8E2DC386FD452D05"
+ }
+ },
+ {
+ "key": "黑猫",
+ "name": "黑猫|APP",
+ "type": 3,
"api": "csp_AppGet",
+ "searchable": 1,
+ "changeable": 1,
+ "ext": {
+ "url": "http://app1-0-0.87333.cc",
+ "dataKey": "VwsHxkCViDXEExWa",
+ "dataIv": "VwsHxkCViDXEExWa"
+ }
+ },
+ {
+ "key": "灵虎",
+ "name": "灵虎|APP",
+ "type": 3,
+ "api": "csp_AppGet",
+ "searchable": 1,
+ "changeable": 1,
+ "ext": {
+ "site": "https://bind.315999.xyz/89.txt",
+ "dataKey": "#getapp@TMD@2025",
+ "dataIv": "#getapp@TMD@2025"
+ }
+ },
+ {
+ "key": "驿站",
+ "name": "驿站|APP",
+ "type": 3,
+ "api": "csp_AppGet",
+ "searchable": 1,
+ "changeable": 1,
"ext": {
"site": "https://dyyztvappapigoodgx.68.gy:12689/ciwk28vu38io8/apiurl.txt",
"dataKey": "dyyztvapiappyyds",
@@ -383,51 +427,29 @@
}
},
{
- "key": "蝴蝶",
- "name": "蝴蝶|APP",
+ "key": "七壹",
+ "name": "七壹|APP",
"type": 3,
- "api": "csp_AppNox",
+ "api": "csp_AppGet",
+ "searchable": 1,
+ "changeable": 1,
"ext": {
- "url": "http://111.170.7.114:8081",
- "header": {
- "content-type": "application/json",
- "x-app-signature": "1B:20:A2:57:B9:EB:EB:4E:09:0E:B3:5C:11:62:9E:B6:76:51:98:5A:31:68:05:58:E2:BF:E7:62:75:86:BA:51",
- "x-app-package": "com.muyuesg.app",
- "x-app-version-code": "7",
- "x-app-version-name": "0.0.7"
- }
+ "url": "https://qiyiys.cc",
+ "dataKey": "45452893929B40D9",
+ "dataIv": "45452893929B40D9"
}
},
{
- "key": "片喵",
- "name": "片喵|APP",
+ "key": "瑞奇",
+ "name": "瑞奇|APP",
"type": 3,
- "api": "csp_AppNox",
+ "api": "csp_AppGet",
+ "searchable": 1,
+ "changeable": 1,
"ext": {
- "url": "https://svip.2video.cc",
- "header": {
- "content-type": "application/json",
- "x-app-signature": "70:DF:B1:2A:AE:C3:E3:73:6E:23:0F:67:B9:3B:C5:63:2D:EA:2A:2C:9E:9D:52:82:1D:3F:3C:3C:B9:10:9E:EE",
- "x-app-package": "com.ds.wlss",
- "x-app-version-code": "56",
- "x-app-version-name": "1.2.6"
- }
- }
- },
- {
- "key": "豆丁",
- "name": "豆丁|APP",
- "type": 3,
- "api": "csp_AppNox",
- "ext": {
- "url": "http://172.247.44.102:9924",
- "header": {
- "content-type": "application/json",
- "x-app-signature": "99:CA:F0:76:5A:92:1F:00:1A:60:96:2C:BB:AC:01:51:A6:4E:C6:28:EB:67:F5:82:9C:2C:78:66:91:C3:60:56",
- "x-app-package": "com.ddsp.app",
- "x-app-version-code": "2",
- "x-app-version-name": "3.0.9"
- }
+ "url": "http://rqxk.gdata.fun",
+ "dataKey": "yangruiqiYsapp00",
+ "dataIv": "yangruiqiYsapp00"
}
},
{
@@ -493,9 +515,11 @@
"changeable": 1,
"ext": {
"site": [
- "https://www.wogg.one",
+ "https://wogg.xxooo.cf",
+ "https://woggpan.888484.xyz",
"https://wogg.333232.xyz",
- "https://woggpan.888484.xyz"
+ "http://woggpan.xxooo.cf",
+ "https://www.wogg.one"
]
},
"timeout": 60
@@ -628,10 +652,11 @@
"changeable": 1,
"ext": {
"site": [
- "https://xhww.net",
- "https://erxiaofn.site",
- "https://erxiaofn.click",
- "https://www.xhww.net"
+ "https://www.2xiaopan.top",
+ "https://2xiaopan.top",
+ "https://www.erxiaozhan.top",
+ "https://www.2xiaozhan.top",
+ "https://wexwp.cc"
]
},
"timeout": 60
@@ -707,9 +732,8 @@
"type": 3,
"api": "csp_PanWebShareCloudLJ",
"searchable": 1,
- "quickSearch": 1,
- "filterable": 1,
- "changeable": 1,
+ "quickSearch": 0,
+ "filterable": 0,
"style": {
"type": "list",
"ratio": 1.433
@@ -730,9 +754,8 @@
"type": 3,
"api": "csp_PanWebShareCloudHM",
"searchable": 1,
- "quickSearch": 1,
- "filterable": 1,
- "changeable": 1,
+ "quickSearch": 0,
+ "filterable": 0,
"style": {
"type": "list",
"ratio": 1.433
@@ -752,9 +775,8 @@
"type": 3,
"api": "csp_PanWebShareCloudKF",
"searchable": 1,
- "quickSearch": 1,
- "filterable": 1,
- "changeable": 1,
+ "quickSearch": 0,
+ "filterable": 0,
"style": {
"type": "list",
"ratio": 1.433
@@ -773,9 +795,8 @@
"type": 3,
"api": "csp_PanWebShareCloudPT",
"searchable": 1,
- "quickSearch": 1,
- "filterable": 1,
- "changeable": 1,
+ "quickSearch": 0,
+ "filterable": 0,
"style": {
"type": "list"
},
@@ -787,9 +808,8 @@
"type": 3,
"api": "csp_PanWebShareCloud123",
"searchable": 1,
- "quickSearch": 1,
- "filterable": 1,
- "changeable": 1,
+ "quickSearch": 0,
+ "filterable": 0,
"style": {
"type": "list",
"ratio": 1.433
@@ -807,6 +827,9 @@
"name": "人人|4K",
"type": 3,
"api": "csp_RenRen",
+ "searchable": 1,
+ "quickSearch": 0,
+ "filterable": 0,
"timeout": 60
},
{
@@ -814,6 +837,9 @@
"name": "即刻|4K",
"type": 3,
"api": "csp_Jike",
+ "searchable": 1,
+ "quickSearch": 0,
+ "filterable": 0,
"style": {
"type": "list"
},
@@ -824,6 +850,9 @@
"name": "双星|4K",
"type": 3,
"api": "csp_ShuangXing",
+ "searchable": 1,
+ "quickSearch": 0,
+ "filterable": 0,
"style": {
"type": "list"
},
@@ -837,7 +866,8 @@
"searchable": 1,
"changeable": 1,
"quickSearch": 1,
- "filterable": 1
+ "filterable": 1,
+ "genre": "shortdrama"
},
{
"key": "锦鲤短剧",
@@ -847,7 +877,8 @@
"searchable": 1,
"changeable": 1,
"quickSearch": 1,
- "filterable": 1
+ "filterable": 1,
+ "genre": "shortdrama"
},
{
"key": "星阁短剧",
@@ -857,7 +888,19 @@
"searchable": 1,
"changeable": 1,
"quickSearch": 1,
- "filterable": 1
+ "filterable": 1,
+ "genre": "shortdrama"
+ },
+ {
+ "key": "碎片短剧",
+ "name": "碎片|短剧",
+ "type": 3,
+ "api": "csp_SuipianDJ",
+ "searchable": 1,
+ "changeable": 1,
+ "quickSearch": 1,
+ "filterable": 1,
+ "genre": "shortdrama"
},
{
"key": "星芽短剧",
@@ -867,7 +910,8 @@
"searchable": 1,
"changeable": 1,
"quickSearch": 1,
- "filterable": 1
+ "filterable": 1,
+ "genre": "shortdrama"
},
{
"key": "剧王短剧",
@@ -877,7 +921,8 @@
"searchable": 1,
"changeable": 1,
"quickSearch": 1,
- "filterable": 1
+ "filterable": 1,
+ "genre": "shortdrama"
},
{
"key": "厂长影视",
@@ -903,12 +948,6 @@
"api": "csp_Tvyb",
"ext": "http://www.tvyb03.com"
},
- {
- "key": "苹果影视",
- "name": "苹果|影视",
- "type": 3,
- "api": "csp_LiteApple"
- },
{
"key": "饺子影视",
"name": "饺子|影视",
@@ -972,6 +1011,17 @@
"api": "csp_XBPQ",
"ext": "./XBPQ/永乐影视.json"
},
+ {
+ "key": "星辰影视",
+ "name": "星辰|影视",
+ "type": 3,
+ "api": "csp_XBPQ",
+ "ext": {
+ "分类url": "https://www.sdconglin.com/show/{cateId}-{area}-{by}-{class}-{lang}-{letter}---{catePg}---{year}.html",
+ "分类": "电视剧$2#短剧$36#电影$1#综艺$3#动漫$4",
+ "简介": "display: none;\">&&<"
+ }
+ },
{
"key": "剧圈影视",
"name": "剧圈|影视",
@@ -1032,18 +1082,6 @@
"parsesKey": "aassddwwxxllsx1x"
}
},
- {
- "key": "卡卡动漫",
- "name": "卡卡|动漫",
- "type": 3,
- "searchable": 1,
- "api": "csp_AppGet",
- "ext": {
- "url": "http://154.201.90.53:8002",
- "dataKey": "123456789abcdefg",
- "dataIv": "123456789abcdefg"
- }
- },
{
"key": "丫丫动漫",
"name": "丫丫|动漫",
@@ -1056,18 +1094,6 @@
"dataIv": "qkxnwkfjwpcnwycl"
}
},
- {
- "key": "冬日动漫",
- "name": "冬日丨动漫",
- "type": 3,
- "searchable": 1,
- "api": "csp_AppGet",
- "ext": {
- "url": "http://www.drdm.fun",
- "dataKey": "qE2nD0rL1lH4uP9r",
- "dataIv": "qE2nD0rL1lH4uP9r"
- }
- },
{
"key": "方舟动漫",
"name": "方舟丨动漫",
@@ -1075,7 +1101,7 @@
"searchable": 1,
"api": "csp_AppGet",
"ext": {
- "url": "https://www.cyfz.vip",
+ "url": "https://www.cyfz.top",
"dataKey": "e72cdfd629e8895d",
"dataIv": "e72cdfd629e8895d"
}
@@ -1300,8 +1326,7 @@
"style": {
"type": "list",
"ratio": 1.433
- },
- "ext": "./json/quarkShare.json"
+ }
},
{
"key": "UC云盘",
@@ -1314,8 +1339,7 @@
"style": {
"type": "list",
"ratio": 1.433
- },
- "ext": "./json/ucShare.json"
+ }
},
{
"key": "百度云盘",
@@ -1355,6 +1379,9 @@
"name": "百酷|搜索",
"type": 3,
"api": "csp_Baiku",
+ "searchable": 1,
+ "quickSearch": 0,
+ "filterable": 0,
"timeout": 60
},
{
@@ -1362,6 +1389,9 @@
"name": "米搜|搜索",
"type": 3,
"api": "csp_MiSou",
+ "searchable": 1,
+ "quickSearch": 0,
+ "filterable": 0,
"timeout": 60
},
{
@@ -1369,6 +1399,9 @@
"name": "酷乐|搜索",
"type": 3,
"api": "csp_KuLe",
+ "searchable": 1,
+ "quickSearch": 0,
+ "filterable": 0,
"timeout": 60
},
{
@@ -1376,6 +1409,9 @@
"name": "鬼鬼|搜索",
"type": 3,
"api": "csp_GuiGui",
+ "searchable": 1,
+ "quickSearch": 0,
+ "filterable": 0,
"timeout": 60
},
{
@@ -1383,6 +1419,9 @@
"name": "混合|搜索",
"type": 3,
"api": "csp_HunHePan",
+ "searchable": 1,
+ "quickSearch": 0,
+ "filterable": 0,
"timeout": 60
},
{
@@ -1390,6 +1429,9 @@
"name": "兄弟|搜索",
"type": 3,
"api": "csp_XiongDiPan",
+ "searchable": 1,
+ "quickSearch": 0,
+ "filterable": 0,
"timeout": 60
},
{
@@ -1397,6 +1439,9 @@
"name": "天翼|搜索",
"type": 3,
"api": "csp_TianYiSo",
+ "searchable": 1,
+ "quickSearch": 0,
+ "filterable": 0,
"timeout": 60
},
{
@@ -1404,6 +1449,9 @@
"name": "趣盘|搜索",
"type": 3,
"api": "csp_QuPanSo",
+ "searchable": 1,
+ "quickSearch": 0,
+ "filterable": 0,
"timeout": 60
},
{
@@ -1429,6 +1477,15 @@
"type": "list"
}
},
+ {
+ "key": "919体育",
+ "name": "919|体育",
+ "type": 3,
+ "api": "csp_919Tiyu",
+ "style": {
+ "type": "list"
+ }
+ },
{
"key": "爱听音乐",
"name": "爱听|音乐",
@@ -1705,7 +1762,17 @@
"url": "https://jx.xmflv.com/?url=",
"ext": {
"header": {
- "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36 Edg/110.0.1587.57"
+ "user-agent": "Mozilla/5.0 (Linux; Android 13; V2049A Build/TP1A.220624.014; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/116.0.0.0 Mobile Safari/537.36"
+ }
+ }
+ },
+ {
+ "name": "云解",
+ "type": 0,
+ "url": "https://yparse.ik9.cc/index.php?url=",
+ "ext": {
+ "header": {
+ "user-agent": "Mozilla/5.0 (Linux; Android 13; V2049A Build/TP1A.220624.014; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/116.0.0.0 Mobile Safari/537.36"
}
}
},
@@ -1715,7 +1782,7 @@
"url": "https://jx.xymp4.cc/?url=",
"ext": {
"header": {
- "user-agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36 Edg/134.0.3124.68"
+ "user-agent": "Mozilla/5.0 (Linux; Android 13; V2049A Build/TP1A.220624.014; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/116.0.0.0 Mobile Safari/537.36"
}
}
},
diff --git a/js/xiaosa/js/爱奇艺.js b/js/xiaosa/js/爱奇艺.js
index 661475641..de9837a57 100755
--- a/js/xiaosa/js/爱奇艺.js
+++ b/js/xiaosa/js/爱奇艺.js
@@ -2,7 +2,6 @@ var rule = {
title: '奇珍异兽[官]',
host: 'https://www.iqiyi.com',
homeUrl: '',
- // detailUrl:'https://pcw-api.iqiyi.com/albums/album/avlistinfo?aid=fyid&size=2000&page=1',
detailUrl: 'https://pcw-api.iqiyi.com/video/video/videoinfowithuser/fyid?agent_type=1&authcookie=&subkey=fyid&subscribe=1',
searchUrl: 'https://search.video.iqiyi.com/o?if=html5&key=**&pageNum=fypage&pos=1&pageSize=24&site=iqiyi',
searchable: 2,
@@ -25,76 +24,57 @@ var rule = {
'n': '新上线',
'v': 4
}]
- }, {
- 'key': 'year',
- 'name': '全部年份',
- 'value': [{
- 'n': '全部',
- 'v': ''
- }, {
- "n": "2026",
- "v": 2026
- }, {
- "n": "2025",
- "v": 2025
- }, {
- "n": "2024",
- "v": 2024
- }, {
- 'n': '2023',
- 'v': 2023
- }, {
- 'n': '2022',
- 'v': 2022
- }, {
- 'n': '2021',
- 'v': 2021
- }, {
- 'n': '2020',
- 'v': 2020
- }, {
- 'n': '2019',
- 'v': 2019
- }, {
- 'n': '2018',
- 'v': 2018
- }, {
- 'n': '2017',
- 'v': 2017
- }, {
- 'n': '2016-2011',
- 'v': '2011_2016'
- }, {
- 'n': '2010-2000',
- 'v': '2000_2010'
- }, {
- 'n': '90年代',
- 'v': '1990_1999'
- }, {
- 'n': '80年代',
- 'v': '1980_1989'
- }, {
- 'n': '更早',
- 'v': '1964_1979'
- }]
- }, {
- 'key': 'is_purchase',
- 'name': '全部资费',
- 'value': [{
- 'n': '全部',
- 'v': ''
- }, {
- 'n': '免费',
- 'v': 0
- }, {
- 'n': '会员',
- 'v': 1
- }, {
- 'n': '付费',
- 'v': 2
- }]
}, {
'key': 'three_category_id',
+ 'name': '类型',
+ 'value': [{
+ 'n': '全部',
+ 'v': ''
+ }, {
+ 'n': '喜剧',
+ 'v': 8
+ }, {
+ 'n': '爱情',
+ 'v': 6
+ }, {
+ 'n': '动作',
+ 'v': 11
+ }, {
+ 'n': '悬疑',
+ 'v': 289
+ }, {
+ 'n': '科幻',
+ 'v': 9
+ }, {
+ 'n': '恐怖',
+ 'v': 10
+ }, {
+ 'n': '犯罪',
+ 'v': 291
+ }, {
+ 'n': '战争',
+ 'v': 7
+ }, {
+ 'n': '动画',
+ 'v': 12
+ }, {
+ 'n': '奇幻',
+ 'v': 1284
+ }, {
+ 'n': '枪战',
+ 'v': 131
+ }, {
+ 'n': '惊悚',
+ 'v': 128
+ }, {
+ 'n': '青春',
+ 'v': 130
+ }, {
+ 'n': '家庭',
+ 'v': 27356
+ }]
+ }, {
+ 'key': 'region',
'name': '地区',
'value': [{
'n': '全部',
@@ -128,75 +108,72 @@ var rule = {
'v': 5
}]
}, {
- 'key': '18001',
- 'name': '类型',
+ 'key': 'year',
+ 'name': '全部年份',
'value': [{
'n': '全部',
'v': ''
}, {
- 'n': '喜剧',
- 'v': 8
+ "n": "2026",
+ "v": 2026
}, {
- 'n': '爱情',
- 'v': 6
+ "n": "2025",
+ "v": 2025
}, {
- 'n': '动作',
- 'v': 11
+ "n": "2024",
+ "v": 2024
}, {
- 'n': '枪战',
- 'v': 131
+ 'n': '2023',
+ 'v': 2023
}, {
- 'n': '犯罪',
- 'v': 291
+ 'n': '2022',
+ 'v': 2022
}, {
- 'n': '惊悚',
- 'v': 128
+ 'n': '2021',
+ 'v': 2021
}, {
- 'n': '恐怖',
- 'v': 10
+ 'n': '2020',
+ 'v': 2020
}, {
- 'n': '悬疑',
- 'v': 289
+ 'n': '2019',
+ 'v': 2019
}, {
- 'n': '动画',
- 'v': 12
+ 'n': '2018',
+ 'v': 2018
}, {
- 'n': '家庭',
- 'v': 27356
+ 'n': '2017',
+ 'v': 2017
}, {
- 'n': '奇幻',
- 'v': 1284
+ 'n': '2016-2011',
+ 'v': '2011_2016'
}, {
- 'n': '魔幻',
- 'v': 129
+ 'n': '2010-2000',
+ 'v': '2000_2010'
}, {
- 'n': '科幻',
- 'v': 9
+ 'n': '90年代',
+ 'v': '1990_1999'
}, {
- 'n': '战争',
- 'v': 7
+ 'n': '80年代',
+ 'v': '1980_1989'
}, {
- 'n': '青春',
- 'v': 130
+ 'n': '更早',
+ 'v': '1964_1979'
}]
}, {
- 'key': '27396',
- 'name': '规格',
+ 'key': 'is_purchase',
+ 'name': '全部资费',
'value': [{
'n': '全部',
'v': ''
}, {
- 'n': '巨制',
- 'v': 27397
+ 'n': '免费',
+ 'v': 0
}, {
- 'n': '院线',
- 'v': 27815
+ 'n': '会员',
+ 'v': 1
}, {
- 'n': '独播',
- 'v': 30149
- }, {
- 'n': '网络电影',
- 'v': 27401
+ 'n': '付费',
+ 'v': 2
}]
}],
'2': [{
@@ -215,6 +192,92 @@ var rule = {
'n': '新上线',
'v': 4
}]
+ }, {
+ 'key': 'three_category_id',
+ 'name': '类型',
+ 'value': [{
+ 'n': '全部',
+ 'v': ''
+ }, {
+ 'n': '古装',
+ 'v': 24
+ }, {
+ 'n': '言情',
+ 'v': 20
+ }, {
+ 'n': '都市',
+ 'v': 24064
+ }, {
+ 'n': '悬疑',
+ 'v': 32
+ }, {
+ 'n': '武侠',
+ 'v': 23
+ }, {
+ 'n': '家庭',
+ 'v': 1654
+ }, {
+ 'n': '喜剧',
+ 'v': 135
+ }, {
+ 'n': '战争',
+ 'v': 27916
+ }, {
+ 'n': '军旅',
+ 'v': 1655
+ }, {
+ 'n': '谍战',
+ 'v': 290
+ }, {
+ 'n': '偶像',
+ 'v': 30
+ }, {
+ 'n': '青春',
+ 'v': 1653
+ }, {
+ 'n': '罪案',
+ 'v': 149
+ }, {
+ 'n': '历史',
+ 'v': 21
+ }, {
+ 'n': '年代',
+ 'v': 27
+ }, {
+ 'n': '科幻',
+ 'v': 34
+ }, {
+ 'n': '奇幻',
+ 'v': 27881
+ }, {
+ 'n': '剧情',
+ 'v': 24063
+ }, {
+ 'n': '农村',
+ 'v': 29
+ }, {
+ 'n': '宫廷',
+ 'v': 139
+ }, {
+ 'n': '商战',
+ 'v': 140
+ }]
+ }, {
+ 'key': 'region',
+ 'name': '地区',
+ 'value': [{
+ 'n': '全部',
+ 'v': ''
+ }, {
+ 'n': '内地',
+ 'v': 15
+ }, {
+ 'n': '中国台湾',
+ 'v': 1117
+ }, {
+ 'n': '美国',
+ 'v': 18
+ }]
}, {
'key': 'year',
'name': '全部年份',
@@ -283,125 +346,6 @@ var rule = {
'n': '付费',
'v': 2
}]
- }, {
- 'key': 'three_category_id',
- 'name': '地区',
- 'value': [{
- 'n': '全部',
- 'v': ''
- }, {
- 'n': '内地',
- 'v': 15
- }, {
- 'n': '港剧',
- 'v': 16
- }, {
- 'n': '韩剧',
- 'v': 17
- }, {
- 'n': '美剧',
- 'v': 18
- }, {
- 'n': '日剧',
- 'v': 309
- }, {
- 'n': '泰剧',
- 'v': 1114
- }, {
- 'n': '台湾地区',
- 'v': 1117
- }, {
- 'n': '英剧',
- 'v': 28916
- }, {
- 'n': '其它',
- 'v': 19
- }]
- }, {
- 'key': '18003',
- 'name': '类型',
- 'value': [{
- 'n': '全部',
- 'v': ''
- }, {
- 'n': '自制',
- 'v': 11992
- }, {
- 'n': '古装',
- 'v': 24
- }, {
- 'n': '言情',
- 'v': 20
- }, {
- 'n': '武侠',
- 'v': 23
- }, {
- 'n': '偶像',
- 'v': 30
- }, {
- 'n': '家庭',
- 'v': 1654
- }, {
- 'n': '青春',
- 'v': 1653
- }, {
- 'n': '都市',
- 'v': 24064
- }, {
- 'n': '喜剧',
- 'v': 135
- }, {
- 'n': '战争',
- 'v': 27916
- }, {
- 'n': '军旅',
- 'v': 1655
- }, {
- 'n': '谍战',
- 'v': 290
- }, {
- 'n': '悬疑',
- 'v': 32
- }, {
- 'n': '罪案',
- 'v': 149
- }, {
- 'n': '穿越',
- 'v': 148
- }, {
- 'n': '宫廷',
- 'v': 139
- }, {
- 'n': '历史',
- 'v': 21
- }, {
- 'n': '神话',
- 'v': 145
- }, {
- 'n': '科幻',
- 'v': 34
- }, {
- 'n': '年代',
- 'v': 27
- }, {
- 'n': '农村',
- 'v': 29
- }, {
- 'n': '商战',
- 'v': 140
- }, {
- 'n': '剧情',
- 'v': 24063
- }, {
- 'n': '奇幻',
- 'v': 27881
- }, {
- 'n': '网剧',
- 'v': 24065
- }, {
- 'n': '竖短片',
- 'v': 32839
- }]
}],
'3': [{
'key': 'mode',
@@ -419,6 +363,50 @@ var rule = {
'n': '新上线',
'v': 4
}]
+ }, {
+ 'key': 'three_category_id',
+ 'name': '类型',
+ 'value': [{
+ 'n': '全部',
+ 'v': ''
+ }, {
+ 'n': '人文',
+ 'v': 70
+ }, {
+ 'n': '历史',
+ 'v': 74
+ }, {
+ 'n': '军事',
+ 'v': 72
+ }, {
+ 'n': '自然',
+ 'v': 33933
+ }, {
+ 'n': '探险',
+ 'v': 73
+ }, {
+ 'n': '社会',
+ 'v': 71
+ }, {
+ 'n': '美食',
+ 'v': 33908
+ }, {
+ 'n': '科技',
+ 'v': 28119
+ }]
+ }, {
+ 'key': 'region',
+ 'name': '地区',
+ 'value': [{
+ 'n': '全部',
+ 'v': ''
+ }, {
+ 'n': '国内',
+ 'v': 20323
+ }, {
+ 'n': '国外',
+ 'v': 20324
+ }]
}, {
'key': 'year',
'name': '全部年份',
@@ -487,152 +475,6 @@ var rule = {
'n': '付费',
'v': 2
}]
- }, {
- 'key': 'three_category_id',
- 'name': '地区',
- 'value': [{
- 'n': '全部',
- 'v': ''
- }, {
- 'n': '国内',
- 'v': 20323
- }, {
- 'n': '国外',
- 'v': 20324
- }]
- }, {
- 'key': '18004',
- 'name': '类型',
- 'value': [{
- 'n': '全部',
- 'v': ''
- }, {
- 'n': '人文',
- 'v': 70
- }, {
- 'n': '美食',
- 'v': 33908
- }, {
- 'n': '医疗',
- 'v': 33924
- }, {
- 'n': '自然',
- 'v': 33933
- }, {
- 'n': '萌宠',
- 'v': 33945
- }, {
- 'n': '财经',
- 'v': 33953
- }, {
- 'n': '罪案',
- 'v': 33960
- }, {
- 'n': '竞技',
- 'v': 33967
- }, {
- 'n': '灾难',
- 'v': 33974
- }, {
- 'n': '军事',
- 'v': 72
- }, {
- 'n': '历史',
- 'v': 74
- }, {
- 'n': '探险',
- 'v': 73
- }, {
- 'n': '社会',
- 'v': 71
- }, {
- 'n': '科技',
- 'v': 28119
- }, {
- 'n': '旅游',
- 'v': 310
- }]
- }, {
- 'key': '28467',
- 'name': '出品方',
- 'value': [{
- 'n': '全部',
- 'v': ''
- }, {
- 'n': 'BBC',
- 'v': 28468
- }, {
- 'n': '美国历史频道',
- 'v': 28470
- }, {
- 'n': '探索频道',
- 'v': 28471
- }, {
- 'n': '央视记录',
- 'v': 28472
- }, {
- 'n': '北京纪实频道',
- 'v': 28473
- }, {
- 'n': '上海纪实频道',
- 'v': 28474
- }, {
- 'n': '朗思文化',
- 'v': 28476
- }, {
- 'n': 'CNEX',
- 'v': 28477
- }, {
- 'n': '五星传奇',
- 'v': 28478
- }, {
- 'n': 'IMG',
- 'v': 28479
- }, {
- 'n': 'NHK',
- 'v': 28480
- }, {
- 'n': '爱奇艺出品',
- 'v': 31283
- }, {
- 'n': 'Netflix',
- 'v': 31286
- }]
- }, {
- 'key': '29076',
- 'name': '片种',
- 'value': [{
- 'n': '全部',
- 'v': ''
- }, {
- 'n': '纪录电影',
- 'v': 29077
- }, {
- 'n': '系列纪录片',
- 'v': 29078
- }, {
- 'n': '网络纪录片',
- 'v': 29082
- }, {
- 'n': '纪实栏目',
- 'v': 29083
- }]
- }, {
- 'key': '31294',
- 'name': '时长',
- 'value': [{
- 'n': '全部',
- 'v': ''
- }, {
- 'n': '微纪录',
- 'v': 29079
- }, {
- 'n': '长纪录',
- 'v': 29080
- }, {
- 'n': '短纪录',
- 'v': 29081
- }]
}],
'4': [{
'key': 'mode',
@@ -650,6 +492,50 @@ var rule = {
'n': '新上线',
'v': 4
}]
+ }, {
+ 'key': 'three_category_id',
+ 'name': '类型',
+ 'value': [{
+ 'n': '全部',
+ 'v': ''
+ }, {
+ 'n': '热血',
+ 'v': 30232
+ }, {
+ 'n': '搞笑',
+ 'v': 30230
+ }, {
+ 'n': '恋爱',
+ 'v': 30243
+ }, {
+ 'n': '冒险',
+ 'v': 30267
+ }, {
+ 'n': '校园',
+ 'v': 30249
+ }, {
+ 'n': '科幻',
+ 'v': 30245
+ }]
+ }, {
+ 'key': 'region',
+ 'name': '地区',
+ 'value': [{
+ 'n': '全部',
+ 'v': ''
+ }, {
+ 'n': '中国大陆',
+ 'v': 37
+ }, {
+ 'n': '日本',
+ 'v': 38
+ }, {
+ 'n': '欧美',
+ 'v': 39
+ }, {
+ 'n': '其它',
+ 'v': 40
+ }]
}, {
'key': 'year',
'name': '全部年份',
@@ -698,9 +584,6 @@ var rule = {
}, {
'n': '80年代',
'v': '1980_1989'
- }, {
- 'n': '更早',
- 'v': '1964_1979'
}]
}, {
'key': 'is_purchase',
@@ -718,154 +601,6 @@ var rule = {
'n': '付费',
'v': 2
}]
- }, {
- 'key': 'three_category_id',
- 'name': '地区',
- 'value': [{
- 'n': '全部',
- 'v': ''
- }, {
- 'n': '中国大陆',
- 'v': 37
- }, {
- 'n': '日本',
- 'v': 38
- }, {
- 'n': '韩国',
- 'v': 1106
- }, {
- 'n': '欧美',
- 'v': 30218
- }, {
- 'n': '其它',
- 'v': 40
- }]
- }, {
- 'key': '30219',
- 'name': '版本',
- 'value': [{
- 'n': '全部',
- 'v': ''
- }, {
- 'n': '动画',
- 'v': 30220
- }, {
- 'n': '特摄',
- 'v': 30223
- }, {
- 'n': '布袋戏',
- 'v': 30224
- }, {
- 'n': '特别篇',
- 'v': 32782
- }, {
- 'n': '动态漫画',
- 'v': 32783
- }, {
- 'n': '动画电影',
- 'v': 32784
- }, {
- 'n': '竖版视频',
- 'v': 32785
- }, {
- 'n': '轻动画',
- 'v': 33482
- }, {
- 'n': '短剧',
- 'v': 33483
- }]
- }, {
- 'key': '30225',
- 'name': '风格',
- 'value': [{
- 'n': '全部',
- 'v': ''
- }, {
- 'n': '搞笑',
- 'v': 30230
- }, {
- 'n': '热血',
- 'v': 30232
- }, {
- 'n': '催泪',
- 'v': 30233
- }, {
- 'n': '治愈',
- 'v': 30234
- }, {
- 'n': '励志',
- 'v': 30237
- }, {
- 'n': '机战',
- 'v': 30241
- }, {
- 'n': '恋爱',
- 'v': 30243
- }, {
- 'n': '科幻',
- 'v': 30245
- }, {
- 'n': '奇幻',
- 'v': 30247
- }, {
- 'n': '推理',
- 'v': 30248
- }, {
- 'n': '校园',
- 'v': 30249
- }, {
- 'n': '日常',
- 'v': 30252
- }, {
- 'n': '历史',
- 'v': 30254
- }, {
- 'n': '美食',
- 'v': 30255
- }, {
- 'n': '职场',
- 'v': 30256
- }, {
- 'n': '偶像',
- 'v': 30258
- }, {
- 'n': '泡面',
- 'v': 30265
- }, {
- 'n': '冒险',
- 'v': 30267
- }, {
- 'n': '竞技',
- 'v': 30268
- }, {
- 'n': '合家欢',
- 'v': 30270
- }, {
- 'n': '武侠',
- 'v': 32792
- }, {
- 'n': '玄幻',
- 'v': 32793
- }]
- }, {
- 'key': '32795',
- 'name': '新类型',
- 'value': [{
- 'n': '全部',
- 'v': ''
- }, {
- 'n': '轻小说改编',
- 'v': 32796
- }, {
- 'n': '漫画改编',
- 'v': 32797
- }, {
- 'n': '游戏改编',
- 'v': 32798
- }, {
- 'n': '原创',
- 'v': 32799
- }]
}],
'6': [{
'key': 'mode',
@@ -883,139 +618,21 @@ var rule = {
'n': '新上线',
'v': 4
}]
- }, {
- 'key': 'year',
- 'name': '全部年份',
- 'value': [{
- 'n': '全部',
- 'v': ''
- }, {
- "n": "2026",
- "v": 2026
- }, {
- "n": "2025",
- "v": 2025
- }, {
- "n": "2024",
- "v": 2024
- }, {
- 'n': '2023',
- 'v': 2023
- }, {
- 'n': '2022',
- 'v': 2022
- }, {
- 'n': '2021',
- 'v': 2021
- }, {
- 'n': '2020',
- 'v': 2020
- }, {
- 'n': '2019',
- 'v': 2019
- }, {
- 'n': '2018',
- 'v': 2018
- }, {
- 'n': '2017',
- 'v': 2017
- }, {
- 'n': '2016-2011',
- 'v': '2011_2016'
- }, {
- 'n': '2010-2000',
- 'v': '2000_2010'
- }, {
- 'n': '90年代',
- 'v': '1990_1999'
- }, {
- 'n': '80年代',
- 'v': '1980_1989'
- }, {
- 'n': '更早',
- 'v': '1964_1979'
- }]
- }, {
- 'key': 'is_purchase',
- 'name': '全部资费',
- 'value': [{
- 'n': '全部',
- 'v': ''
- }, {
- 'n': '免费',
- 'v': 0
- }, {
- 'n': '会员',
- 'v': 1
- }, {
- 'n': '付费',
- 'v': 2
- }]
}, {
'key': 'three_category_id',
- 'name': '地区',
- 'value': [{
- 'n': '全部',
- 'v': ''
- }, {
- 'n': '内地',
- 'v': 151
- }, {
- 'n': '港台',
- 'v': 152
- }, {
- 'n': '韩国',
- 'v': 33306
- }, {
- 'n': '欧美',
- 'v': 154
- }, {
- 'n': '其它',
- 'v': 1113
- }]
- }, {
- 'key': '18014',
'name': '类型',
'value': [{
'n': '全部',
'v': ''
}, {
- 'n': '播报',
- 'v': 155
- }, {
- 'n': '访谈',
- 'v': 156
- }, {
- 'n': '游戏',
- 'v': 158
- }, {
- 'n': '晚会',
- 'v': 292
- }, {
- 'n': '曲艺',
- 'v': 293
+ 'n': '真人秀',
+ 'v': 2224
}, {
'n': '脱口秀',
'v': 2118
}, {
- 'n': '真人秀',
- 'v': 2224
- }, {
- 'n': '竞技',
- 'v': 30278
- }, {
- 'n': '爱奇艺出品',
- 'v': 30279
- }, {
- 'n': '竞演',
- 'v': 33860
- }]
- }, {
- 'key': '33162',
- 'name': '题材',
- 'value': [{
- 'n': '全部',
- 'v': ''
+ 'n': '晚会',
+ 'v': 292
}, {
'n': '音乐',
'v': 33163
@@ -1023,266 +640,18 @@ var rule = {
'n': '舞蹈',
'v': 33172
}, {
- 'n': '文化',
- 'v': 33173
- }, {
- 'n': '美食',
- 'v': 33182
- }, {
- 'n': '伦理',
- 'v': 33184
- }, {
- 'n': '相亲',
- 'v': 33193
- }, {
- 'n': '纪实',
- 'v': 33195
- }, {
- 'n': '生活',
- 'v': 33196
- }, {
- 'n': '亲子',
- 'v': 33197
- }, {
- 'n': '少儿',
- 'v': 33198
- }, {
- 'n': '财经',
- 'v': 33199
- }, {
- 'n': '健康',
- 'v': 33200
- }, {
- 'n': '时尚',
- 'v': 33203
- }, {
- 'n': '旅游',
- 'v': 33205
- }, {
- 'n': '教育',
- 'v': 33206
- }, {
- 'n': '其它',
- 'v': 33220
- }, {
- 'n': '爱情',
- 'v': 33316
- }, {
- 'n': '搞笑',
- 'v': 33317
- }, {
- 'n': '益智',
- 'v': 33318
- }, {
- 'n': '职场',
- 'v': 33319
- }, {
- 'n': '语言',
- 'v': 33530
- }, {
- 'n': '辩论',
- 'v': 33531
- }, {
- 'n': '演讲',
- 'v': 33843
- }]
- }],
- '5': [{
- 'key': 'mode',
- 'name': '综合排序',
- 'value': [{
- 'n': '全部',
- 'v': ''
- }, {
- 'n': '热播榜',
- 'v': 11
- }, {
- 'n': '好评榜',
- 'v': 8
- }, {
- 'n': '新上线',
- 'v': 4
+ 'n': '竞技',
+ 'v': 30278
}]
}, {
- 'key': 'year',
- 'name': '全部年份',
- 'value': [{
- 'n': '全部',
- 'v': ''
- }, {
- "n": "2026",
- "v": 2026
- }, {
- "n": "2025",
- "v": 2025
- }, {
- "n": "2024",
- "v": 2024
- }, {
- 'n': '2023',
- 'v': 2023
- }, {
- 'n': '2022',
- 'v': 2022
- }, {
- 'n': '2021',
- 'v': 2021
- }, {
- 'n': '2020',
- 'v': 2020
- }, {
- 'n': '2019',
- 'v': 2019
- }, {
- 'n': '2018',
- 'v': 2018
- }, {
- 'n': '2017',
- 'v': 2017
- }, {
- 'n': '2016-2011',
- 'v': '2011_2016'
- }, {
- 'n': '2010-2000',
- 'v': '2000_2010'
- }, {
- 'n': '90年代',
- 'v': '1990_1999'
- }, {
- 'n': '80年代',
- 'v': '1980_1989'
- }, {
- 'n': '更早',
- 'v': '1964_1979'
- }]
- }, {
- 'key': 'is_purchase',
- 'name': '全部资费',
- 'value': [{
- 'n': '全部',
- 'v': ''
- }, {
- 'n': '免费',
- 'v': 0
- }, {
- 'n': '会员',
- 'v': 1
- }, {
- 'n': '付费',
- 'v': 2
- }]
- }, {
- 'key': 'three_category_id',
+ 'key': 'region',
'name': '地区',
'value': [{
'n': '全部',
'v': ''
}, {
'n': '内地',
- 'v': 221
- }, {
- 'n': '港台',
- 'v': 220
- }, {
- 'n': '欧美',
- 'v': 219
- }, {
- 'n': '日韩',
- 'v': 218
- }, {
- 'n': '拉美',
- 'v': 217
- }, {
- 'n': '亚洲地区',
- 'v': 216
- }, {
- 'n': '非洲',
- 'v': 215
- }]
- }, {
- 'key': '18009',
- 'name': '语种',
- 'value': [{
- 'n': '全部',
- 'v': ''
- }, {
- 'n': '普通话',
- 'v': 91
- }, {
- 'n': '粤语',
- 'v': 92
- }, {
- 'n': '闽南语',
- 'v': 93
- }, {
- 'n': '英语',
- 'v': 94
- }, {
- 'n': '日语',
- 'v': 95
- }, {
- 'n': '韩语',
- 'v': 96
- }, {
- 'n': '其它',
- 'v': 97
- }]
- }, {
- 'key': '23554',
- 'name': '音乐类型',
- 'value': [{
- 'n': '全部',
- 'v': ''
- }, {
- 'n': '单曲MV',
- 'v': 23556
- }, {
- 'n': '单曲现场',
- 'v': 23557
- }, {
- 'n': '演唱会',
- 'v': 23558
- }, {
- 'n': '新闻',
- 'v': 23559
- }, {
- 'n': '访谈',
- 'v': 23560
- }, {
- 'n': '音乐记录',
- 'v': 23561
- }, {
- 'n': '音乐周边',
- 'v': 23562
- }, {
- 'n': '音乐节目',
- 'v': 23563
- }, {
- 'n': '影视原声',
- 'v': 23564
- }, {
- 'n': '音乐短片',
- 'v': 23565
- }, {
- 'n': '其他',
- 'v': 23566
- }]
- }],
- '16': [{
- 'key': 'mode',
- 'name': '综合排序',
- 'value': [{
- 'n': '全部',
- 'v': ''
- }, {
- 'n': '热播榜',
- 'v': 11
- }, {
- 'n': '好评榜',
- 'v': 8
- }, {
- 'n': '新上线',
- 'v': 4
+ 'v': 151
}]
}, {
'key': 'year',
@@ -1332,9 +701,6 @@ var rule = {
}, {
'n': '80年代',
'v': '1980_1989'
- }, {
- 'n': '更早',
- 'v': '1964_1979'
}]
}, {
'key': 'is_purchase',
@@ -1352,46 +718,192 @@ var rule = {
'n': '付费',
'v': 2
}]
- }, {
- 'key': '18061',
- 'name': '类型',
+ }],
+ '35': [{
+ 'key': 'mode',
+ 'name': '综合排序',
'value': [{
'n': '全部',
'v': ''
}, {
- 'n': '喜剧',
- 'v': 1296
+ 'n': '热播榜',
+ 'v': 11
}, {
- 'n': '爱情',
- 'v': 1297
+ 'n': '好评榜',
+ 'v': 8
}, {
- 'n': '动作',
- 'v': 1298
+ 'n': '新上线',
+ 'v': 4
+ }]
+ }, {
+ 'key': 'year',
+ 'name': '全部年份',
+ 'value': [{
+ 'n': '全部',
+ 'v': ''
}, {
- 'n': '奇幻',
- 'v': 1299
+ "n": "2026",
+ "v": 2026
}, {
- 'n': '惊悚',
- 'v': 1300
+ "n": "2025",
+ "v": 2025
}, {
- 'n': '悬疑',
- 'v': 1301
+ "n": "2024",
+ "v": 2024
}, {
- 'n': '青春',
- 'v': 1302
+ 'n': '2023',
+ 'v': 2023
+ }, {
+ 'n': '2022',
+ 'v': 2022
+ }]
+ }, {
+ 'key': 'is_purchase',
+ 'name': '全部资费',
+ 'value': [{
+ 'n': '全部',
+ 'v': ''
+ }, {
+ 'n': '免费',
+ 'v': 0
+ }, {
+ 'n': '会员',
+ 'v': 1
+ }, {
+ 'n': '付费',
+ 'v': 2
+ }]
+ }],
+ '15': [{
+ 'key': 'mode',
+ 'name': '综合排序',
+ 'value': [{
+ 'n': '全部',
+ 'v': ''
+ }, {
+ 'n': '热播榜',
+ 'v': 11
+ }, {
+ 'n': '好评榜',
+ 'v': 8
+ }, {
+ 'n': '新上线',
+ 'v': 4
+ }]
+ }, {
+ 'key': 'is_purchase',
+ 'name': '全部资费',
+ 'value': [{
+ 'n': '全部',
+ 'v': ''
+ }, {
+ 'n': '免费',
+ 'v': 0
+ }, {
+ 'n': '会员',
+ 'v': 1
+ }, {
+ 'n': '付费',
+ 'v': 2
+ }]
+ }],
+ '37': [{
+ 'key': 'mode',
+ 'name': '综合排序',
+ 'value': [{
+ 'n': '全部',
+ 'v': ''
+ }, {
+ 'n': '热播榜',
+ 'v': 11
+ }, {
+ 'n': '好评榜',
+ 'v': 8
+ }, {
+ 'n': '新上线',
+ 'v': 4
+ }]
+ }, {
+ 'key': 'year',
+ 'name': '全部年份',
+ 'value': [{
+ 'n': '全部',
+ 'v': ''
+ }, {
+ "n": "2026",
+ "v": 2026
+ }, {
+ "n": "2025",
+ "v": 2025
+ }, {
+ "n": "2024",
+ "v": 2024
+ }, {
+ 'n': '2023',
+ 'v': 2023
+ }, {
+ 'n': '2022',
+ 'v': 2022
+ }]
+ }, {
+ 'key': 'is_purchase',
+ 'name': '全部资费',
+ 'value': [{
+ 'n': '全部',
+ 'v': ''
+ }, {
+ 'n': '免费',
+ 'v': 0
+ }, {
+ 'n': '会员',
+ 'v': 1
+ }, {
+ 'n': '付费',
+ 'v': 2
+ }]
+ }],
+ '31': [{
+ 'key': 'mode',
+ 'name': '综合排序',
+ 'value': [{
+ 'n': '全部',
+ 'v': ''
+ }, {
+ 'n': '热播榜',
+ 'v': 11
+ }, {
+ 'n': '好评榜',
+ 'v': 8
+ }, {
+ 'n': '新上线',
+ 'v': 4
+ }]
+ }, {
+ 'key': 'is_purchase',
+ 'name': '全部资费',
+ 'value': [{
+ 'n': '全部',
+ 'v': ''
+ }, {
+ 'n': '免费',
+ 'v': 0
+ }, {
+ 'n': '会员',
+ 'v': 1
+ }, {
+ 'n': '付费',
+ 'v': 2
}]
}]
},
- // url:'https://pcw-api.iqiyi.com/search/recommend/list?channel_id=fyclass&data_type=1&is_purchase=&mode=24&page_id=fypage&ret_num=48&three_category_id=',
- url: 'https://pcw-api.iqiyi.com/search/recommend/list?channel_id=fyclass&data_type=1&page_id=fypage&ret_num=48',
- filter_url: 'is_purchase={{fl.is_purchase}}&mode={{fl.mode}}&three_category_id={{fl.three_category_id}}&market_release_date_level={{fl.year}}',
- // url:'https://pcw-api.iqiyi.com/search/video/videolists?channel_id=fyclass&pageNum=fypage&pageSize=24&data_type=1&site=iqiyi',
+ url: 'https://pcw-api.iqiyi.com/search/recommend/list?channel_id=fyclass&data_type=1&page_id=fypage&ret_num=24',
+ filter_url: 'is_purchase={{fl.is_purchase}}&mode={{fl.mode}}&three_category_id={{fl.three_category_id}}&market_release_date_level={{fl.year}}®ion={{fl.region}}',
headers: {
'User-Agent': 'MOBILE_UA'
},
timeout: 5000,
- class_name: '电影&电视剧&纪录片&动漫&综艺&音乐&网络电影',
- class_url: '1&2&3&4&6&5&16',
+ class_name: '电视剧&短剧&电影&综艺&少儿&动漫&漫剧&纪录片&知识',
+ class_url: '2&35&1&6&15&4&37&3&31',
limit: 20,
play_parse: true,
lazy: $js.toString(() => {
@@ -1430,20 +942,8 @@ var rule = {
};
}
}),
- // play_parse:true,
- // 手动调用解析请求json的url,此lazy不方便
- // lazy:'js:input="https://cache.json.icu/home/api?type=ys&uid=292796&key=fnoryABDEFJNPQV269&url="+input.split("?")[0];log(input);let html=JSON.parse(request(input));log(html);input=html.url||input',
- // 推荐:'.list_item;img&&alt;img&&src;a&&Text;a&&data-float',
- // 一级:'json:.data.list;.name;.imageUrl;.latestOrder;.albumId',
推荐: '',
- // 推荐:'js:let d=[];fetch_params.headers["user-agent"]=PC_UA;pdfh=jsp.pdfh;pdfa=jsp.pdfa;pd=jsp.pd;let html=fetch(HOST,fetch_params);let lists=pdfa(html,".qy-mod-li");lists.forEach(function(it){try{let title=pdfh(it,"p.sub&&title");let desc=pdfh(it,".qy-mod-label&&Text");let pic_url=pd(it,"img&&src");d.push({title:title,desc:desc,img:pic_url})}catch(e){}});res=setResult(d);',
- 一级: 'js:let d=[];if(MY_CATE==="16"){input=input.replace("channel_id=16","channel_id=1").split("three_category_id")[0];input+="three_category_id=27401"}else if(MY_CATE==="5"){input=input.replace("data_type=1","data_type=2")}let html=request(input);let json=JSON.parse(html);if(json.code==="A00003"){fetch_params.headers["user-agent"]=PC_UA;json=JSON.parse(fetch(input,fetch_params))}json.data.list.forEach(function(data){if(data.channelId===1){desc=data.hasOwnProperty("score")?data.score+"分\\t":""}else if(data.channelId===2||data.channelId===4){if(data.latestOrder===data.videoCount){desc=(data.hasOwnProperty("score")?data.score+"分\\t":"")+data.latestOrder+"集全"}else{if(data.videoCount){desc=(data.hasOwnProperty("score")?data.score+"分\\t":"")+data.latestOrder+"/"+data.videoCount+"集"}else{desc="更新至 "+data.latestOrder+"集"}}}else if(data.channelId===6){desc=data.period+"期"}else if(data.channelId===5){desc=data.focus}else{if(data.latestOrder){desc="更新至 第"+data.latestOrder+"期"}else if(data.period){desc=data.period}else{desc=data.focus}}url=MY_CATE+"$"+data.albumId;d.push({url:url,title:data.name,desc:desc,pic_url:data.imageUrl.replace(".jpg","_390_520.jpg?caplist=jpg,webp")})});setResult(d);',
- // 一级:'js:let d=[];if(MY_CATE==="16"){input=input.replace("channel_id=16","channel_id=1").split("three_category_id")[0];input+="three_category_id=27401"}else if(MY_CATE==="5"){input=input.replace("data_type=1","data_type=2")}let html=fetch(input,fetch_params);let json=JSON.parse(html);if(json.code==="A00003"){fetch_params.headers["user-agent"]=PC_UA;json=JSON.parse(fetch(input,fetch_params))}json.data.list.forEach(function(data){if(data.channelId===1){desc=data.hasOwnProperty("score")?data.score+"分\\t":""}else if(data.channelId===2||data.channelId===4){if(data.latestOrder===data.videoCount){desc=(data.hasOwnProperty("score")?data.score+"分\\t":"")+data.latestOrder+"集全"}else{if(data.videoCount){desc=(data.hasOwnProperty("score")?data.score+"分\\t":"")+data.latestOrder+"/"+data.videoCount+"集"}else{desc="更新至 "+data.latestOrder+"集"}}}else if(data.channelId===6){desc=data.period+"期"}else if(data.channelId===5){desc=data.focus}else{if(data.latestOrder){desc="更新至 第"+data.latestOrder+"期"}else if(data.period){desc=data.period}else{desc=data.focus}}url=MY_CATE+"$"+data.albumId;d.push({url:url,title:data.name,desc:desc,pic_url:data.imageUrl.replace(".jpg","_390_520.jpg?caplist=jpg,webp")})});setResult(d);',
- // 一级:'json:.data.list;.name;.imageUrl;.playUrl;.latestOrder',
- // 二级:{is_json:1,"title":"data.title;data.moviecategory[0]+data.moviecategory[1]","img":"data.cdncover","desc":"data.area[0];data.director[0]","content":"data.description","tabs":"data.playlink_sites;data.playlinksdetail.#idv.quality","lists":"data.playlinksdetail.#idv.default_url"},
- // 二级:{is_json:1,"title":"data.name+data.subtitle;data.latestOrder","img":"data.imageUrl","desc":"data.categories;data.areas","content":"data.description","tabs":"data.name","lists":"data.playlinksdetail.#idv.default_url"},
- 二级: '',
- 二级: 'js:let d=[];let html=request(input);let json=JSON.parse(html).data;VOD={vod_id:"",vod_url:input,vod_name:"",type_name:"",vod_actor:"",vod_year:"",vod_director:"",vod_area:"",vod_content:"",vod_remarks:"",vod_pic:""};VOD.vod_name=json.name;try{if(json.latestOrder){VOD.vod_remarks="类型: "+(json.categories[0].name||"")+"\\t"+(json.categories[1].name||"")+"\\t"+(json.categories[2].name||"")+"\\t"+"评分:"+(json.score||"")+"\\n更新至:第"+json.latestOrder+"集(期)/共"+json.videoCount+"集(期)"}else{VOD.vod_remarks="类型: "+(json.categories[0].name||"")+"\\t"+(json.categories[1].name||"")+"\\t"+(json.categories[2].name||"")+"\\t"+"评分:"+(json.score||"")+json.period}}catch(e){VOD.vod_remarks=json.subtitle}VOD.vod_area=(json.focus||"")+"\\n资费:"+(json.payMark===1?"VIP":"免费")+"\\n地区:"+(json.areas||"");let vsize="579_772";try{vsize=json.imageSize[12]}catch(e){}VOD.vod_pic=json.imageUrl.replace(".jpg","_"+vsize+".jpg?caplist=jpg,webp");VOD.type_name=json.categories.map(function(it){return it.name}).join(",");if(json.people.main_charactor){let vod_actors=[];json.people.main_charactor.forEach(function(it){vod_actors.push(it.name)});VOD.vod_actor=vod_actors.join(",")}VOD.vod_content=json.description;let playlists=[];if(json.channelId===1||json.channelId===5){playlists=[{playUrl:json.playUrl,imageUrl:json.imageUrl,shortTitle:json.shortTitle,focus:json.focus,period:json.period}]}else{if(json.channelId===6){let qs=json.period.split("-")[0];let listUrl="https://pcw-api.iqiyi.com/album/source/svlistinfo?cid=6&sourceid="+json.albumId+"&timelist="+qs;let playData=JSON.parse(request(listUrl)).data[qs];playData.forEach(function(it){playlists.push({playUrl:it.playUrl,imageUrl:it.imageUrl,shortTitle:it.shortTitle,focus:it.focus,period:it.period})})}else{let listUrl="https://pcw-api.iqiyi.com/albums/album/avlistinfo?aid="+json.albumId+"&size=200&page=1";let data=JSON.parse(request(listUrl)).data;let total=data.total;playlists=data.epsodelist;if(total>200){for(let i=2;i200){for(let i=2;i200){for(let i=2;i 10000:
+ online_str = f"{online / 10000:.1f}万"
+ else:
+ online_str = str(online)
+
+ v = self.buildvod(
+ f"{tid}@@{room['roomid']}",
+ room.get('title', '未知标题'),
+ room.get('cover') or room.get('system_cover'),
+ f"{online_str}人",
+ 0,
+ room.get('uname', ''),
+ style={"type": "rect", "ratio": 1.33}
+ )
+ vdata.append(v)
+
+ # 检查是否有更多数据
+ has_more = data.get('data', {}).get('has_more', 0)
+ if not has_more:
+ pagecount = int(pg)
+ else:
+ pagecount = 9999
+ else:
+ print(f"B站API返回错误: {data.get('message', '未知错误')} (code: {data.get('code')})")
+ pagecount = 1
+
+ return vdata, pagecount
+
+ except Exception as e:
+ print(f"B站内容获取错误: {e}")
+ return vdata, 1
def huyaContent(self, tid, pg, filter, extend, vdata):
if extend.get('cate') and pg == '1' and 'click' not in tid:
@@ -295,44 +418,6 @@ class Spider(Spider):
vdata.append(v)
return vdata, 9999
- def douyinContent(self, tid, pg, filter, extend, vdata):
- if extend.get('cate') and pg == '1' and 'click' not in tid:
- ids = extend.get('cate').split('@@')
- for i in self.dyifdata['categoryData']:
- c = i['partition']
- if c['id_str'] == ids[0] and c['title'] == ids[1]:
- vlist = i['sub_partition'].copy()
- vlist.insert(0, {'partition': c})
- for j in vlist:
- j = j['partition']
- v = self.buildvod(
- vod_id=f"click_{tid}@@{j['id_str']}@@{j['type']}",
- vod_name=j.get('title'),
- vod_pic='https://p3-pc-weboff.byteimg.com/tos-cn-i-9r5gewecjs/pwa_v3/512x512-1.png',
- vod_tag=1,
- style={"type": "oval", "ratio": 1}
- )
- vdata.append(v)
- return vdata, 1
- else:
- path = f'/webcast/web/partition/detail/room/?aid=6383&app_name=douyin_web&live_id=1&device_platform=web&count=15&offset={(int(pg) - 1) * 15}&partition=720&partition_type=1'
- if 'click' in tid:
- ids = tid.split('_')[1].split('@@')
- tid = ids[0]
- path = f'/webcast/web/partition/detail/room/?aid=6383&app_name=douyin_web&live_id=1&device_platform=web&count=15&offset={(int(pg) - 1) * 15}&partition={ids[1]}&partition_type={ids[-1]}&req_from=2'
- data = self.fetch(f'{self.hosts[tid]}{path}', headers=self.dyheaders).json()
- for i in data['data']['data']:
- v = self.buildvod(
- vod_id=f"{tid}@@{i['web_rid']}",
- vod_name=i['room'].get('title'),
- vod_pic=i['room']['cover'].get('url_list')[0],
- vod_year=i.get('user_count_str'),
- vod_remarks=i['room']['owner'].get('nickname'),
- style={"type": "rect", "ratio": 1.33}
- )
- vdata.append(v)
- return vdata, 9999
-
def douyuContent(self, tid, pg, filter, extend, vdata):
if extend.get('cate') and pg == '1' and 'click' not in tid:
for i in self.dyufdata['data']['cate2Info']:
@@ -375,8 +460,6 @@ class Spider(Spider):
vod = self.biliDetail(ids)
elif ids[0] == 'huya':
vod = self.huyaDetail(ids)
- elif ids[0] == 'douyin':
- vod = self.douyinDetail(ids)
elif ids[0] == 'douyu':
vod = self.douyuDetail(ids)
return {'list': [vod]}
@@ -425,186 +508,550 @@ class Spider(Spider):
return self.handle_exception(e)
def biliDetail(self, ids):
+ """
+ B站直播详情 - 使用playUrl接口获取多清晰度
+ """
try:
- vdata = self.fetch(
- f'{self.hosts[ids[0]][0]}/xlive/web-room/v1/index/getInfoByRoom?room_id={ids[1]}&wts={int(time.time())}',
- headers=self.gethr(0, ids[0])).json()
- v = vdata['data']['room_info']
+ room_id = ids[1]
+
+ # 获取房间信息
+ info_res = self.fetch(
+ f'{self.hosts["bili"][0]}/room/v1/Room/get_info?room_id={room_id}',
+ headers=self.headers[0]
+ ).json()
+
+ if info_res.get('code') != 0:
+ return self.handle_exception(Exception("获取房间信息失败"))
+
+ room_info = info_res['data']
+ title = room_info.get('title', 'B站直播')
+
vod = self.buildvod(
- vod_name=v.get('title'),
- type_name=v.get('parent_area_name') + '/' + v.get('area_name'),
- vod_remarks=v.get('tags'),
- vod_play_from=v.get('title'),
+ vod_name=title,
+ type_name=f"{room_info.get('parent_area_name', '')}/{room_info.get('area_name', '')}",
+ vod_director=room_info.get('uname', ''),
+ vod_remarks=f"在线{room_info.get('online', 0)}人"
)
- data = self.fetch(
- f'{self.hosts[ids[0]][0]}/xlive/web-room/v2/index/getRoomPlayInfo?room_id={ids[1]}&protocol=0%2C1&format=0%2C1%2C2&codec=0%2C1&platform=web',
- headers=self.gethr(0, ids[0])).json()
- vdnams = data['data']['playurl_info']['playurl']['g_qn_desc']
- all_accept_qns = []
- streams = data['data']['playurl_info']['playurl']['stream']
- for stream in streams:
- for format_item in stream['format']:
- for codec in format_item['codec']:
- if 'accept_qn' in codec:
- all_accept_qns.append(codec['accept_qn'])
- max_accept_qn = max(all_accept_qns, key=len) if all_accept_qns else []
- quality_map = {
- item['qn']: item['desc']
- for item in vdnams
- }
- quality_names = [f"{quality_map.get(qn)}${ids[0]}@@{ids[1]}@@{qn}" for qn in max_accept_qn]
- vod['vod_play_url'] = "#".join(quality_names)
+
+ # 获取播放地址信息
+ play_res = self.fetch(
+ f'{self.hosts["bili"][0]}/room/v1/Room/playUrl?cid={room_id}&qn=10000&platform=web',
+ headers={
+ **self.headers[0],
+ 'Referer': 'https://live.bilibili.com/',
+ 'Origin': 'https://live.bilibili.com'
+ }
+ ).json()
+
+ if play_res.get('code') != 0:
+ return self.handle_exception(Exception("获取播放地址失败"))
+
+ play_data = play_res['data']
+ accept_quality = play_data.get('accept_quality', ['10000', '400', '250', '150'])
+ quality_desc = {item['qn']: item['desc'] for item in play_data.get('quality_description', [])}
+
+ # 构建清晰度列表
+ qualities = []
+ for qn in sorted([int(q) for q in accept_quality], reverse=True):
+ desc = quality_desc.get(qn, f'清晰度{qn}')
+ qualities.append(f"{desc}$bili@@{room_id}@@{qn}")
+
+ vod['vod_play_from'] = 'B站直播'
+ vod['vod_play_url'] = '#'.join(qualities)
return vod
+
except Exception as e:
+ print(f"B站详情错误: {e}")
return self.handle_exception(e)
def huyaDetail(self, ids):
+ """
+ 虎牙播放详情 - 参考最新三合一.js重构
+ 支持多线路多清晰度选择
+ 核心算法:通过房间信息API获取uid、streamName和rateArray,为每个清晰度生成签名URL
+ 清晰度说明:
+ - 蓝光8M/6M/4M/10M = 8000/6000/4000/10000 kbps = 1080P+
+ - 蓝光 = 3000 kbps = 1080P
+ - 超清 = 2000 kbps = 1080P (官方标准)
+ - 高清 = 1200 kbps = 720P
+ - 标清/流畅 = 500-800 kbps = 480P/540P
+ """
try:
- vdata = self.fetch(f'{self.hosts[ids[0]][1]}/cache.php?m=Live&do=profileRoom&roomid={ids[1]}',
- headers=self.headers[0]).json()
- v = vdata['data']['liveData']
+ room_id = ids[1]
+
+ # 1. 获取房间信息
+ api_url = f'{self.hosts[ids[0]][1]}/cache.php?m=Live&do=profileRoom&roomid={room_id}'
+ res = self.fetch(api_url, headers=self.headers[0])
+
+ if res.status_code != 200:
+ return self.handle_exception(Exception(f"API请求失败: {res.status_code}"))
+
+ data = res.json()
+ if not data or not data.get('data'):
+ return self.handle_exception(Exception("房间数据为空"))
+
+ room_data = data['data']
+
+ # 2. 提取关键信息
+ uid = room_data.get('profileInfo', {}).get('uid')
+ stream_info = room_data.get('stream', {})
+ live_data = room_data.get('liveData', {})
+
+ if not uid:
+ return self.handle_exception(Exception("缺少uid"))
+
+ # 3. 获取streamName和码率信息
+ base_stream_list = stream_info.get('baseSteamInfoList', [])
+ if not base_stream_list:
+ return self.handle_exception(Exception("无直播流信息"))
+
+ # 获取第一个CDN的streamName作为基准
+ base_stream = base_stream_list[0]
+ stream_name = base_stream.get('sStreamName')
+ if not stream_name:
+ return self.handle_exception(Exception("无法获取streamName"))
+
+ # 4. 构建VOD对象
vod = self.buildvod(
- vod_name=v.get('introduction'),
- type_name=v.get('gameFullName'),
- vod_director=v.get('nick'),
- vod_remarks=v.get('contentIntro'),
+ vod_name=live_data.get('introduction', '虎牙直播'),
+ type_name=live_data.get('gameFullName', ''),
+ vod_director=live_data.get('nick', ''),
+ vod_remarks=live_data.get('contentIntro', ''),
)
- data = dict(reversed(list(vdata['data']['stream'].items())))
- names = []
- plist = []
-
- for stream_type, stream_data in data.items():
- if isinstance(stream_data, dict) and 'multiLine' in stream_data and 'rateArray' in stream_data:
- names.append(f"线路{len(names) + 1}")
- qualities = sorted(
- stream_data['rateArray'],
- key=lambda x: (x['iBitRate'], x['sDisplayName']),
- reverse=True
+
+ # 5. 获取所有CDN线路
+ cdn_list = []
+ for stream in base_stream_list:
+ cdn_type = stream.get('sCdnType', 'AL')
+ flv_url = stream.get('sFlvUrl', '')
+ hls_url = stream.get('sHlsUrl', '')
+ stream_name_cdn = stream.get('sStreamName', stream_name)
+
+ if flv_url:
+ cdn_list.append({
+ 'cdn': cdn_type,
+ 'flv_base': flv_url,
+ 'hls_base': hls_url,
+ 'stream_name': stream_name_cdn,
+ 'priority': stream.get('iWebPriorityRate', 0)
+ })
+
+ # 按优先级排序
+ cdn_list.sort(key=lambda x: x['priority'], reverse=True)
+
+ # 6. 获取清晰度列表 (rateArray)
+ rate_array = stream_info.get('rateArray', [])
+
+ # 如果没有rateArray,尝试从vMultiStreamInfo获取
+ if not rate_array and 'vMultiStreamInfo' in room_data:
+ rate_array = room_data['vMultiStreamInfo']
+
+ # 如果仍然没有,使用默认清晰度(按虎牙官方标准)
+ if not rate_array:
+ rate_array = [
+ {'sDisplayName': '蓝光4M', 'iBitRate': 4000},
+ {'sDisplayName': '蓝光', 'iBitRate': 3000},
+ {'sDisplayName': '超清', 'iBitRate': 2000}, # 2000kbps = 1080P
+ {'sDisplayName': '高清', 'iBitRate': 1200}, # 1200kbps = 720P
+ {'sDisplayName': '流畅', 'iBitRate': 500}
+ ]
+
+ # 过滤和排序清晰度
+ # 虎牙的rateArray中,iBitRate就是码率值,sDisplayName是显示名称
+ # 需要确保:超清=2000kbps(1080P),高清=1200kbps(720P)
+ filtered_rates = []
+ seen_bitrates = set()
+
+ for rate in rate_array:
+ bit_rate = rate.get('iBitRate', 0)
+ name = rate.get('sDisplayName', '')
+
+ # 跳过重复的码率
+ if bit_rate in seen_bitrates:
+ continue
+
+ # 修正清晰度名称,确保符合虎牙标准
+ # 2000kbps应该是超清(1080P),不是高清
+ if bit_rate == 2000 and ('高清' in name or '720' in name):
+ name = '超清' # 强制修正为超清
+ elif bit_rate == 1200 and ('标清' in name or '480' in name):
+ name = '高清' # 1200kbps对应高清
+ elif bit_rate == 2000 and name == '原画':
+ name = '超清' # 修正原画为超清
+
+ seen_bitrates.add(bit_rate)
+ filtered_rates.append({
+ 'sDisplayName': name,
+ 'iBitRate': bit_rate
+ })
+
+ # 按码率从高到低排序
+ sorted_rates = sorted(filtered_rates, key=lambda x: x['iBitRate'], reverse=True)
+
+ # 7. 为每个CDN生成各清晰度的播放URL
+ play_lines = []
+ line_names = []
+
+ for cdn_idx, cdn in enumerate(cdn_list[:3]): # 最多取3个CDN
+ cdn_name = cdn['cdn']
+ line_names.append(f"线路{cdn_idx + 1}({cdn_name})")
+
+ qualities = []
+ for rate in sorted_rates:
+ quality_name = rate['sDisplayName']
+ bit_rate = rate['iBitRate']
+
+ # 生成该清晰度的URL
+ quality_url = self._generate_huya_play_url(
+ cdn, uid, stream_name, bit_rate
)
- cdn_urls = []
- for cdn in stream_data['multiLine']:
- quality_urls = []
- for quality in qualities:
- quality_name = quality['sDisplayName']
- bit_rate = quality['iBitRate']
- base_url = cdn['url']
- if bit_rate > 0:
- if '.m3u8' in base_url:
- new_url = base_url.replace(
- 'ratio=2000',
- f'ratio={bit_rate}'
- )
- else:
- new_url = base_url.replace(
- 'imgplus.flv',
- f'imgplus_{bit_rate}.flv'
- )
- else:
- new_url = base_url
- quality_urls.extend([quality_name, new_url])
- encoded_urls = self.e64(json.dumps(quality_urls))
- cdn_urls.append(f"{cdn['cdnType']}${ids[0]}@@{encoded_urls}")
-
- if cdn_urls:
- plist.append('#'.join(cdn_urls))
- vod['vod_play_from'] = "$$$".join(names)
- vod['vod_play_url'] = "$$$".join(plist)
+
+ qualities.extend([quality_name, quality_url])
+
+ # 编码该线路的所有清晰度
+ encoded_qualities = self.e64(json.dumps(qualities))
+ play_lines.append(f"{live_data.get('introduction', '直播')}${ids[0]}@@{encoded_qualities}")
+
+ # 8. 构建播放数据
+ vod['vod_play_from'] = "$$$".join(line_names)
+ vod['vod_play_url'] = "$$$".join(play_lines)
+
return vod
+
except Exception as e:
return self.handle_exception(e)
-
- def douyinDetail(self, ids):
- url = f'{self.hosts[ids[0]]}/webcast/room/web/enter/?aid=6383&app_name=douyin_web&live_id=1&device_platform=web&enter_from=web_live&web_rid={ids[1]}&room_id_str=&enter_source=&Room-Enter-User-Login-Ab=0&is_need_double_stream=false&cookie_enabled=true&screen_width=1980&screen_height=1080&browser_language=zh-CN&browser_platform=Win32&browser_name=Edge&browser_version=125.0.0.0'
- data = self.fetch(url, headers=self.dyheaders).json()
- try:
- vdata = data['data']['data'][0]
- vod = self.buildvod(
- vod_name=vdata['title'],
- vod_remarks=vdata['user_count_str'],
- )
- resolution_data = vdata['stream_url']['live_core_sdk_data']['pull_data']['options']['qualities']
- stream_json = vdata['stream_url']['live_core_sdk_data']['pull_data']['stream_data']
- stream_json = json.loads(stream_json)
- available_types = []
- if any(sdk_key in stream_json['data'] and 'main' in stream_json['data'][sdk_key] for sdk_key in
- stream_json['data']):
- available_types.append('main')
- if any(sdk_key in stream_json['data'] and 'backup' in stream_json['data'][sdk_key] for sdk_key in
- stream_json['data']):
- available_types.append('backup')
- plist = []
- for line_type in available_types:
- format_arrays = {'flv': [], 'hls': [], 'lls': []}
- qualities = sorted(resolution_data, key=lambda x: x['level'], reverse=True)
- for quality in qualities:
- sdk_key = quality['sdk_key']
- if sdk_key in stream_json['data'] and line_type in stream_json['data'][sdk_key]:
- stream_info = stream_json['data'][sdk_key][line_type]
- if stream_info.get('flv'):
- format_arrays['flv'].extend([quality['name'], stream_info['flv']])
- if stream_info.get('hls'):
- format_arrays['hls'].extend([quality['name'], stream_info['hls']])
- if stream_info.get('lls'):
- format_arrays['lls'].extend([quality['name'], stream_info['lls']])
- format_urls = []
- for format_name, url_array in format_arrays.items():
- if url_array:
- encoded_urls = self.e64(json.dumps(url_array))
- format_urls.append(f"{format_name}${ids[0]}@@{encoded_urls}")
-
- if format_urls:
- plist.append('#'.join(format_urls))
-
- names = ['线路1', '线路2'][:len(plist)]
- vod['vod_play_from'] = "$$$".join(names)
- vod['vod_play_url'] = "$$$".join(plist)
- return vod
-
- except Exception as e:
- return self.handle_exception(e)
+
+ def _generate_huya_play_url(self, cdn, uid, stream_name, bit_rate):
+ """
+ 生成虎牙播放URL,参考最新三合一.js算法
+ 关键:ratio参数必须正确设置为iBitRate值(如2000、4000等)
+ """
+ # 基础URL构建
+ flv_base = cdn['flv_base']
+ stream = cdn['stream_name']
+
+ # 生成时间戳和签名参数
+ timestamp = int(time.time())
+ seqid = f"{uid}{timestamp}"
+ ss = hashlib.md5(f"{seqid}|huya_adr|102".encode()).hexdigest()
+ ws_time = hex(timestamp + 21600)[2:] # 16进制,有效期6小时
+
+ # 计算wsSecret
+ ws_secret = hashlib.md5(
+ f"DWq8BcJ3h6DJt6TY_{uid}_{stream_name}_{ss}_{ws_time}".encode()
+ ).hexdigest()
+
+ # 构建基础URL
+ base_url = f"{flv_base}/{stream}.flv"
+
+ # 关键修复:ratio参数直接使用iBitRate值
+ # 超清=2000,高清=1200,蓝光=3000/4000/6000/8000
+ if bit_rate > 0:
+ ratio_param = f"ratio={bit_rate}"
+ else:
+ # 原画/0码率时,使用默认2000或从URL推断
+ ratio_param = "ratio=2000"
+
+ # 构建完整URL
+ play_url = (
+ f"{base_url}?{ratio_param}&wsSecret={ws_secret}&wsTime={ws_time}"
+ f"&ctype=huya_adr&seqid={seqid}&uid={uid}"
+ f"&fs=bgct&ver=1&t=102"
+ )
+
+ return play_url
def douyuDetail(self, ids):
- headers = self.gethr(0, zr=f'{self.hosts[ids[0]]}/{ids[1]}')
+ """
+ 斗鱼播放详情 - 参考最新三合一.js重构
+ 核心算法:设备ID生成 -> 获取加密密钥 -> 计算签名 -> 获取播放地址
+ 修复:切换分辨率只能播放1秒的问题
+ 方案:存储房间号和码率信息,在playerContent中实时获取对应码率的URL
+ """
try:
- data = self.fetch(f'{self.hosts[ids[0]]}/betard/{ids[1]}', headers=headers).json()
- vname = data['room']['room_name']
+ channel = ids[1]
+ headers = self.gethr(0, zr=f'{self.hosts[ids[0]]}/{channel}')
+
+ # 1. 初始化会话和设备ID (参考JS中的initialize和setupDeviceId)
+ session = {}
+
+ # 请求首页获取Cookie
+ try:
+ home_res = self.fetch(f'{self.hosts[ids[0]]}/{channel}', headers=headers)
+ if home_res.headers.get('Set-Cookie'):
+ cookie_str = home_res.headers.get('Set-Cookie')
+ # 解析dy_did
+ did_match = re.search(r'dy_did=([a-f0-9]{32})', cookie_str)
+ if did_match:
+ device_id = did_match.group(1)
+ else:
+ device_id = self._generate_random_hex(32)
+ else:
+ device_id = self._generate_random_hex(32)
+ except:
+ device_id = self._generate_random_hex(32)
+
+ session['dy_did'] = device_id
+ session['mantine-color-scheme-value'] = 'light'
+
+ # 2. 获取房间基本信息
+ betard_res = self.fetch(f'{self.hosts[ids[0]]}/betard/{channel}', headers=headers).json()
+ if not betard_res or not betard_res.get('room'):
+ return self.handle_exception(Exception("获取房间信息失败"))
+
+ room_info = betard_res['room']
+ vname = room_info.get('room_name', '斗鱼直播')
+
vod = self.buildvod(
vod_name=vname,
- vod_remarks=data['room'].get('second_lvl_name'),
- vod_director=data['room'].get('nickname'),
+ vod_remarks=room_info.get('second_lvl_name', ''),
+ vod_director=room_info.get('nickname', ''),
)
- vdata = self.fetch(f'{self.hosts[ids[0]]}/swf_api/homeH5Enc?rids={ids[1]}', headers=headers).json()
- json_body = vdata['data']
- json_body = {"html": self.douyu_text(json_body[f'room{ids[1]}']), "rid": ids[1]}
- sign = self.post('http://alive.nsapps.cn/api/AllLive/DouyuSign', json=json_body, headers=self.headers[1]).json()['data']
- body = f'{sign}&cdn=&rate=-1&ver=Douyu_223061205&iar=1&ive=1&hevc=0&fa=0'
- body=self.params_to_json(body)
- nubdata = self.post(f'{self.hosts[ids[0]]}/lapi/live/getH5Play/{ids[1]}', data=body, headers=headers).json()
- plist = []
- names = []
- for i,x in enumerate(nubdata['data']['cdnsWithName']):
- names.append(f'线路{i+1}')
- d = {'sign': sign, 'cdn': x['cdn'], 'id': ids[1]}
- plist.append(
- f'{vname}${ids[0]}@@{self.e64(json.dumps(d))}@@{self.e64(json.dumps(nubdata["data"]["multirates"]))}')
- vod['vod_play_from'] = "$$$".join(names)
- vod['vod_play_url'] = "$$$".join(plist)
+
+ # 3. 获取安全密钥 (参考JS中的getSecurityKey)
+ sec_url = f"{self.hosts[ids[0]]}/wgapi/livenc/liveweb/websec/getEncryption?did={device_id}"
+ sec_res = self.fetch(sec_url, headers=headers).json()
+
+ if not sec_res or sec_res.get('error') != 0:
+ return self.handle_exception(Exception("获取加密密钥失败"))
+
+ security_data = sec_res['data']
+ secret_key = security_data.get('key')
+ random_str = security_data.get('rand_str')
+ enc_time = security_data.get('enc_time', 1)
+ enc_data = security_data.get('enc_data')
+
+ # 4. 计算签名 (参考JS中的computeSignature)
+ current_time = int(time.time())
+
+ # 迭代计算MD5
+ current = random_str
+ for _ in range(enc_time):
+ current = hashlib.md5(f"{current}{secret_key}".encode()).hexdigest()
+
+ signature = hashlib.md5(f"{current}{secret_key}{channel}{current_time}".encode()).hexdigest()
+
+ # 5. 请求播放地址 (参考JS中的requestStreamData)
+ play_payload = {
+ 'enc_data': enc_data,
+ 'tt': str(current_time),
+ 'did': device_id,
+ 'auth': signature,
+ 'cdn': '',
+ 'rate': '',
+ 'hevc': '0',
+ 'fa': '0',
+ 'ive': '0'
+ }
+
+ play_api = f"{self.hosts[ids[0]]}/lapi/live/getH5PlayV1/{channel}"
+
+ # 构建请求头带Cookie
+ play_headers = headers.copy()
+ cookie_str = '; '.join([f"{k}={v}" for k, v in session.items()])
+ play_headers['Cookie'] = cookie_str
+ play_headers['Content-Type'] = 'application/x-www-form-urlencoded'
+
+ play_res = requests.post(play_api, data=play_payload, headers=play_headers, timeout=10).json()
+
+ if not play_res or play_res.get('error') != 0:
+ # 尝试旧版API
+ play_res = self._try_legacy_douyu_api(channel, device_id, signature, current_time, play_headers)
+ if not play_res:
+ return self.handle_exception(Exception("获取播放地址失败"))
+
+ stream_info = play_res.get('data', {})
+
+ # 6. 检查并更新设备ID (参考JS中的checkAndUpdateDeviceId)
+ rtmp_live = stream_info.get('rtmp_live', '')
+ if rtmp_live:
+ did_match = re.search(r'did=([a-f0-9]{32})', rtmp_live)
+ if did_match and did_match.group(1) != device_id:
+ device_id = did_match.group(1)
+ session['dy_did'] = device_id
+ # 重新请求
+ play_payload['did'] = device_id
+ play_res = requests.post(play_api, data=play_payload, headers=play_headers, timeout=10).json()
+ if play_res and play_res.get('error') == 0:
+ stream_info = play_res.get('data', {})
+
+ # 7. 提取播放URL和多码率信息
+ stream_url = None
+ if stream_info.get('rtmp_url') and stream_info.get('rtmp_live'):
+ stream_url = f"{stream_info['rtmp_url']}/{stream_info['rtmp_live']}"
+ elif stream_info.get('hls_url'):
+ stream_url = stream_info['hls_url']
+
+ if not stream_url:
+ return self.handle_exception(Exception("无法获取播放地址"))
+
+ # 8. 构建多码率选项
+ multirates = stream_info.get('multirates', [])
+
+ # 关键修复:存储房间号和码率信息,而不是直接存储URL
+ # 这样在切换清晰度时可以重新获取对应码率的签名URL
+ qualities = []
+
+ if multirates:
+ # 按码率排序
+ sorted_rates = sorted(multirates, key=lambda x: x.get('bit', 0), reverse=True)
+ for rate in sorted_rates:
+ bit_rate = rate.get('rate', -1)
+ name = rate.get('name', f"{bit_rate}P")
+
+ # 存储格式:码率值,用于playerContent中重新获取URL
+ # 使用特殊标记#来区分这是码率值而不是URL
+ qualities.extend([name, f"#{bit_rate}"])
+ else:
+ # 只有原画
+ qualities = ['原画', '#-1']
+
+ # 同时存储房间号和设备信息,用于重新获取URL
+ # 格式:房间号|设备ID|签名信息(base64编码)
+ session_info = {
+ 'channel': channel,
+ 'device_id': device_id,
+ 'secret_key': secret_key,
+ 'random_str': random_str,
+ 'enc_time': enc_time,
+ 'enc_data': enc_data
+ }
+ encoded_session = self.e64(json.dumps(session_info))
+
+ # 9. 构建播放数据
+ # vod_play_url格式:房间名$平台@@base64(清晰度列表)@@base64(会话信息)
+ encoded_qualities = self.e64(json.dumps(qualities))
+ vod['vod_play_from'] = '斗鱼直播'
+ vod['vod_play_url'] = f"{vname}${ids[0]}@@{encoded_qualities}@@{encoded_session}"
+
return vod
+
except Exception as e:
return self.handle_exception(e)
+
+ def _generate_random_hex(self, length):
+ """生成随机十六进制字符串"""
+ hex_chars = '0123456789abcdef'
+ return ''.join(random.choice(hex_chars) for _ in range(length))
- def douyu_text(self, text):
- function_positions = [m.start() for m in re.finditer('function', text)]
- total_functions = len(function_positions)
- if total_functions % 2 == 0:
- target_index = total_functions // 2 + 1
- else:
- target_index = (total_functions - 1) // 2 + 1
- if total_functions >= target_index:
- cut_position = function_positions[target_index - 1]
- ctext = text[4:cut_position]
- return re.sub(r'eval\(strc\)\([\w\d,]+\)', 'strc', ctext)
- return text
+ def _try_legacy_douyu_api(self, channel, device_id, signature, timestamp, headers):
+ """尝试使用旧版API获取播放地址"""
+ try:
+ legacy_payload = {
+ 'did': device_id,
+ 'tt': str(timestamp),
+ 'sign': signature,
+ 'cdn': '',
+ 'rate': '-1',
+ 'ver': 'Douyu_223061205',
+ 'iar': '1',
+ 'ive': '1',
+ 'hevc': '0',
+ 'fa': '0'
+ }
+ legacy_api = f"https://www.douyu.com/lapi/live/getH5Play/{channel}"
+ res = requests.post(legacy_api, data=legacy_payload, headers=headers, timeout=10)
+ return res.json() if res.status_code == 200 else None
+ except:
+ return None
+
+ def _get_douyu_play_url(self, channel, device_id, secret_key, random_str, enc_time, enc_data, rate):
+ """
+ 获取斗鱼指定码率的播放URL(带签名)
+ 用于切换清晰度时重新获取URL
+ """
+ try:
+ current_time = int(time.time())
+
+ # 重新计算签名
+ current = random_str
+ for _ in range(enc_time):
+ current = hashlib.md5(f"{current}{secret_key}".encode()).hexdigest()
+
+ signature = hashlib.md5(f"{current}{secret_key}{channel}{current_time}".encode()).hexdigest()
+
+ # 构建请求
+ play_payload = {
+ 'enc_data': enc_data,
+ 'tt': str(current_time),
+ 'did': device_id,
+ 'auth': signature,
+ 'cdn': '',
+ 'rate': str(rate) if rate > 0 else '',
+ 'hevc': '0',
+ 'fa': '0',
+ 'ive': '0'
+ }
+
+ play_api = f"https://www.douyu.com/lapi/live/getH5PlayV1/{channel}"
+
+ headers = {
+ 'User-Agent': self.headers[0]['User-Agent'],
+ 'Referer': f'https://www.douyu.com/{channel}',
+ 'Origin': 'https://www.douyu.com',
+ 'Cookie': f'dy_did={device_id}; mantine-color-scheme-value=light',
+ 'Content-Type': 'application/x-www-form-urlencoded'
+ }
+
+ play_res = requests.post(play_api, data=play_payload, headers=headers, timeout=10).json()
+
+ if not play_res or play_res.get('error') != 0:
+ # 尝试旧版API
+ return self._get_douyu_play_url_legacy(channel, device_id, signature, current_time, rate)
+
+ stream_info = play_res.get('data', {})
+
+ # 检查设备ID是否匹配
+ if stream_info.get('rtmp_live'):
+ did_match = re.search(r'did=([a-f0-9]{32})', stream_info['rtmp_live'])
+ if did_match and did_match.group(1) != device_id:
+ # 设备ID不匹配,使用新设备ID重新获取
+ return self._get_douyu_play_url(channel, did_match.group(1), secret_key, random_str, enc_time, enc_data, rate)
+
+ if stream_info.get('rtmp_url') and stream_info.get('rtmp_live'):
+ return f"{stream_info['rtmp_url']}/{stream_info['rtmp_live']}"
+ elif stream_info.get('hls_url'):
+ return stream_info['hls_url']
+
+ return None
+ except Exception as e:
+ print(f"获取斗鱼播放URL失败: {e}")
+ return None
+
+ def _get_douyu_play_url_legacy(self, channel, device_id, signature, timestamp, rate):
+ """使用旧版API获取斗鱼播放URL"""
+ try:
+ legacy_payload = {
+ 'did': device_id,
+ 'tt': str(timestamp),
+ 'sign': signature,
+ 'cdn': '',
+ 'rate': str(rate) if rate > 0 else '-1',
+ 'ver': 'Douyu_223061205',
+ 'iar': '1',
+ 'ive': '1',
+ 'hevc': '0',
+ 'fa': '0'
+ }
+ legacy_api = f"https://www.douyu.com/lapi/live/getH5Play/{channel}"
+
+ headers = {
+ 'User-Agent': self.headers[0]['User-Agent'],
+ 'Referer': f'https://www.douyu.com/{channel}',
+ 'Cookie': f'dy_did={device_id}',
+ 'Content-Type': 'application/x-www-form-urlencoded'
+ }
+
+ res = requests.post(legacy_api, data=legacy_payload, headers=headers, timeout=10)
+ if res.status_code == 200:
+ data = res.json()
+ if data.get('error') == 0:
+ stream_info = data.get('data', {})
+ if stream_info.get('rtmp_url') and stream_info.get('rtmp_live'):
+ return f"{stream_info['rtmp_url']}/{stream_info['rtmp_live']}"
+ return None
+ except:
+ return None
def searchContent(self, key, quick, pg="1"):
pass
@@ -613,12 +1060,12 @@ class Spider(Spider):
try:
ids = id.split('@@')
p = 1
- if ids[0] in ['wangyi', 'douyin','huya']:
+ if ids[0] in ['wangyi']:
p, url = 0, json.loads(self.d64(ids[1]))
elif ids[0] == 'bili':
p, url = self.biliplay(ids)
elif ids[0] == 'huya':
- p, url = 0, json.loads(self.d64(ids[1]))
+ p, url = self.huyaplay(ids)
elif ids[0] == 'douyu':
p, url = self.douyuplay(ids)
return {'parse': p, 'url': url, 'header': self.playheaders[ids[0]]}
@@ -626,69 +1073,116 @@ class Spider(Spider):
return {'parse': 1, 'url': self.excepturl, 'header': self.headers[0]}
def biliplay(self, ids):
+ """
+ B站播放解析 - 使用playUrl接口获取指定清晰度直播流
+ ids: [平台, 房间号, 清晰度qn]
+ 支持多线路返回
+ """
try:
- data = self.fetch(
- f'{self.hosts[ids[0]][0]}/xlive/web-room/v2/index/getRoomPlayInfo?room_id={ids[1]}&protocol=0,1&format=0,2&codec=0&platform=web&qn={ids[2]}',
- headers=self.gethr(0, ids[0])).json()
+ room_id = ids[1]
+ qn = ids[2] if len(ids) > 2 else '10000'
+
+ # 使用playUrl接口获取直播流
+ play_url = f'{self.hosts["bili"][0]}/room/v1/Room/playUrl?cid={room_id}&qn={qn}&platform=web'
+ data = self.fetch(play_url, headers={
+ **self.headers[0],
+ 'Referer': 'https://live.bilibili.com/',
+ 'Origin': 'https://live.bilibili.com'
+ }).json()
+
+ if data.get('code') != 0:
+ return 1, self.excepturl
+
+ play_data = data['data']
+ durl_list = play_data.get('durl', [])
+
+ if not durl_list:
+ return 1, self.excepturl
+
+ # 构建多线路结果 [线路1, URL1, 线路2, URL2, ...]
urls = []
- line_index = 1
- for stream in data['data']['playurl_info']['playurl']['stream']:
- for format_item in stream['format']:
- for codec in format_item['codec']:
- for url_info in codec['url_info']:
- full_url = f"{url_info['host']}/{codec['base_url'].lstrip('/')}{url_info['extra']}"
- urls.extend([f"线路{line_index}", full_url])
- line_index += 1
+ for idx, item in enumerate(durl_list, 1):
+ url = item.get('url')
+ if url:
+ urls.extend([f'线路{idx}', url])
+
+ # 如果只有一条线路,直接返回URL
+ if len(urls) == 2:
+ return 0, urls[1] # 直接返回URL字符串
+
return 0, urls
+
except Exception as e:
+ print(f"B站播放错误: {e}")
+ return 1, self.excepturl
+
+ def huyaplay(self, ids):
+ """
+ 虎牙播放解析 - 返回所有清晰度选项供用户选择
+ ids[1] 格式: base64编码的 [清晰度名称1, URL1, 清晰度名称2, URL2, ...]
+ """
+ try:
+ # ids[1] 是编码后的播放地址列表 [名称1, URL1, 名称2, URL2, ...]
+ decoded = json.loads(self.d64(ids[1]))
+ # decoded 是一个列表,奇数索引是名称,偶数索引是URL
+ return 0, decoded
+ except Exception as e:
+ print(f"虎牙播放解析错误: {e}")
return 1, self.excepturl
def douyuplay(self, ids):
+ """
+ 斗鱼播放解析 - 实时获取对应码率的播放URL
+ ids格式: [平台, base64(清晰度列表), base64(会话信息)]
+ 清晰度列表: [名称1, #码率1, 名称2, #码率2, ...]
+ #表示这是码率值,需要重新获取URL
+ """
try:
- sdata = json.loads(self.d64(ids[1]))
- headers = self.gethr(0, zr=f'{self.hosts[ids[0]]}/{sdata["id"]}')
- ldata = json.loads(self.d64(ids[2]))
- result_obj = {}
- with ThreadPoolExecutor(max_workers=len(ldata)) as executor:
- futures = [
- executor.submit(
- self.douyufp,
- sdata,
- quality,
- headers,
- self.hosts[ids[0]],
- result_obj
- ) for quality in ldata
- ]
- for future in futures:
- future.result()
-
+ if len(ids) < 3:
+ # 兼容旧格式
+ decoded = json.loads(self.d64(ids[1]))
+ return 0, decoded
+
+ # 解析清晰度列表和会话信息
+ qualities = json.loads(self.d64(ids[1]))
+ session_info = json.loads(self.d64(ids[2]))
+
+ channel = session_info['channel']
+ device_id = session_info['device_id']
+ secret_key = session_info['secret_key']
+ random_str = session_info['random_str']
+ enc_time = session_info['enc_time']
+ enc_data = session_info['enc_data']
+
+ # 为每个清晰度实时获取播放URL
result = []
- for bit in sorted(result_obj.keys(), reverse=True):
- result.extend(result_obj[bit])
-
- if result:
- return 0, result
- return 1, self.excepturl
-
+ for i in range(0, len(qualities), 2):
+ name = qualities[i]
+ rate_marker = qualities[i + 1]
+
+ # 解析码率值(去掉#前缀)
+ if rate_marker.startswith('#'):
+ rate = int(rate_marker[1:])
+ else:
+ rate = -1
+
+ # 实时获取对应码率的URL
+ play_url = self._get_douyu_play_url(
+ channel, device_id, secret_key, random_str,
+ enc_time, enc_data, rate
+ )
+
+ if play_url:
+ result.extend([name, play_url])
+
+ if not result:
+ return 1, self.excepturl
+
+ return 0, result
except Exception as e:
+ print(f"斗鱼播放解析错误: {e}")
return 1, self.excepturl
- def douyufp(self, sdata, quality, headers, host, result_obj):
- try:
- body = f'{sdata["sign"]}&cdn={sdata["cdn"]}&rate={quality["rate"]}'
- body=self.params_to_json(body)
- data = self.post(f'{host}/lapi/live/getH5Play/{sdata["id"]}',
- data=body, headers=headers).json()
- if data.get('data'):
- play_url = data['data']['rtmp_url'] + '/' + data['data']['rtmp_live']
- bit = quality.get('bit', 0)
- if bit not in result_obj:
- result_obj[bit] = []
- result_obj[bit].extend([quality['name'], play_url])
- except Exception as e:
- print(f"Error fetching {quality['name']}: {str(e)}")
-
def localProxy(self, param):
pass
@@ -763,5 +1257,4 @@ class Spider(Spider):
def handle_exception(self, e):
print(f"报错: {str(e)}")
- return {'vod_play_from': '哎呀翻车啦', 'vod_play_url': f'翻车啦${self.excepturl}'}
-
+ return {'vod_play_from': '哎呀翻车啦', 'vod_play_url': f'翻车啦${self.excepturl}'}
\ No newline at end of file
diff --git a/js/xiaosa/spider.jar b/js/xiaosa/spider.jar
index 67351183310441fea20451354bb5c25e8280744a..21c5266ce76e0af6eec342d29196db99b1cd60f5 100755
GIT binary patch
literal 1560852
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 bUQbYcTC>?u%tXuj)
zYgyDal~bBJ+5(YopICEHsS8|%^p9Y4T!cAUw{v!483D+PyCB2J#J*^-ZyTR5K~?SS{i^}X
zEUfK9y|;WAK$50ZTVwf)vR)K@ZG%yj$&s}pFuatRCkk4Mmj$E0Bq1}H!Om4{lEb%K
zD!Duh4Y;q*^f}4z1DVQI#-|^yH(-|s%mQ_T!z-^=fY33{L4zIPQY|pth
z?J?D9&sd-_`IFTkNt?3XN-1sKfNUeGN?TOTs17do0#XP8ia#KSkP6x@lq@Frfh9zB
z?c;e`s=2BP`^@hK7t+ry!359Z&_l;eky2*bu|A6SPTkHxBMq32z43Y7?NGa{`HfCm
zMALmnU?|`aNs8;9lm2~}riELJQ?8MV;WnqWn0_m4wOg2NI4@3P25A2Qp8kP{Iy-(y
z`fhN}zF}~7IC%E4NiNpo%9_JnBmwEN4jT(U)bb-)37gyI_O{gW3X>5O#WTY}R-tMB
zT1%j^v={bpQ#cfmKP2FY08$xZ=~YUh0^%&Cm1J4EldJx6n-xzoiZ!<>ajmzu*HFSW
z!ae2t+DMFF_Y`g)8ZLbtrfjmw8J{e_bYr7OQd}`J8PHGU8qQbMVw1?H@DOSHf@@(u
zwAjKv>1W8C=F={F9k!?^0+wt|_5>)}TZ0}@Oq_XWruaU!<~stsc~NQk#|K?bmVuK*
zk5E%S=05s%#^(+uaC_Up`?
z`73Uc$eBL>rum($9&+Nt_9DB>3Ijq_?>g*)BFOxBN6;@_A43OuNWI*1dKa>Ywcf
zN}04<^95Mqy>hD=Q&e0JnumEP#VWg=hJVLDAo;jlB)-hD5@73yDw1LjOS=rF-|D-xd(-aSu*o!66XbHCWK#k`UaTyZO$UGw00A{b%OPoPX}Ex>a43>Z0@Z+iUN=U4x6LoGkm1m(b^T-cqv3Mj^G6+ucV@FbY;(OQCkst8ltOjN@
zE5|Ho32>$4q)?h9WjyEDV2@^LpfH=xc+T^XGqpnEf`dLXE_w`j_{lD_xdW#!8P93u
zhGQsf7NMx4?&wTzavf-*J{&33>Qe5~AD8Sqy2)0(8Q)`Eetrpu5WLn4&oF
z0zSEwxlgZ%I&kqnC$Vg>eRW3zAv=z_davZi?q
z5Pu#p={|_|iUf>x8*Z*45uC~t>52O6^hgPVQ5XSk3wE4@HqPod(Z8V-(XZ=#@1e?w
z(Sp$WXe@{7D^Wk8n0CK_vxCn?1Em$2yDaudRN#_E4!Z5Hj#s&5eoi(PXvxnm5W(r
zDTN`$p5BB)_hB7rzrfv#T4Xg}-u)qal)udqWt3^Jz0jBmeTDXb(x7ADNjqzXIfDX-
zG3ltxuO2*|9FV1SZPjhWtk0;63avCnF{Xg6T
z(5BM<-eVri=UV3+(FOer7}Y>y1wcyD&~+-+M>8%XDxtSiL&ZN^o=I`|5HXw5=<*Ml
zksX9jHt}1_hyzRAI%~=U6qBccblA^f5l
z39}gwJ+<3K?clYwJKqxP{2V`q=uv!lj>@C_2&j(C;^uIMou%FlHKFaBY+)$b4|VaN
zekXfCLn9LHdl{3>*fbmo009hNqQ1B0WufX4OgW`{LL!myOpQF=u-CE}0bFSX{T2*N
zQ_TQ@^AQBloP&IyK4)|~Oe2pdOS_erw>)qeB;Pl?F(>WxRHZVqQZTj1=rL2`LjFDx
z=<0okzFzW?=wKV%PiQ>(K>Yx_mGXOqKb77p>(JTrN|>n6Gwgj*OBrQ+n0gQ;NIwAt
z>4{$!uDH2Qm{-@%B)qTawj34a5tIFhr$Ao!oHOMYvni1^SZGjc{={1mnU6|3T*-b$
zQy}MfJBJi%h99CMMJR}}PBP)v>_{1`s>&=gh;b=FAvYX5hh_#HO^~NIvUx>t0fxo5
z_kv_HwK%=iqJoJJji5~Y?Ld+N;BEVf`LV^xW2P$>AJvi&V>zf>guQya6%kY^OO#k1
z6iRqJVqD-(Ec;iLzn6tv`8j^z(pw?l-b>Juz%E2ID$zbtO#+jRPe^|%c}sEnboiBj
zI06INd9|(jX$Juq9-4~Yl#fN!V;Di|pER0y9ZKa#Q)D7YS1XshvDS(Qs^e0tNtcmm
zUo{Od>Q1BxqInC)_HHO!`&GIg9qAOqbB^9!5#o_>GBi`p18t!Av6m3Z!oNIs0jGQm;Ep`^NMY75{;nw|l4!by*gpxrdGD;8k6DYM5rQZ!lh@zR`;v{rZ
z#+3yWlPnNg)Hdr2?`o0;Q?9m12L
zi$cRmg1WMbFCM9d6LV(>eI@MVH)oINC^F}AhjbFLV##je&q>O(DX-+>uI5WTu^Ns1
z{?_ac9L4Ca5y=Wtd~FZuHI22rV-6bLS?rg}j3+{by-4Pq>EkvuDUK4mw~0{yi>09<
z+$>IzqP(KzNLTq@5rQ+j^f>tCZ-3lu^i;w@Mj*yOfK=s>PRZAiFG2cpI2K590F0uK
z1Js-|fIumAm5!<2NG+8Wca~F2oPRChI6V^982XBtg4qHi5YmUYy%&1YZbzpqqwKt|
z9=rC|oX}Cb4?Wy5guvt33wNO?TvJLBnu1n)?#w5tMDp~4b-mWcPM?JvDQJkgWx)hu
z@b;kz8ct%1@%OS+-;~uyHEu2LnNAw(*|ZomfS9sUjc>U%a$=7Mep#rd4X7(llb=Gt
z{6_GwEZS+54Q?jdO%`h^VZSylyFX@JMVjp<1;{a}-dQ*-T1Q6)d*J3!HjTVrd%NKB
zkUeQn!HmMl#)zD*t{;r}k*j*0kVHquk>F-fKCx6(4q#7nD|&@&QQHPU9e!k)=a0N7
z0qUjvWSS!uZ*z@vD0oUUZ0|mVUXJSvXA%P_8jCmAQ3!$-3@L+06|bV;*dT(i5cZ0-
zP7clMt&{p}H}<(?XWfxxkY-65NxZ9Ij&Jmb*g~t|(h;WoNK|TOOy0wz*Ghu#IHN6@
z&FBJUr`5O1qQn825pk-}Z(yvTHWGC^TPv{jvqeRUBT+{1j^B)RP`Qs#Te?zb3fPV6|KRSAq9i
z)LUd#c2!RCfhB90=3vI=%R2&Yf7)X8$Fiuw%1)3fp;PQddFuU?MPYIjG8RJ_aV5Efr(nJt%<;lizJHDtPg&(v
zc9lNl=%nJ&p?^+rQBIU`h?xCYnZ(+c`K6N0Hr16_Eb~o2t4r7SSC^GPbHB6jsS+s7Gme}biiH(
zCqtL-m(li7Ayh&ha_2n}C+cDbr__mL*`C!gaH2hd(z{!Z!Ad1L7tIJt0lpE4Nddi{
zG{CNLumy3BrviDUELPiJJ+GuV15gzx`~a51g$(I)B0KOw8a-4|gU5@-WZoOMlyUsR
z{t_5Q^NGAjU&U{Gb)5_S{j9c$7oM9Gn7$$
zv9A`r!JUb7Mc9LDUKTlSV@lpt*DeAi%s9-G1q-?*@Ai&FhaZ}i|>^%TfuvmVIu?5`zIHQM-ItqlkkZ!CJOqa&m$P|*5EPikp
ztiOB<6zzXS@q4lZYY>)-+(6w+zBYhixWo{Zy0lHxrz6ssTab>}&BnwCu
zb=~>^Pbxj@)_M%s100ZBx=3;P(rhl=J8_eb@!tpu#mxkAD$Q@ivuLP=F-bG0S5qs5g+ZIOU^`m>Xp
zF1@ADXF_%K3T9Tre$GI_?24%U?e!}_^LOLT9R$n*cJxXSLP`qYVlk?O2sE=^&dr=bP6o|`DkA}6NS&+cNx4-xtPD-+h
z3*-r&VwZ5Z?5l#&aV1dFL`m8#LE~#%gyyhqi=j)%oVO@R9$E3Pw%4>=Au2CE2MhrG
zT^cd~HYX5pTBO>W=-~rivGrCy0<14BN2(698P58dLd?-SWW%V~l$9(Lki!tX`yo2z0mbw^Ip6zVn^_#L~nSr0VxM#))JF
zv;$-i>6K5BOgd3K~u42PNbK+r(kB_A9
z{U(h^=#{Vdnd-!Qds}>PH9y?PE08vnIzYaG)mXiGCLgl!+_N*>Zu7K-?^gSrSY+>2ni_B|SVTtmfwMsa`2|T5y
z=ID{R-HM4eE0k;x7(^dfsl?}2<~;T!Z2c>?Rdo>NuM1tFiIUJaF`%Xh5Fc27tjhSg@knG?18y$vc)p?u*utWqo_nm_fsg(M
zWL3*|0X1{z)N)(wKA8e!DscR_f?-$SYsC_V9`TliWa%yZaiyd0Vz*cN5c7%n$WqDT
zoa3Wxzd4qX%_5+a+DX%}W&4{p9|K7h)<^0et;TXV0HYxy#SvD=Y;xZnWt|xd+;)0!
zqiBjuYs5+hdrm%(*&B%?Lo-67U^WItnJAD=1D837`uX(8xRH*kj$Vcc+)VDQ@qOrc-#*uOn{MY=pPur($VFmf{T0wcb6LtovaxXs9`KL`FP
zpe;alP;8Dpup|A(OsSF27^DE!4t`@cl@MVw3N1VQ0ka8P|S
z6C!L!p~Y4RXyqYq7~*d*!2@vK0r(c4_)+x7-A@ZrMAX7oR8ICN#VJ`3aR
zVQU$&KVSIX?H#`y{U=jkzbNw|{mUKSnu6(=ddVG_0*af9rkO7ZoO~1+FvW60=bvrd
zE(; JlR~hLs$143Bz?zP#EVR
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 ;BW04g0
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 | |