mirror of https://github.com/qist/tvbox
Compare commits
22 Commits
6fd303b3ca
...
2dc5742dae
Author | SHA1 | Date |
---|---|---|
![]() |
2dc5742dae | |
![]() |
e48f6cc853 | |
![]() |
50e840026d | |
![]() |
aecc0d5720 | |
![]() |
a7fdc523ce | |
![]() |
7c835063c9 | |
![]() |
af7c0fa710 | |
![]() |
03f8997c23 | |
![]() |
e627e702f3 | |
![]() |
9d4a756cf9 | |
![]() |
128eec9f05 | |
![]() |
0dbc77cbdf | |
![]() |
002a4c2fba | |
![]() |
ee13461bd5 | |
![]() |
3a00f6cc00 | |
![]() |
b11cdd5ab3 | |
![]() |
c717c5cc05 | |
![]() |
c5c8bb2a28 | |
![]() |
3b08f703c1 | |
![]() |
a913005742 | |
![]() |
4dcbced56c | |
![]() |
fe2d34282f |
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"spider":"./jar/fan.txt;md5;2c6500c44ee7e7b915f8c0afb0723e50",
|
||||
"spider":"./jar/fan.txt;md5;5451e3dec4d06a33b04962d8dde7f842",
|
||||
"logo":"https://avatars.githubusercontent.com/u/58679624?v=4",
|
||||
"lives":[{"name":"初秋语•ipv4","type":0,"url":"./list.txt","playerType":2,"epg":"http://epg.112114.xyz/?ch={name}&date={date}","logo": "https://live.fanmingming.com/tv/{name}.png"},
|
||||
{"name":"YanG•综合","type":0,"url":"https://tv.iill.top/m3u/Gather","ua": "okhttp/3.15","playerType":2,"epg":"http://epg.112114.xyz/?ch={name}&date={date}"},
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"spider":"./jar/fan.txt;md5;2c6500c44ee7e7b915f8c0afb0723e50",
|
||||
"spider":"./jar/fan.txt;md5;5451e3dec4d06a33b04962d8dde7f842",
|
||||
"wallpaper":"https://深色壁纸.xxooo.cf/",
|
||||
|
||||
"sites":[
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"spider":"./jar/fan.txt;md5;2c6500c44ee7e7b915f8c0afb0723e50",
|
||||
"spider":"./jar/fan.txt;md5;5451e3dec4d06a33b04962d8dde7f842",
|
||||
"lives":[
|
||||
{"name":"live","boot": false,"type":0,"url":"./tv.txt","playerType":2,"ua":"okhttp/3.8.1","timeout":20,"epg":"https://epg.112114.xyz/?ch={name}&date={date}","logo":"https://logo.ugigc.dpdns.org/{name}.png"}
|
||||
{"name":"live","boot": false,"type":0,"url":"./tv.txt","playerType":1,"ua":"okhttp/3.8.1","timeout":20,"epg":"https://epg.112114.xyz/?ch={name}&date={date}","logo":"https://logo.ugigc.dpdns.org/{name}.png"}
|
||||
],
|
||||
"wallpaper":"https://qist.cc/api/api.php",
|
||||
"sites":[
|
||||
|
@ -24,13 +24,11 @@
|
|||
{"key":"Lib","name":"🌟立播┃秒播","type":3,"api":"csp_LibvioGuard","timeout":10,"searchable":1,"quickSearch":1,"changeable":1,"ext":{"Cloud-drive":"tvfan/Cloud-drive.txt","from":"4k|auto"}},
|
||||
{"key":"zxzj","name":"🍊在线┃秒播","type":3,"api":"csp_ZxzjGuard","timeout":10,"searchable":1,"quickSearch":1,"changeable":1,"ext":"https://www.zxzjhd.com/"},
|
||||
{"key":"厂长","name":"📔厂长┃不卡","type":3,"api":"csp_NewCzGuard","timeout":10,"playerType":2,"searchable":1,"quickSearch":1,"changeable":1},
|
||||
{"key":"溢彩","name":"💡流光┃秒播","type":3,"api":"csp_AppSxGuard","timeout":10,"searchable":1,"quickSearch":1,"changeable":1,"ext":"rfOb1uAWbkRHp7hdxprG9un3+T/f19e82TUvZMviAElDfhsS/jcju7U0fe1MnN1h63CTaYIPjmEw9C0qVsgBO8um85+eGlSkG/r2q6m0DA=="},
|
||||
{"key":"比特","name":"🍄比特┃手机","type":3,"api":"csp_BttwooGuard","timeout":10,"searchable":1,"quickSearch":1,"changeable":1},
|
||||
{"key":"低端","name":"⏮️低端┃外剧","type":3,"api":"csp_DdrkGuard","timeout":10,"playerType":"2","searchable":1,"quickSearch":1,"changeable":1},
|
||||
{"key":"萌米","name":"👀萌米┃多线","type":3,"api":"csp_AppTTGuard","timeout":10,"playerType":2,"searchable":1,"quickSearch":1,"changeable":1,"ext":"uqGL1bNENEIVq+dC1p/Y9uWjuA=="},
|
||||
{"key":"热播","name":"📺热播┃多线","type":3,"api":"csp_AppTTGuard","timeout":10,"playerType":2,"searchable":1,"quickSearch":1,"changeable":1,"ext":"uqGL1bNENExT7/hGxpSE5qU="},
|
||||
{"key":"兄弟","name":"🍊水星┃多线","type":3,"api":"csp_AppSxGuard","timeout":10,"searchable":1,"quickSearch":1,"filterable":1,"ext":"rfOb1uAWbkRHp7hdxprG9un3+SLP183q3ik3cJDiAwlFdF8L6SIvrvc9LrpTyIg76T7QJZdEkWNj43wiSaA0TJyQpu2IF2jsSLWFx7WkAmG40hFxJ1tI+Jf+EVG8DtoDRcNi+TtVGULnWrSz3EWnVcxR3EJhXnrwYWe1kJtNW5txuHAO"},
|
||||
{"key":"神车","name":"🐻小熊┃秒播","type":3,"api":"csp_AppSxGuard","timeout":10,"searchable":1,"quickSearch":0,"changeable":0,"ext":"rfOX1voDIQhH8epBwpmIsuS8oz/VnNfnxigtaMviCwldcRBVvSwnsuM5MM4OgfA64zPRJJ0UnjpsuU0yDQ=="},
|
||||
{"key":"欢视","name":"👓欢视┃多线","type":3,"api":"csp_AppTTGuard","timeout":10,"playerType":2,"searchable":1,"quickSearch":1,"changeable":1,"ext":"uqGL1bNENExT9fFAy5mE5qU="},
|
||||
{"key":"奥特","name":"🏝奥特┃多线","type":3,"api":"csp_AueteGuard","timeout":10,"searchable":1,"quickSearch":1,"changeable":1,"ext":"https://auete.com/"},
|
||||
{"key":"贱贱","name":"🐭荐片┃P2P","type":3,"api":"csp_JPJGuard","timeout":10,"playerType":2,"searchable":1,"quickSearch":1,"changeable":0},
|
||||
|
|
BIN
jar/fan.txt
BIN
jar/fan.txt
Binary file not shown.
|
@ -1,7 +1,7 @@
|
|||
var rule = {
|
||||
title:'闪雷影视',
|
||||
编码:'gb2312',
|
||||
host:'http://sl.hdkszx.com:808',
|
||||
host:'http://iptv.hdkszx.com:808',
|
||||
url:'/www/List.asp?classid=fyclass&searchword=&page=fypage',
|
||||
filterable:0,//是否启用分类筛选,
|
||||
class_name:'电影&电视剧&综艺&动漫&音乐',
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
var rule = {
|
||||
title: 'TVB云播',
|
||||
//模板:'mxpro',
|
||||
host: 'http://www.tvyun07.com',
|
||||
host: 'http://www.tvyb03.com',
|
||||
url: 'vod/show/id/fyfilter.html',
|
||||
filterable: 1,//是否启用分类筛选,
|
||||
filter_url: '{{fl.cateId}}{{fl.area}}{{fl.by}}{{fl.class}}{{fl.lang}}{{fl.letter}}/page/fypage{{fl.year}}',
|
||||
|
|
4
jsm.json
4
jsm.json
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"spider":"./jar/fan.txt;md5;2c6500c44ee7e7b915f8c0afb0723e50",
|
||||
"spider":"./jar/fan.txt;md5;5451e3dec4d06a33b04962d8dde7f842",
|
||||
"lives":[
|
||||
{"name": "ITV","type": 0,"url": "./ITV.txt","epg": "http://epg.51zmt.top:8000/e.xml","ua": "okhttp/3.15,AptvPlayer/1.4.0","timeout": 3,"playerType": 2},
|
||||
{"name":"fmm","type":0,"url":"https://live.fanmingming.com/tv/m3u/ipv6.m3u","playerType":1,"ua":"okhttp/3.8.1","timeout":20,"epg":"https://epg.112114.xyz/?ch={name}&date={date}","logo":"https://epg.112114.xyz/logo/{name}.png"},
|
||||
|
@ -27,13 +27,11 @@
|
|||
{"key":"Lib","name":"🌟立播┃秒播","type":3,"api":"csp_LibvioGuard","timeout":10,"searchable":1,"quickSearch":1,"changeable":1,"ext":{"Cloud-drive":"tvfan/Cloud-drive.txt","from":"4k|auto"}},
|
||||
{"key":"zxzj","name":"🍊在线┃秒播","type":3,"api":"csp_ZxzjGuard","timeout":10,"searchable":1,"quickSearch":1,"changeable":1,"ext":"https://www.zxzjhd.com/"},
|
||||
{"key":"厂长","name":"📔厂长┃不卡","type":3,"api":"csp_NewCzGuard","timeout":10,"playerType":2,"searchable":1,"quickSearch":1,"changeable":1},
|
||||
{"key":"溢彩","name":"💡流光┃秒播","type":3,"api":"csp_AppSxGuard","timeout":10,"searchable":1,"quickSearch":1,"changeable":1,"ext":"rfOb1uAWbkRHp7hdxprG9un3+T/f19e82TUvZMviAElDfhsS/jcju7U0fe1MnN1h63CTaYIPjmEw9C0qVsgBO8um85+eGlSkG/r2q6m0DA=="},
|
||||
{"key":"比特","name":"🍄比特┃手机","type":3,"api":"csp_BttwooGuard","timeout":10,"searchable":1,"quickSearch":1,"changeable":1},
|
||||
{"key":"低端","name":"⏮️低端┃外剧","type":3,"api":"csp_DdrkGuard","timeout":10,"playerType":"2","searchable":1,"quickSearch":1,"changeable":1},
|
||||
{"key":"萌米","name":"👀萌米┃多线","type":3,"api":"csp_AppTTGuard","timeout":10,"playerType":2,"searchable":1,"quickSearch":1,"changeable":1,"ext":"uqGL1bNENEIVq+dC1p/Y9uWjuA=="},
|
||||
{"key":"热播","name":"📺热播┃多线","type":3,"api":"csp_AppTTGuard","timeout":10,"playerType":2,"searchable":1,"quickSearch":1,"changeable":1,"ext":"uqGL1bNENExT7/hGxpSE5qU="},
|
||||
{"key":"兄弟","name":"🍊水星┃多线","type":3,"api":"csp_AppSxGuard","timeout":10,"searchable":1,"quickSearch":1,"filterable":1,"ext":"rfOb1uAWbkRHp7hdxprG9un3+SLP183q3ik3cJDiAwlFdF8L6SIvrvc9LrpTyIg76T7QJZdEkWNj43wiSaA0TJyQpu2IF2jsSLWFx7WkAmG40hFxJ1tI+Jf+EVG8DtoDRcNi+TtVGULnWrSz3EWnVcxR3EJhXnrwYWe1kJtNW5txuHAO"},
|
||||
{"key":"神车","name":"🐻小熊┃秒播","type":3,"api":"csp_AppSxGuard","timeout":10,"searchable":1,"quickSearch":0,"changeable":0,"ext":"rfOX1voDIQhH8epBwpmIsuS8oz/VnNfnxigtaMviCwldcRBVvSwnsuM5MM4OgfA64zPRJJ0UnjpsuU0yDQ=="},
|
||||
{"key":"欢视","name":"👓欢视┃多线","type":3,"api":"csp_AppTTGuard","timeout":10,"playerType":2,"searchable":1,"quickSearch":1,"changeable":1,"ext":"uqGL1bNENExT9fFAy5mE5qU="},
|
||||
{"key":"奥特","name":"🏝奥特┃多线","type":3,"api":"csp_AueteGuard","timeout":10,"searchable":1,"quickSearch":1,"changeable":1,"ext":"https://auete.com/"},
|
||||
{"key":"贱贱","name":"🐭荐片┃P2P","type":3,"api":"csp_JPJGuard","timeout":10,"playerType":2,"searchable":1,"quickSearch":1,"changeable":0},
|
||||
|
|
693
xiaosa/api.json
693
xiaosa/api.json
|
@ -38,7 +38,7 @@
|
|||
},
|
||||
{
|
||||
"key": "热播影视",
|
||||
"name": "热播|影视",
|
||||
"name": "热播|APP",
|
||||
"type": 3,
|
||||
"api": "csp_AppRJ",
|
||||
"searchable": 1,
|
||||
|
@ -50,7 +50,7 @@
|
|||
},
|
||||
{
|
||||
"key": "天天影视",
|
||||
"name": "天天|影视",
|
||||
"name": "天天|APP",
|
||||
"type": 3,
|
||||
"api": "csp_AppRJ",
|
||||
"searchable": 1,
|
||||
|
@ -62,7 +62,7 @@
|
|||
},
|
||||
{
|
||||
"key": "浪酷影视",
|
||||
"name": "浪酷|影视",
|
||||
"name": "浪酷|APP",
|
||||
"type": 3,
|
||||
"api": "csp_AppRJ",
|
||||
"searchable": 1,
|
||||
|
@ -74,20 +74,209 @@
|
|||
},
|
||||
{
|
||||
"key": "菲儿影视",
|
||||
"name": "菲菲|影视",
|
||||
"name": "菲儿|APP",
|
||||
"type": 3,
|
||||
"api": "csp_AppFerr",
|
||||
"ext": "sHR2rlsfjI4L3t4RXQMkn/M3t4AXAKTrZj3tfhm1t/gMT3dOrHqIzUNqLUEOIDMvllTbX6e1hMhB2mfpOaCmHNOL1yBB3SmxNyqXlai90EIpdnwOOgCR9Z+YwCTj6ySjzJ2VBiH3eXeOGcavcNeVRA=="
|
||||
"ext": {
|
||||
"url": "https://appcms.freehd.vip",
|
||||
"dataKey": "be5348dfb0c3c283",
|
||||
"dataIv": "5f5449dd14313217"
|
||||
}
|
||||
},
|
||||
{
|
||||
"key": "影探影视",
|
||||
"name": "影探|影视",
|
||||
"key": "彼岸",
|
||||
"name": "彼岸|APP",
|
||||
"type": 3,
|
||||
"api": "csp_AppYsV2",
|
||||
"searchable": 1,
|
||||
"quickSearch": 1,
|
||||
"filterable": 1,
|
||||
"ext": "http://cmsyt114.lyyytv.cn/api.php/app/"
|
||||
"api": "csp_AppGet",
|
||||
"ext": {
|
||||
"url": "http://172.247.44.217:30011",
|
||||
"dataKey": "JLa1oRdL6+eK7@M)",
|
||||
"dataIv": "JLa1oRdL6+eK7@M)",
|
||||
"deviceId": "",
|
||||
"version": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"key": "时常",
|
||||
"name": "时常|APP",
|
||||
"type": 3,
|
||||
"quickSearch": 1,
|
||||
"api": "csp_AppGet",
|
||||
"ext": {
|
||||
"url": "http://111.180.198.40:1110",
|
||||
"dataKey": "asgcxhjkts124573",
|
||||
"dataIv": "asgcxhjkts124573",
|
||||
"deviceId": "",
|
||||
"version": "101"
|
||||
}
|
||||
},
|
||||
{
|
||||
"key": "雨滴",
|
||||
"name": "雨滴|APP",
|
||||
"type": 3,
|
||||
"quickSearch": 1,
|
||||
"api": "csp_AppGet",
|
||||
"ext": {
|
||||
"url": "https://c8w2ov7u5wg2z1o8p21c.aliyuncs.click:27899",
|
||||
"dataKey": "k9o3p2c8b7m3z0o8",
|
||||
"dataIv": "k9o3p2c8b7m3z0o8",
|
||||
"deviceId": "",
|
||||
"version": "100"
|
||||
}
|
||||
},
|
||||
{
|
||||
"key": "玉米",
|
||||
"name": "玉米|APP",
|
||||
"type": 3,
|
||||
"quickSearch": 1,
|
||||
"api": "csp_AppGet",
|
||||
"ext": {
|
||||
"url": "https://www.zjc.app",
|
||||
"dataKey": "ab4e9a421675f14b",
|
||||
"dataIv": "ab4e9a421675f14b",
|
||||
"deviceId": "",
|
||||
"version": "442"
|
||||
}
|
||||
},
|
||||
{
|
||||
"key": "优质",
|
||||
"name": "优质|APP",
|
||||
"type": 3,
|
||||
"quickSearch": 1,
|
||||
"api": "csp_AppGet",
|
||||
"ext": {
|
||||
"url": "https://apiapplbys.lbys.cc:5678",
|
||||
"dataKey": "apiapplbyskey168",
|
||||
"dataIv": "apiapplbyskey168",
|
||||
"deviceId": "",
|
||||
"version": "107"
|
||||
}
|
||||
},
|
||||
{
|
||||
"key": "木叶",
|
||||
"name": "木叶|APP",
|
||||
"type": 3,
|
||||
"quickSearch": 1,
|
||||
"api": "csp_AppGet",
|
||||
"ext": {
|
||||
"url": "http://46.203.125.54:2663",
|
||||
"dataKey": "RuN9LRvwTRgpQnpK",
|
||||
"dataIv": "RuN9LRvwTRgpQnpK",
|
||||
"deviceId": "",
|
||||
"version": "547"
|
||||
}
|
||||
},
|
||||
{
|
||||
"key": "米兔",
|
||||
"name": "米兔|APP",
|
||||
"type": 3,
|
||||
"quickSearch": 1,
|
||||
"api": "csp_AppGet",
|
||||
"ext": {
|
||||
"url": "https://www.zjc.app",
|
||||
"dataKey": "ab4e9a421675f14b",
|
||||
"dataIv": "ab4e9a421675f14b",
|
||||
"deviceId": "",
|
||||
"version": "442"
|
||||
}
|
||||
},
|
||||
{
|
||||
"key": "光速",
|
||||
"name": "光速|APP",
|
||||
"type": 3,
|
||||
"quickSearch": 1,
|
||||
"api": "csp_AppGet",
|
||||
"ext": {
|
||||
"url": "http://59.153.167.137:8899",
|
||||
"dataKey": "4d83b87c4c5ea111",
|
||||
"dataIv": "4d83b87c4c5ea111",
|
||||
"deviceId": "",
|
||||
"version": "462"
|
||||
}
|
||||
},
|
||||
{
|
||||
"key": "格格",
|
||||
"name": "格格|APP",
|
||||
"type": 3,
|
||||
"quickSearch": 1,
|
||||
"api": "csp_AppGet",
|
||||
"ext": {
|
||||
"url": "http://111.180.198.40:1110",
|
||||
"dataKey": "asgcxhjkts124573",
|
||||
"dataIv": "asgcxhjkts124573",
|
||||
"deviceId": "",
|
||||
"version": "119"
|
||||
}
|
||||
},
|
||||
{
|
||||
"key": "悠悠",
|
||||
"name": "悠悠|APP",
|
||||
"type": 3,
|
||||
"quickSearch": 1,
|
||||
"api": "csp_AppGet",
|
||||
"ext": {
|
||||
"url": "http://156.225.30.65:5566",
|
||||
"dataKey": "DxwIstrdWbYpblwn",
|
||||
"dataIv": "DxwIstrdWbYpblwn",
|
||||
"deviceId": "",
|
||||
"version": "119"
|
||||
}
|
||||
},
|
||||
{
|
||||
"key": "晴天",
|
||||
"name": "晴天|APP",
|
||||
"type": 3,
|
||||
"quickSearch": 1,
|
||||
"api": "csp_AppGet",
|
||||
"ext": {
|
||||
"url": "https://appcms.sun4k.top",
|
||||
"dataKey": "b025dcd9c289cbb3",
|
||||
"dataIv": "b025dcd9c289cbb3",
|
||||
"deviceId": "",
|
||||
"version": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"key": "在看",
|
||||
"name": "在看|APP",
|
||||
"type": 3,
|
||||
"quickSearch": 1,
|
||||
"api": "csp_AppGet",
|
||||
"ext": {
|
||||
"url": "http://149.88.64.161:9525",
|
||||
"dataKey": "123456789ABCDEFG",
|
||||
"dataIv": "123456789ABCDEFG",
|
||||
"deviceId": "",
|
||||
"version": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"key": "星河",
|
||||
"name": "星河|APP",
|
||||
"type": 3,
|
||||
"quickSearch": 1,
|
||||
"api": "csp_AppGet",
|
||||
"ext": {
|
||||
"url": "http://121.62.22.204:9876",
|
||||
"dataKey": "f5e2tx53ykp6s2c9",
|
||||
"dataIv": "f5e2tx53ykp6s2c9",
|
||||
"deviceId": "",
|
||||
"version": "361"
|
||||
}
|
||||
},
|
||||
{
|
||||
"key": "追忆",
|
||||
"name": "追忆|APP",
|
||||
"type": 3,
|
||||
"quickSearch": 0,
|
||||
"api": "csp_AppMiTo",
|
||||
"ext": {
|
||||
"url": "http://110.42.7.130:1866",
|
||||
"dataKey": "aassddwwxxllsx1x",
|
||||
"playKey": "1bada76e67e1e7f9",
|
||||
"version": "1.2.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"key": "哔哩视频",
|
||||
|
@ -172,7 +361,7 @@
|
|||
"searchable": 1,
|
||||
"quickSearch": 1,
|
||||
"filterable": 1,
|
||||
"ext": "./json/wogg.json?"
|
||||
"ext": "./json/wogg.json"
|
||||
},
|
||||
{
|
||||
"key": "木偶",
|
||||
|
@ -182,7 +371,7 @@
|
|||
"searchable": 1,
|
||||
"quickSearch": 1,
|
||||
"filterable": 1,
|
||||
"ext": "./json/mogg.json?"
|
||||
"ext": "./json/mogg.json"
|
||||
},
|
||||
{
|
||||
"key": "蜡笔",
|
||||
|
@ -193,18 +382,7 @@
|
|||
"quickSearch": 1,
|
||||
"filterable": 1,
|
||||
"changeable": 1,
|
||||
"ext": "./json/lb.json?"
|
||||
},
|
||||
{
|
||||
"key": "小米",
|
||||
"name": "小米|4K弹幕",
|
||||
"type": 3,
|
||||
"api": "csp_PanWebShare",
|
||||
"searchable": 1,
|
||||
"quickSearch": 1,
|
||||
"filterable": 1,
|
||||
"changeable": 1,
|
||||
"ext": "./json/xm.json?"
|
||||
"ext": "./json/lb.json"
|
||||
},
|
||||
{
|
||||
"key": "至臻",
|
||||
|
@ -215,7 +393,7 @@
|
|||
"quickSearch": 1,
|
||||
"filterable": 1,
|
||||
"changeable": 1,
|
||||
"ext": "./json/zz.json?"
|
||||
"ext": "./json/zz.json"
|
||||
},
|
||||
{
|
||||
"key": "多多",
|
||||
|
@ -226,7 +404,7 @@
|
|||
"quickSearch": 1,
|
||||
"filterable": 1,
|
||||
"changeable": 1,
|
||||
"ext": "./json/yyds.json?"
|
||||
"ext": "./json/yyds.json"
|
||||
},
|
||||
{
|
||||
"key": "欧哥",
|
||||
|
@ -237,7 +415,7 @@
|
|||
"quickSearch": 1,
|
||||
"filterable": 1,
|
||||
"changeable": 1,
|
||||
"ext": "./json/og.json?"
|
||||
"ext": "./json/og.json"
|
||||
},
|
||||
{
|
||||
"key": "二小",
|
||||
|
@ -248,7 +426,7 @@
|
|||
"quickSearch": 1,
|
||||
"filterable": 1,
|
||||
"changeable": 1,
|
||||
"ext": "./json/ex.json?"
|
||||
"ext": "./json/ex.json"
|
||||
},
|
||||
{
|
||||
"key": "百家",
|
||||
|
@ -259,7 +437,7 @@
|
|||
"quickSearch": 1,
|
||||
"filterable": 1,
|
||||
"changeable": 1,
|
||||
"ext": "./json/bj.json?"
|
||||
"ext": "./json/bj.json"
|
||||
},
|
||||
{
|
||||
"key": "大玩",
|
||||
|
@ -270,7 +448,7 @@
|
|||
"quickSearch": 1,
|
||||
"filterable": 1,
|
||||
"changeable": 1,
|
||||
"ext": "./json/dawo.json?"
|
||||
"ext": "./json/dawo.json"
|
||||
},
|
||||
{
|
||||
"key": "虎斑",
|
||||
|
@ -281,7 +459,7 @@
|
|||
"quickSearch": 1,
|
||||
"filterable": 1,
|
||||
"changeable": 1,
|
||||
"ext": "./json/hb.json?"
|
||||
"ext": "./json/hb.json"
|
||||
},
|
||||
{
|
||||
"key": "闪电",
|
||||
|
@ -292,7 +470,7 @@
|
|||
"quickSearch": 1,
|
||||
"filterable": 1,
|
||||
"changeable": 1,
|
||||
"ext": "./json/sd.json?"
|
||||
"ext": "./json/sd.json"
|
||||
},
|
||||
{
|
||||
"key": "下饭",
|
||||
|
@ -303,7 +481,7 @@
|
|||
"quickSearch": 1,
|
||||
"filterable": 1,
|
||||
"changeable": 1,
|
||||
"ext": "./json/xf.json?"
|
||||
"ext": "./json/xf.json"
|
||||
},
|
||||
{
|
||||
"key": "团长",
|
||||
|
@ -328,7 +506,7 @@
|
|||
"type": "list",
|
||||
"ratio": 1.433
|
||||
},
|
||||
"ext": "./json/lj.json?"
|
||||
"ext": "./json/lj.json"
|
||||
},
|
||||
{
|
||||
"key": "海绵",
|
||||
|
@ -343,7 +521,7 @@
|
|||
"type": "list",
|
||||
"ratio": 1.433
|
||||
},
|
||||
"ext": "./json/hm.json?"
|
||||
"ext": "./json/hm.json"
|
||||
},
|
||||
{
|
||||
"key": "Pan1",
|
||||
|
@ -358,7 +536,22 @@
|
|||
"type": "list",
|
||||
"ratio": 1.433
|
||||
},
|
||||
"ext": "./json/pan1.json?"
|
||||
"ext": "./json/pan1.json"
|
||||
},
|
||||
{
|
||||
"key": "夸父",
|
||||
"name": "夸父|4K",
|
||||
"type": 3,
|
||||
"api": "csp_PanWebShareCloudKF",
|
||||
"searchable": 1,
|
||||
"quickSearch": 1,
|
||||
"filterable": 1,
|
||||
"changeable": 1,
|
||||
"style": {
|
||||
"type": "list",
|
||||
"ratio": 1.433
|
||||
},
|
||||
"ext": "./json/kf.json"
|
||||
},
|
||||
{
|
||||
"key": "趣盘",
|
||||
|
@ -415,10 +608,23 @@
|
|||
"key": "河马短剧",
|
||||
"name": "河马|短剧",
|
||||
"type": 3,
|
||||
"api": "csp_AppHMDJ",
|
||||
"api": "./py/河马短剧.py",
|
||||
"searchable": 1,
|
||||
"quickSearch": 0,
|
||||
"filterable": 0
|
||||
"changeable": 1,
|
||||
"quickSearch": 1,
|
||||
"filterable": 1,
|
||||
"playerType": 2
|
||||
},
|
||||
{
|
||||
"key": "偷乐短剧",
|
||||
"name": "偷乐|短剧",
|
||||
"type": 3,
|
||||
"api": "./py/偷乐短剧.py",
|
||||
"searchable": 1,
|
||||
"changeable": 1,
|
||||
"quickSearch": 1,
|
||||
"filterable": 1,
|
||||
"playerType": 2
|
||||
},
|
||||
{
|
||||
"key": "爱看短剧",
|
||||
|
@ -431,16 +637,6 @@
|
|||
"filterable": 1,
|
||||
"playerType": 2
|
||||
},
|
||||
{
|
||||
"key": "爱我短剧",
|
||||
"name": "爱我|短剧",
|
||||
"type": 3,
|
||||
"api": "csp_XBPQ",
|
||||
"searchable": 1,
|
||||
"quickSearch": 1,
|
||||
"filterable": 1,
|
||||
"ext": "./XBPQ/爱我短剧.json"
|
||||
},
|
||||
{
|
||||
"key": "短剧网",
|
||||
"name": "短剧网|短剧",
|
||||
|
@ -458,9 +654,19 @@
|
|||
"filterable": 1,
|
||||
"ext": "./XYQHiker/短剧屋.json"
|
||||
},
|
||||
{
|
||||
"key": "QD4K",
|
||||
"name": "QD影视|影视",
|
||||
"type": 3,
|
||||
"api": "csp_AppYsV2",
|
||||
"searchable": 1,
|
||||
"quickSearch": 1,
|
||||
"filterable": 1,
|
||||
"ext": "http://172.83.156.150:1010/api.php/app/"
|
||||
},
|
||||
{
|
||||
"key": "HG影视",
|
||||
"name": "HG影视|APP",
|
||||
"name": "HG影视|影视",
|
||||
"type": 3,
|
||||
"api": "csp_AppYsV2",
|
||||
"searchable": 1,
|
||||
|
@ -483,7 +689,7 @@
|
|||
},
|
||||
{
|
||||
"key": "猎手影视",
|
||||
"name": "猎手|APP",
|
||||
"name": "猎手|影视",
|
||||
"type": 3,
|
||||
"api": "./py/猎手影视.py",
|
||||
"searchable": 1,
|
||||
|
@ -494,7 +700,7 @@
|
|||
},
|
||||
{
|
||||
"key": "火车影视",
|
||||
"name": "火车|APP",
|
||||
"name": "火车|影视",
|
||||
"type": 3,
|
||||
"api": "./py/火车影视.py",
|
||||
"searchable": 1,
|
||||
|
@ -505,7 +711,7 @@
|
|||
},
|
||||
{
|
||||
"key": "美帕影视",
|
||||
"name": "美帕|APP",
|
||||
"name": "美帕|影视",
|
||||
"type": 3,
|
||||
"api": "./py/美帕影视.py",
|
||||
"searchable": 1,
|
||||
|
@ -516,7 +722,7 @@
|
|||
},
|
||||
{
|
||||
"key": "嗨皮影视",
|
||||
"name": "嗨皮|APP",
|
||||
"name": "嗨皮|影视",
|
||||
"type": 3,
|
||||
"api": "./py/嗨皮影视.py",
|
||||
"searchable": 1,
|
||||
|
@ -525,209 +731,17 @@
|
|||
"filterable": 1,
|
||||
"playerType": 2
|
||||
},
|
||||
{
|
||||
"key": "巧技",
|
||||
"name": "巧技|APP",
|
||||
"type": 3,
|
||||
"api": "csp_qiao2",
|
||||
"playerType": 2,
|
||||
"ext": "https://fs-im-kefu.7moor-fs1.com/ly/4d2c3f00-7d4c-11e5-af15-41bf63ae4ea0/1740038979341/cksp.txt"
|
||||
},
|
||||
{
|
||||
"key": "木头",
|
||||
"name": "木头|APP",
|
||||
"type": 3,
|
||||
"api": "csp_Shark",
|
||||
"playerType": 1,
|
||||
"ext": "saHR0cDovL2Ntcy5taXRvdHYuY29tL3xhYXNzZGR3d3h4bGxzeDF4fGJic3NxZGJic3NsbDI1c3g="
|
||||
},
|
||||
{
|
||||
"key": "永夜",
|
||||
"name": "永夜|APP",
|
||||
"type": 3,
|
||||
"api": "csp_Muou",
|
||||
"playerType": 2,
|
||||
"ext": "caHR0cHM6Ly9yeHlzeXlkcy5vc3MtY24tY2hlbmdkdS5hbGl5dW5jcy5jb20vZ2V0YXBwLnR4dHxlYmFkM2YxYTU4YjEzOTMzfGViYWQzZjFhNThiMTM5MzN8MTAw"
|
||||
},
|
||||
{
|
||||
"key": "星河",
|
||||
"name": "星河|APP",
|
||||
"type": 3,
|
||||
"api": "csp_Muou",
|
||||
"playerType": 2,
|
||||
"ext": "caHR0cDovL3Rlbmd4dW55dW5hbGl5dW4ub3NzLWNuLXNoYW5naGFpLmFsaXl1bmNzLmNvbS90ZW5neHVueXVuLnR4dHxmNWUydHg1M3lrcDZzMmM5fGY1ZTJ0eDUzeWtwNnMyYzl8MzYx"
|
||||
},
|
||||
{
|
||||
"key": "油条",
|
||||
"name": "油条|APP",
|
||||
"type": 3,
|
||||
"api": "csp_Muou",
|
||||
"playerType": 2,
|
||||
"ext": "caHR0cDovLzU5LjE1My4xNjcuMTM3Ojg4OTl8NGQ4M2I4N2M0YzVlYTExMXw0ZDgzYjg3YzRjNWVhMTExfDQ2Mg=="
|
||||
},
|
||||
{
|
||||
"key": "二三",
|
||||
"name": "二三|App",
|
||||
"name": "二三|影视",
|
||||
"type": 3,
|
||||
"api": "csp_Muou",
|
||||
"playerType": 2,
|
||||
"ext": "caHR0cHM6Ly8xMjN5c3cuY29tfDIz5b2x6KeGfDQuMS44"
|
||||
},
|
||||
{
|
||||
"key": "主角",
|
||||
"name": "主角|APP",
|
||||
"type": 3,
|
||||
"api": "csp_Xdai",
|
||||
"playerType": 2,
|
||||
"ext": "caHR0cHM6Ly9kdHltLnpqeXkuY2MvZ2ctZ2V0YXBwL2dldC1nZy50eHR8UE1LYVprQXY0UXA1M0VXbnxQTUthWmtBdjRRcDUzRVdufDQyNQ=="
|
||||
},
|
||||
{
|
||||
"key": "时常",
|
||||
"name": "时常|APP",
|
||||
"type": 3,
|
||||
"api": "csp_Xdai",
|
||||
"playerType": 1,
|
||||
"ext": "jaHR0cDovLzExMS4xODAuMTk4LjQwOjExMTB8YXNnY3hoamt0czEyNDU3M3xhc2djeGhqa3RzMTI0NTczfDEwMQ=="
|
||||
},
|
||||
{
|
||||
"key": "雨滴",
|
||||
"name": "雨滴|APP",
|
||||
"type": 3,
|
||||
"api": "csp_Xdai",
|
||||
"playerType": 1,
|
||||
"ext": "jaHR0cHM6Ly95ZHlzZHluYW1pY2RvbWFpbm5hbWUuNjguZ3k6MTA2NzgvYzltMmpzMjk4eDgyaDYvbDltOGJ4MjNqMm8ycDlxL2R5bmFtaWNkb21haW5uYW1lLnR4dHxrOW8zcDJjOGI3bTN6MG84fGs5bzNwMmM4YjdtM3owbzh8MTAw"
|
||||
},
|
||||
{
|
||||
"key": "现代",
|
||||
"name": "现代|APP",
|
||||
"type": 3,
|
||||
"api": "csp_Xdai",
|
||||
"playerType": 1,
|
||||
"ext": "caHR0cHM6Ly9jbXMud2xiYnEueHl6fHNkZXYxNXJ3c2E5NmZzZGV8c2RldjE1cndzYTk2ZnNkZXwzMDA="
|
||||
},
|
||||
{
|
||||
"key": "淘气",
|
||||
"name": "淘气|APP",
|
||||
"type": 3,
|
||||
"api": "csp_Xdai",
|
||||
"playerType": 1,
|
||||
"ext": "jaHR0cHM6Ly9za2FwLm9zcy1jbi1oYW5nemhvdS5hbGl5dW5jcy5jb20vZ2V0LnR4dHw0OTkwNDg4MjQ4OTA0ODg0fDQ5OTA0ODgyNDg5MDQ4ODR8MTA3"
|
||||
},
|
||||
{
|
||||
"key": "玉米",
|
||||
"name": "玉米|APP",
|
||||
"type": 3,
|
||||
"api": "csp_Xdai",
|
||||
"playerType": 1,
|
||||
"ext": "jaHR0cHM6Ly93d3cuempjLmFwcC98YWI0ZTlhNDIxNjc1ZjE0YnxhYjRlOWE0MjE2NzVmMTRifDQ0Mg=="
|
||||
},
|
||||
{
|
||||
"key": "优质",
|
||||
"name": "优质|APP",
|
||||
"type": 3,
|
||||
"api": "csp_Xdai",
|
||||
"playerType": 1,
|
||||
"ext": "jaHR0cHM6Ly9sYnlzYXBpZHR5bWd4LjY4Lmd5OjE2Nzg5L2xieXNhcGlkdHltL2FwcC50eHR8YXBpYXBwbGJ5c2tleTE2OHxhcGlhcHBsYnlza2V5MTY4fDEwNw=="
|
||||
},
|
||||
{
|
||||
"key": "木叶",
|
||||
"name": "木叶|APP",
|
||||
"type": 3,
|
||||
"api": "csp_Xdai",
|
||||
"playerType": 2,
|
||||
"ext": "saHR0cDovLzExMy40NS4yNDMuMjMzL211eWUudHh0fFJ1TjlMUnZ3VFJncFFucEt8UnVOOUxSdndUUmdwUW5wS3w1NDc="
|
||||
},
|
||||
{
|
||||
"key": "起点",
|
||||
"name": "起点|APP",
|
||||
"type": 3,
|
||||
"api": "csp_Xdai",
|
||||
"playerType": 1,
|
||||
"ext": "jaHR0cDovL2NhaWppLm8wYS5jbnw3MGZkNjFkOTkxZjQzMjU3fDcwZmQ2MWQ5OTFmNDMyNTd8MTAw"
|
||||
},
|
||||
{
|
||||
"key": "米兔",
|
||||
"name": "米兔|APP",
|
||||
"type": 3,
|
||||
"api": "csp_Xdai",
|
||||
"playerType": 1,
|
||||
"ext": "jaHR0cHM6Ly93d3cuempjLmFwcHxhYjRlOWE0MjE2NzVmMTRifGFiNGU5YTQyMTY3NWYxNGJ8NDQy"
|
||||
},
|
||||
{
|
||||
"key": "光速",
|
||||
"name": "光速|APP",
|
||||
"type": 3,
|
||||
"api": "csp_Xdai",
|
||||
"playerType": 1,
|
||||
"ext": "jaHR0cDovLzU5LjE1My4xNjcuMTM3Ojg4OTl8NGQ4M2I4N2M0YzVlYTExMXw0ZDgzYjg3YzRjNWVhMTExfDQ2Mg=="
|
||||
},
|
||||
{
|
||||
"key": "优秀",
|
||||
"name": "优秀|APP",
|
||||
"type": 3,
|
||||
"api": "csp_Xdai",
|
||||
"playerType": 1,
|
||||
"ext": "jaHR0cDovL2FpLnhpYW95dW4uaW5rfEtMckZxU2ptYzRPSWo3NkJ8S0xyRnFTam1jNE9Jajc2QnwzMDA="
|
||||
},
|
||||
{
|
||||
"key": "莉莉",
|
||||
"name": "莉莉|APP",
|
||||
"type": 3,
|
||||
"api": "csp_Xdai",
|
||||
"playerType": 1,
|
||||
"ext": "jaHR0cDovLzU5LjE1My4xNjcuMTg2OjEwMDk5fFBNS2Faa0F2NFFwNTNFV258UE1LYVprQXY0UXA1M0VXbnw0MjU="
|
||||
},
|
||||
{
|
||||
"key": "电影",
|
||||
"name": "电影|APP",
|
||||
"type": 3,
|
||||
"api": "csp_Xdai",
|
||||
"playerType": 1,
|
||||
"ext": "jaHR0cHM6Ly9jOHcyb3Y3dTV3ZzJ6MW84cDIxYy5hbGl5dW5jcy5jbGljazoyNzg5OXxrOW8zcDJjOGI3bTN6MG84fGs5bzNwMmM4YjdtM3owbzh8MTAw"
|
||||
},
|
||||
{
|
||||
"key": "奇妙",
|
||||
"name": "奇妙|APP",
|
||||
"type": 3,
|
||||
"api": "csp_Xdai",
|
||||
"playerType": 1,
|
||||
"ext": "jaHR0cDovLzE1NC4xMi45MS4yMTE6NjY4fDEyMzQ1Njc4OUFCQ0RFRkd8MTIzNDU2Nzg5QUJDREVGR3wxMDY="
|
||||
},
|
||||
{
|
||||
"key": "人人",
|
||||
"name": "人人|APP",
|
||||
"type": 3,
|
||||
"api": "csp_Xdai",
|
||||
"playerType": 1,
|
||||
"ext": "jaHR0cHM6Ly9zdmlwMS5mdW58bGFvZGllc2Rhd3Nzd2FzZHxsYW9kaWVzZGF3c3N3YXNkfDI5OGU1ZmUyOWM3NGIzNWFhYmI5ODM2ZWUyZjZmNDQ5ZnwxMDU="
|
||||
},
|
||||
{
|
||||
"key": "格格",
|
||||
"name": "格格|APP",
|
||||
"type": 3,
|
||||
"api": "csp_Xdai",
|
||||
"playerType": 2,
|
||||
"ext": "jaHR0cDovLzExMS4xODAuMTk4LjQwOjExMTAvYXBpLnBocHxhc2djeGhqa3RzMTI0NTczfGFzZ2N4aGprdHMxMjQ1NzN8MTE5"
|
||||
},
|
||||
{
|
||||
"key": "悠悠",
|
||||
"name": "悠悠|APP",
|
||||
"type": 3,
|
||||
"api": "csp_Xdai",
|
||||
"playerType": 2,
|
||||
"ext": "jaHR0cDovLzE1Ni4yMjUuMzAuNjU6NTU2Ni9hcGkucGhwfER4d0lzdHJkV2JZcGJsd258RHh3SXN0cmRXYllwYmx3bnwxMTk="
|
||||
},
|
||||
{
|
||||
"key": "云端",
|
||||
"name": "云端|APP",
|
||||
"type": 3,
|
||||
"api": "csp_Xdai",
|
||||
"playerType": 2,
|
||||
"ext": "jaHR0cHM6Ly95ZHlzZHluYW1pY2RvbWFpbm5hbWUuNjguZ3k6MTA2NzgvYzltMmpzMjk4eDgyaDYvbDltOGJ4MjNqMm8ycDlxL2R5bmFtaWNkb21haW5uYW1lLnR4dHxrOW8zcDJjOGI3bTN6MG84fGs5bzNwMmM4YjdtM3owbzh8MTAw"
|
||||
},
|
||||
{
|
||||
"key": "蝴蝶",
|
||||
"name": "蝴蝶|APP",
|
||||
"name": "蝴蝶|影视",
|
||||
"type": 3,
|
||||
"api": "csp_Hudie",
|
||||
"playerType": 2,
|
||||
|
@ -735,7 +749,7 @@
|
|||
},
|
||||
{
|
||||
"key": "快看",
|
||||
"name": "快看|APP",
|
||||
"name": "快看|影视",
|
||||
"type": 3,
|
||||
"api": "csp_AppYsV2",
|
||||
"searchable": 1,
|
||||
|
@ -746,7 +760,7 @@
|
|||
},
|
||||
{
|
||||
"key": "移动",
|
||||
"name": "移动|APP",
|
||||
"name": "移动|影视",
|
||||
"type": 3,
|
||||
"api": "csp_YD",
|
||||
"searchable": 1,
|
||||
|
@ -763,13 +777,6 @@
|
|||
"filterable": 1,
|
||||
"ext": "https://www.czzymovie.com/"
|
||||
},
|
||||
{
|
||||
"key": "糯米影视",
|
||||
"name": "糯米┃影视",
|
||||
"type": 3,
|
||||
"api": "csp_Wwys",
|
||||
"ext": "https://www.wwgz.cn"
|
||||
},
|
||||
{
|
||||
"key": "私人影视",
|
||||
"name": "私人|影视",
|
||||
|
@ -828,6 +835,33 @@
|
|||
"quickSearch": 1,
|
||||
"ext": "https://v.wetv.wang"
|
||||
},
|
||||
{
|
||||
"key": "攻阁影视",
|
||||
"name": "攻阁|影视",
|
||||
"type": 3,
|
||||
"playerType": "2",
|
||||
"api": "csp_Lggys"
|
||||
},
|
||||
{
|
||||
"key": "鸭梨影视",
|
||||
"name": "鸭梨|影视",
|
||||
"type": 3,
|
||||
"api": "csp_KmeiJu"
|
||||
},
|
||||
{
|
||||
"key": "绝对影视",
|
||||
"name": "绝对|影视",
|
||||
"type": 3,
|
||||
"api": "csp_FourK",
|
||||
"ext": "https://www.4kvm.tv"
|
||||
},
|
||||
{
|
||||
"key": "白白影视",
|
||||
"name": "白白|影视",
|
||||
"type": 3,
|
||||
"api": "csp_SuBaiBai",
|
||||
"ext": "https://www.subaibai.com"
|
||||
},
|
||||
{
|
||||
"key": "低端影视",
|
||||
"name": "低端|影视",
|
||||
|
@ -837,24 +871,6 @@
|
|||
"quickSearch": 1,
|
||||
"filterable": 1
|
||||
},
|
||||
{
|
||||
"key": "快看影视",
|
||||
"name": "快看|影视",
|
||||
"type": 3,
|
||||
"api": "csp_Kuaikan",
|
||||
"searchable": 1,
|
||||
"quickSearch": 1,
|
||||
"filterable": 1
|
||||
},
|
||||
{
|
||||
"key": "饭团影视",
|
||||
"name": "饭团|影视",
|
||||
"type": 3,
|
||||
"api": "csp_Fantuan",
|
||||
"searchable": 1,
|
||||
"quickSearch": 1,
|
||||
"filterable": 1
|
||||
},
|
||||
{
|
||||
"key": "来看影视",
|
||||
"name": "来看|影视",
|
||||
|
@ -873,6 +889,15 @@
|
|||
"quickSearch": 1,
|
||||
"filterable": 1
|
||||
},
|
||||
{
|
||||
"key": "快看影视",
|
||||
"name": "快看|影视",
|
||||
"type": 3,
|
||||
"api": "csp_Kuaikan",
|
||||
"searchable": 1,
|
||||
"quickSearch": 1,
|
||||
"filterable": 1
|
||||
},
|
||||
{
|
||||
"key": "采集之王",
|
||||
"name": "采集|合集",
|
||||
|
@ -1336,29 +1361,43 @@
|
|||
"key": "曼波动漫",
|
||||
"name": "曼波|动漫",
|
||||
"type": 3,
|
||||
"api": "csp_Xdai",
|
||||
"searchable": 1,
|
||||
"quickSearch": 0,
|
||||
"filterable": 0,
|
||||
"ext": "jaHR0cHM6Ly9hcHAub21vZnVuMS50b3AvYXBpLnBocHw2NmRjMzA5Y2JlZWNhNDU0fDY2ZGMzMDljYmVlY2E0NTR8MTAw"
|
||||
"quickSearch": 1,
|
||||
"api": "csp_AppGet",
|
||||
"ext": {
|
||||
"url": "https://app.omofun1.top",
|
||||
"dataKey": "66dc309cbeeca454",
|
||||
"dataIv": "66dc309cbeeca454",
|
||||
"deviceId": "",
|
||||
"version": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"key": "稀饭动漫",
|
||||
"name": "稀饭|动漫",
|
||||
"type": 3,
|
||||
"api": "csp_Xdai",
|
||||
"searchable": 1,
|
||||
"quickSearch": 0,
|
||||
"filterable": 0,
|
||||
"ext": "jaHR0cHM6Ly94ZmFwcC0xMzA1MzkwMDY1LmNvcy5hcC1ndWFuZ3pob3UubXlxY2xvdWQuY29tL2dldGFwcC50eHR8MXlaMlNwbjlrcm56VktvQ3wxeVoyU3BuOWtybnpWS29DfDEwMA=="
|
||||
"quickSearch": 1,
|
||||
"api": "csp_AppGet",
|
||||
"ext": {
|
||||
"url": "https://pzoap.moedot.net",
|
||||
"dataKey": "1yZ2Spn9krnzVKoC",
|
||||
"dataIv": "1yZ2Spn9krnzVKoC",
|
||||
"deviceId": "",
|
||||
"version": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"key": "咕咕动漫",
|
||||
"name": "咕咕|动漫",
|
||||
"type": 3,
|
||||
"api": "csp_Xdai",
|
||||
"playerType": 1,
|
||||
"ext": "jaHR0cHM6Ly93d3cuZ3VndTMuY29tfG5LZlo4S1g2SlROV1J6VER8bktmWjhLWDZKVE5XUnpURHw0MDE="
|
||||
"quickSearch": 1,
|
||||
"api": "csp_AppGet",
|
||||
"ext": {
|
||||
"url": "https://www.gugu3.com",
|
||||
"dataKey": "nKfZ8KX6JTNWRzTD",
|
||||
"dataIv": "nKfZ8KX6JTNWRzTD",
|
||||
"deviceId": "",
|
||||
"version": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"key": "动画片",
|
||||
|
@ -1430,13 +1469,6 @@
|
|||
"api": "./js/drpy2.min.js",
|
||||
"ext": "./js/花子动漫.js"
|
||||
},
|
||||
{
|
||||
"key": "动漫巴士",
|
||||
"name": "巴士|动漫",
|
||||
"type": 3,
|
||||
"api": "./js/drpy2.min.js",
|
||||
"ext": "./js/动漫巴士.js"
|
||||
},
|
||||
{
|
||||
"key": "樱花动漫",
|
||||
"name": "樱花|动漫",
|
||||
|
@ -1660,6 +1692,16 @@
|
|||
"type": "list"
|
||||
}
|
||||
},
|
||||
{
|
||||
"key": "短剧大全",
|
||||
"name": "短剧|大全",
|
||||
"type": 3,
|
||||
"api": "./js/quark.min.js",
|
||||
"ext": "./js/短剧大全.js",
|
||||
"style": {
|
||||
"type": "list"
|
||||
}
|
||||
},
|
||||
{
|
||||
"key": "AList",
|
||||
"name": "AList|合集",
|
||||
|
@ -1683,11 +1725,11 @@
|
|||
"key": "88看球",
|
||||
"name": "88|看球",
|
||||
"type": 3,
|
||||
"api": "./js/drpy2.min.js",
|
||||
"api": "csp_Kanqiu",
|
||||
"gridview": 3,
|
||||
"style": {
|
||||
"type": "list"
|
||||
},
|
||||
"ext": "./js/88看球.js"
|
||||
}
|
||||
},
|
||||
{
|
||||
"key": "急救教学",
|
||||
|
@ -1940,6 +1982,26 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "QD4K",
|
||||
"type": 1,
|
||||
"url": "https://zy.qiaoji8.com/xiafan.php?url=",
|
||||
"ext": {
|
||||
"flag": [
|
||||
"QD4K",
|
||||
"iyf",
|
||||
"duanju",
|
||||
"gzcj",
|
||||
"GTV",
|
||||
"GZYS",
|
||||
"weggz",
|
||||
"Ace"
|
||||
],
|
||||
"header": {
|
||||
"User-Agent": "okhttp/4.9.1"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "咸鱼",
|
||||
"type": 0,
|
||||
|
@ -2119,14 +2181,33 @@
|
|||
"type": 0,
|
||||
"url": "https://gh-proxy.com/https://raw.githubusercontent.com/PizazzGY/TV/master/output/user_result.txt",
|
||||
"epg": "http://cdn.1678520.xyz/epg/?ch={name}&date={date}",
|
||||
"playerType": 2,
|
||||
"timeout": 10
|
||||
},
|
||||
{
|
||||
"name": "AI直播+",
|
||||
"type": 0,
|
||||
"url": "https://gh-proxy.com/https://raw.githubusercontent.com/PizazzGY/TV/master/output/user_result.m3u",
|
||||
"epg": "http://cdn.1678520.xyz/epg/?ch={name}&date={date}",
|
||||
"timeout": 10
|
||||
},
|
||||
{
|
||||
"name": "Guovin",
|
||||
"type": 0,
|
||||
"url": "https://gitee.com/mytv-android/iptv-api/raw/master/output/result.m3u",
|
||||
"epg": "http://cdn.1678520.xyz/epg/?ch={name}&date={date}",
|
||||
"timeout": 10
|
||||
},
|
||||
{
|
||||
"name": "咪咕直播",
|
||||
"type": 0,
|
||||
"url": "https://yun.urldwz.com/f/Q6y3ca/migu.m3u",
|
||||
"timeout": 10
|
||||
},
|
||||
{
|
||||
"name": "虎牙一起看",
|
||||
"type": 3,
|
||||
"api": "csp_Feiyang",
|
||||
"url": "https://9877.kstore.space/Live/huyayqk.m3u",
|
||||
"url": "https://yun.urldwz.com/f/BE9PSL/huyayqk.m3u",
|
||||
"timeout": 10,
|
||||
"ua": "okhttp/3.15"
|
||||
},
|
||||
|
@ -2134,7 +2215,7 @@
|
|||
"name": "斗鱼一起看",
|
||||
"type": 3,
|
||||
"api": "csp_Feiyang",
|
||||
"url": "https://9877.kstore.space/Live/douyuyqk.m3u",
|
||||
"url": "https://yun.urldwz.com/f/NR9qiA/douyuyqk.m3u",
|
||||
"timeout": 10,
|
||||
"ua": "okhttp/3.15"
|
||||
},
|
||||
|
@ -2142,7 +2223,7 @@
|
|||
"name": "YY轮播",
|
||||
"type": 3,
|
||||
"api": "csp_Feiyang",
|
||||
"url": "https://9877.kstore.space/Live/yylunbo.m3u",
|
||||
"url": "https://yun.urldwz.com/f/dlkycZ/yylunbo.m3u",
|
||||
"timeout": 10,
|
||||
"ua": "okhttp/3.15"
|
||||
},
|
||||
|
@ -2150,7 +2231,7 @@
|
|||
"name": "B站直播",
|
||||
"type": 3,
|
||||
"api": "csp_Feiyang",
|
||||
"url": "https://9877.kstore.space/Live/bilibili.m3u",
|
||||
"url": "https://yun.urldwz.com/f/9XBkHK/bilibili.m3u",
|
||||
"timeout": 10,
|
||||
"ua": "okhttp/3.15"
|
||||
},
|
||||
|
@ -2172,7 +2253,6 @@
|
|||
"name": "范明明",
|
||||
"type": 0,
|
||||
"url": "https://live.fanmingming.cn/tv/m3u/ipv6.m3u",
|
||||
"playerType": 2,
|
||||
"timeout": 10
|
||||
},
|
||||
{
|
||||
|
@ -2182,8 +2262,7 @@
|
|||
"epg": "http://epg.51zmt.top:8000/api/diyp/?ch={name}&date={date}",
|
||||
"logo": "https://epg.iill.top/logo/{name}.png",
|
||||
"ua": "okhttp/3.15,AptvPlayer/1.4.0",
|
||||
"timeout": 10,
|
||||
"playerType": 2
|
||||
"timeout": 10
|
||||
}
|
||||
],
|
||||
"hosts": [
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
var rule = {
|
||||
类型: '影视', //影视|听书|漫画|小说
|
||||
title: '短剧',
|
||||
host: 'https://ai-img.ycubbs.cn/',
|
||||
homeUrl: '/api/duanju/list',
|
||||
url: '/api/duanju/list',
|
||||
searchUrl: 'https://api.kuleu.com/api/action?text=**',
|
||||
searchable: 1,
|
||||
quickSearch: 0,
|
||||
filterable: 0,
|
||||
headers: {
|
||||
'User-Agent': 'MOBILE_UA',
|
||||
},
|
||||
hikerListCol: "text_1",
|
||||
hikerClassListCol: "text_1",
|
||||
timeout: 5000,
|
||||
class_name: '',
|
||||
class_url: '',
|
||||
play_parse: true,
|
||||
lazy: $js.toString(() => {
|
||||
input = "push://" + input;
|
||||
}),
|
||||
double: false,
|
||||
推荐: '*',
|
||||
一级: 'json:data;name;;;url',
|
||||
二级: '*',
|
||||
搜索: 'json:data;name;;;viewlink',
|
||||
}
|
|
@ -9,76 +9,95 @@
|
|||
]
|
||||
},
|
||||
{
|
||||
"name": "影视一",
|
||||
"name": "短剧合集",
|
||||
"folders": [
|
||||
{
|
||||
"shareId": "dW5pJdgF8c9",
|
||||
"folder": "root"
|
||||
},
|
||||
{
|
||||
"shareId": "Y5wMKfVDD6K",
|
||||
"folder": "root"
|
||||
},
|
||||
{
|
||||
"shareId": "LEaepiYfxcw",
|
||||
"folder": "root"
|
||||
},
|
||||
{
|
||||
"shareId": "v1bBBEcNf9p",
|
||||
"folder": "root"
|
||||
"folder": "6616613853041ba53f2842918e02346943d980b4"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "影视二",
|
||||
"name": "动漫合集",
|
||||
"folders": [
|
||||
{
|
||||
"shareId": "uWa9gbM3RJ7",
|
||||
"folder": "655c7b6c66368f43652a45288146c6e7cb269aa8"
|
||||
"shareId": "LEaepiYfxcw",
|
||||
"folder": "61019a966975bfef583449a39b36da512384b2d7"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "影视三",
|
||||
"name": "电影合集",
|
||||
"folders": [
|
||||
{
|
||||
"shareId": "ZHNChQfiPfk",
|
||||
"folder": "root"
|
||||
},
|
||||
{
|
||||
"shareId": "e27BPgDwxeA",
|
||||
"folder": "root"
|
||||
},
|
||||
{
|
||||
"shareId": "XUH7r6BZuML",
|
||||
"folder": "root"
|
||||
},
|
||||
{
|
||||
"shareId": "qZ4f1i2EFW2",
|
||||
"folder": "root"
|
||||
},
|
||||
{
|
||||
"shareId": "ohJ68NV7iFw",
|
||||
"folder": "root"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "电视剧合集",
|
||||
"folders": [
|
||||
{
|
||||
"shareId": "ftMhRaKUfYp",
|
||||
"folder": "root"
|
||||
},
|
||||
{
|
||||
"shareId": "MLWPRHRt9W3",
|
||||
"folder": "root"
|
||||
},
|
||||
{
|
||||
"shareId": "8Fg4TNsd2A2",
|
||||
"folder": "root"
|
||||
},
|
||||
{
|
||||
"shareId": "ar8Kg9azw1S",
|
||||
"folder": "root"
|
||||
},
|
||||
{
|
||||
"shareId": "GMYSz3AHFaA",
|
||||
"folder": "root"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "综艺合集",
|
||||
"folders": [
|
||||
{
|
||||
"shareId": "UuHi9PeYSVz",
|
||||
"folder": "root"
|
||||
},
|
||||
{
|
||||
"shareId": "v9To3HC6vhs",
|
||||
"folder": "root"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "其它合集",
|
||||
"folders": [
|
||||
{
|
||||
"shareId": "4ydLxf7VgH7",
|
||||
"folder": "root"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "影视四",
|
||||
"folders": [
|
||||
},
|
||||
{
|
||||
"shareId": "5bsnAp5fbCW",
|
||||
"folder": "root"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "影视五",
|
||||
"folders": [
|
||||
{
|
||||
"shareId": "dieULBdYP3D",
|
||||
"folder": "root"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "影视六",
|
||||
"folders": [
|
||||
{
|
||||
"shareId": "sg8CdGUwmUr",
|
||||
"folder": "root"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "影视七",
|
||||
"folders": [
|
||||
{
|
||||
"shareId": "wHPKUENKFsS",
|
||||
"shareId": "uWa9gbM3RJ7",
|
||||
"folder": "root"
|
||||
}
|
||||
]
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
{
|
||||
"SiteUrl": "https://www.hmxz.org",
|
||||
"Classes": [
|
||||
{
|
||||
"type_name": "电影",
|
||||
|
@ -8,13 +9,14 @@
|
|||
"type_name": "剧集",
|
||||
"type_id": "2"
|
||||
},
|
||||
{
|
||||
"type_name": "动漫",
|
||||
"type_id": "3"
|
||||
},
|
||||
{
|
||||
"type_name": "综艺",
|
||||
"type_id": "5"
|
||||
},
|
||||
{
|
||||
"type_name": "动漫",
|
||||
"type_id": "3"
|
||||
}
|
||||
]
|
||||
],
|
||||
"Cookie": "bbs_sid=rrru52bda4v655kl9u1c87f00m; bbs_token=dZRAvHbHcUZkuJ7oHALqWoUs00C1fGqqXDXH7I8LH6hMddXP"
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
{
|
||||
"SiteUrl": "https://www.kuafuzy.com",
|
||||
"Classes": [
|
||||
{
|
||||
"type_name": "电影",
|
||||
"type_id": "1"
|
||||
},
|
||||
{
|
||||
"type_name": "剧集",
|
||||
"type_id": "2"
|
||||
},
|
||||
{
|
||||
"type_name": "4K电影",
|
||||
"type_id": "3"
|
||||
},
|
||||
{
|
||||
"type_name": "4K剧集",
|
||||
"type_id": "4"
|
||||
},
|
||||
{
|
||||
"type_name": "动漫",
|
||||
"type_id": "5"
|
||||
},
|
||||
{
|
||||
"type_name": "短剧",
|
||||
"type_id": "6"
|
||||
}
|
||||
],
|
||||
"Cookie": "bbs_token=zNQpYs_2BmC2e_2FcUM_2BmuihZ33Jswh_2Fj7sPtelqcw_3D_3D; bbs_sid=lgs96gh42gevj7lsg5f8o3kjsi"
|
||||
}
|
|
@ -18,17 +18,13 @@
|
|||
"type_name": "剧集",
|
||||
"type_id": "2"
|
||||
},
|
||||
{
|
||||
"type_name": "综艺",
|
||||
"type_id": "25"
|
||||
},
|
||||
{
|
||||
"type_name": "动漫",
|
||||
"type_id": "3"
|
||||
},
|
||||
{
|
||||
"type_name": "纪录片",
|
||||
"type_id": "4"
|
||||
"type_name": "天翼专区",
|
||||
"type_id": "27"
|
||||
}
|
||||
],
|
||||
"Filters": {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
{
|
||||
"SiteUrl": "https://time.123in.link",
|
||||
"Classes": [
|
||||
{
|
||||
"type_name": "电影",
|
||||
|
@ -20,5 +21,6 @@
|
|||
"type_name": "动漫",
|
||||
"type_id": "37"
|
||||
}
|
||||
]
|
||||
],
|
||||
"Cookie": "bbs_sid=rrru52bda4v655kl9u1c87f00m; bbs_token=dZRAvHbHcUZkuJ7oHALqWoUs00C1fGqqXDXH7I8LH6hMddXP"
|
||||
}
|
|
@ -18,29 +18,93 @@
|
|||
]
|
||||
},
|
||||
{
|
||||
"name": "4K影视",
|
||||
"folders": [
|
||||
{
|
||||
"shareId": "7568042397a9",
|
||||
"folder": "0a9f0d04a8704f35b18763948ece0593"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "短剧合集1",
|
||||
"name": "短剧合集",
|
||||
"folders": [
|
||||
{
|
||||
"shareId": "885fd4ba2d92",
|
||||
"folder": "81ca012717cb45228f237e26d8da20c8"
|
||||
"folder": "0"
|
||||
},
|
||||
{
|
||||
"shareId": "a1cda418984f",
|
||||
"folder": "0"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "短剧合集2",
|
||||
"name": "电影合集",
|
||||
"folders": [
|
||||
{
|
||||
"shareId": "a1cda418984f",
|
||||
"folder": "7e09c18d7f8045f983eca086be8ddb8f"
|
||||
"shareId": "49ab75d52e00",
|
||||
"folder": "0"
|
||||
},
|
||||
{
|
||||
"shareId": "a632967760cf",
|
||||
"folder": "0"
|
||||
},
|
||||
{
|
||||
"shareId": "2f59bb5d96b9",
|
||||
"folder": "0"
|
||||
},
|
||||
{
|
||||
"shareId": "50828c368def",
|
||||
"folder": "0"
|
||||
},
|
||||
{
|
||||
"shareId": "e07e26aecc08",
|
||||
"folder": "0"
|
||||
},
|
||||
{
|
||||
"shareId": "0536a38a356e",
|
||||
"folder": "0"
|
||||
},
|
||||
{
|
||||
"shareId": "e273ef697403",
|
||||
"folder": "0"
|
||||
},
|
||||
{
|
||||
"shareId": "c8ac6c88e5d8",
|
||||
"folder": "0"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "电视剧合集",
|
||||
"folders": [
|
||||
{
|
||||
"shareId": "d19c4ebe1ff7",
|
||||
"folder": "0"
|
||||
},
|
||||
{
|
||||
"shareId": "cd4c5ac7e830",
|
||||
"folder": "0"
|
||||
},
|
||||
{
|
||||
"shareId": "e1b2ba8b6d6c",
|
||||
"folder": "0"
|
||||
},
|
||||
{
|
||||
"shareId": "166fa0a7ca6f",
|
||||
"folder": "0"
|
||||
},
|
||||
{
|
||||
"shareId": "37a92c0b7f10",
|
||||
"folder": "0"
|
||||
},
|
||||
{
|
||||
"shareId": "fb3386e42af2",
|
||||
"folder": "0"
|
||||
},
|
||||
{
|
||||
"shareId": "46ce214f4ed7",
|
||||
"folder": "0"
|
||||
},
|
||||
{
|
||||
"shareId": "fe4681d7fb43",
|
||||
"folder": "0"
|
||||
},
|
||||
{
|
||||
"shareId": "8d65e885b059",
|
||||
"folder": "0"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -7,5 +7,41 @@
|
|||
"folder": "0"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "豆瓣TOP250部",
|
||||
"folders": [
|
||||
{
|
||||
"shareId": "c0503fdee6644",
|
||||
"folder": "0"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "日剧",
|
||||
"folders": [
|
||||
{
|
||||
"shareId": "391b86c09cd24",
|
||||
"folder": "9df4921d548841199e625765413f8bd6"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "韩剧",
|
||||
"folders": [
|
||||
{
|
||||
"shareId": "21f04a22052f4",
|
||||
"folder": "950f5ca7d5e54d528c0dae1fddec5c78"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "音乐",
|
||||
"folders": [
|
||||
{
|
||||
"shareId": "369e30038dae4",
|
||||
"folder": "1b8a55dc18a54fb7aea8ed2b6fd6ad53"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
|
@ -80,14 +80,6 @@
|
|||
"class_name": "H4sIAFlXhmYC/z1RbXaCMBC8TU7QW/RSip/oq8orxVp56hNoaqtFq1gFopfJZsMtGhLor93Z3czuTNBNgB0IuomkXbApwSyXdkpg8CHyrzJw5qPdI+D5ql1m2D+IVkdn1IFrVmaiORENT8/ZtOqK/itPbV2bM57Skl1sKd5GZVYsN7owjXS4xGWA8V6jow6YfgJ70VTJL4SenghpMetWR6rHiqYGimK8r4HeU2sx640i86YG5px/regaNZqqnjG7K5C74B54/kY4e5bWj0zmPB0SjL9x0iLyfCxDsW6DM9BEXizjFDpDokxWBksayPikHGTC6+FyVyri+TtOutVOfrExNeaoo01HRnfhXeuxaST8bQX4JRQNKuMbrCwC3Rn6S2ztZH9BHh7RfKzwbQhqKRAdi7UjmkP1hcrrJ8m26hRjfCiDDs9m/LYicD3xLMDNXZ4HRLYdcVoIa4ueQ3C0V52ixeBikcJKxH5s9vwBtOQp10cCAAA=",
|
||||
"class_url": "1&2&3&4&6&7&8&9&10&11&12&13&14&15&16&17&18&19&20&23&25&26&27&28&29&30&31&39&44&45&47&48&49&50&51&52&53&54&55&56&57&58&59&60&61&62&63&64&65&66&67&68&69&70"
|
||||
},
|
||||
{
|
||||
"name": "快车资源",
|
||||
"url": "https://caiji.kczyapi.com",
|
||||
"parse_url": "",
|
||||
"cate_exclude": "电影|电视剧|综艺|动漫|预告片|伦理|影视解说|体育赛事|港台三级|两性课堂|写真热舞",
|
||||
"class_name": "H4sIAFZXhmYC/z1RbXaCMBC8TU7QW/RSip/oq8orxVp56hNoaqtFq1gFopfJZsMtGhLor93Z3czuTNBNgB0IuomkXbApwSyXdkpg8CHyrzJw5qPdI+D5ql1m2D+IVkdn1IFrVmaiORENT8/ZtOqK/itPbV2bM57Skl1sKd5GZVYsN7owjXS4xGWA8V6jow6YfgJ70VTJL4SenghpMetWR6rHiqYGimK8r4HeU2sx640i86YG5px/regaNZqqnjG7K5C74B54/kY4e5bWj0zmPB0SjL9x0iLyfCxDsW6DM9BEXizjFDpDokxWBksayPikHGTC6+FyVyri+TtOutVOfrExNeaoo01HRnfhXeuxaST8bQX4JRQNKuMbrCwC3Rn6S2ztZH9BHh7RfKzwbQhqKRAdi7UjmkP1hcrrJ8m26hRjfCiDDs9m/LYicD3xLMDNXZ4HRLYdcVoIa4ueQ3C0V52ixeBikcJKxH5s9vwBtOQp10cCAAA=",
|
||||
"class_url": "1&2&3&4&6&7&8&9&10&11&12&13&14&15&16&17&18&19&20&23&25&26&27&28&29&30&31&39&44&45&47&48&49&50&51&52&53&54&55&56&57&58&59&60&61&62&63&64&65&66&67&68&69&70"
|
||||
},
|
||||
{
|
||||
"name": "️极速资源",
|
||||
"url": "https://jszyapi.com",
|
||||
|
@ -113,23 +105,6 @@
|
|||
"class_name": "H4sIAFZXhmYC/1WR0VLCQAxF/6bfqXQsbB9omYEq2JEHKqtQ2iIC0nbxZ5pk+Qt303VG307uZnJvsjQ9gtqTGHr6+4WaHQjpUdNqUVsNwjdst446lTIlqWmyRKM9+g9McgKXxhLex3iXcJ+Q7hVHT10tWHtWXS2tx209x6+SafluZEuYS7qOLUFU4eXK2uMrpjnT8QxZYkkXFagZ+y53LhxNmz8GHPt3niv6Qa4w1lHV7+kCuAIyeZsHrsBD9S+ak4lvpuVKl58e+iEOFuxdnKDu80SZXvHqMA4g+uAjDHJKJhw6LEltmMqCYt/r2jXFAf/B6WAFs5Yx/QEG4wmPmwEAAA==",
|
||||
"class_url": "1&2&3&4&5&6&7&8&9&10&11&12&13&14&15&16&17&18&22&23&24&25&26&27&30&31&32&33&37&38&39&42&43&44&45&46&48&49&51&54"
|
||||
},
|
||||
{
|
||||
"name": "天空资源",
|
||||
"url": "https://m3u8.tiankongapi.com",
|
||||
"parse_url": "",
|
||||
"cate_exclude": "电影|连续剧|动漫|综艺|伦理片|电影解说|体育赛事|短剧",
|
||||
"api": "/api.php/provide/vod/from/tkm3u8/",
|
||||
"class_name": "H4sIAFdXhmYC/zVQW3LCMAy8jc/JYygknSllCqGUTPkoYAphEqCB4uD0Mrbk3KK2Yn95V9autMJpqeWJodhrOcNoyMzfJ1ZHHXEGGcf6xaFmu4Df3CEd75RMXR+OTtAfEOITfa8cgu4rdBKHbK//hdG7EhHVktSWCcU7nJIC4xzlnmpLqQSnaatvS/w0eBwYVg8TCabXvFk8eeL2GReBzDdWFAitHTTjAu41ebX+raMVQJoF0ub0pLzpdRLIpfCbWIF7kK5l+JfJf5jeDH1u7NbNR01pexkmE8ozuKqKbqHkm+mdTblU4pnhyt32H73g+qZ2AQAA",
|
||||
"class_url": "1&2&3&4&5&6&7&8&9&10&11&12&20&21&22&23&24&25&26&27&28&29&30&31&32&33&34&35&36&37&38&39&40&41&42&44"
|
||||
},
|
||||
{
|
||||
"name": "百度云资源",
|
||||
"url": "https://api.apibdzy.com",
|
||||
"parse_url": "",
|
||||
"cate_exclude": "电影|电视剧|综艺|动漫|伦理片|纪录片|体育赛事|资讯",
|
||||
"class_name": "H4sIAFdXhmYC/zVP7W7CMAx8mzzn1vGVTgKqla4TSEgTLMAQLaBMkDZ9msRO32KNm/67O9t3Z0yl1VeGqXRiYrlgWNWOK2bjA9S/zNQ/uJwgn3rB6A2hbNMteoSzK7yNCYnEPiuP4HUJLxntcRGmMMuN4qTtRPtFOfAooLl71G6PJHzuKV+drF6RZ1ygPoVsTCvsq9pFCc+GLs4Cm7lHdvxnqoy0e0kC5YRfOucuYyCPonMYCDkML6+1USI83t8MpA8KJDpjlvhabSShXIRaRn+46Obk2qh35uTIXQrWjwKBfA75NpD2e2ST+B8HkFGOfQEAAA==",
|
||||
"class_url": "1&2&3&4&5&6&7&8&9&10&11&12&13&14&15&16&17&18&20&21&22&23&24&25&26&27&28&29&30&31&32&33&34&36&37&38&39"
|
||||
},
|
||||
{
|
||||
"name": "无尽资源",
|
||||
"url": "https://api.wujinapi.me",
|
||||
|
|
|
@ -0,0 +1,790 @@
|
|||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
# 偷乐短剧爬虫
|
||||
|
||||
import sys
|
||||
import json
|
||||
import re
|
||||
import time
|
||||
import urllib.parse
|
||||
import requests
|
||||
from bs4 import BeautifulSoup
|
||||
|
||||
# 导入基础类
|
||||
sys.path.append('../../')
|
||||
try:
|
||||
from base.spider import Spider
|
||||
except ImportError:
|
||||
# 本地调试时的替代实现
|
||||
class Spider:
|
||||
def init(self, extend=""):
|
||||
pass
|
||||
|
||||
class Spider(Spider):
|
||||
def __init__(self):
|
||||
# 网站主URL
|
||||
self.siteUrl = "https://www.toule.top"
|
||||
|
||||
# 根据网站实际结构,分类链接格式为: /index.php/vod/show/class/分类名/id/1.html
|
||||
# 分类ID映射 - 从网站中提取的分类
|
||||
self.cateManual = {
|
||||
"男频": "/index.php/vod/show/class/%E7%94%B7%E9%A2%91/id/1.html",
|
||||
"女频": "/index.php/vod/show/class/%E5%A5%B3%E9%A2%91/id/1.html",
|
||||
"都市": "/index.php/vod/show/class/%E9%83%BD%E5%B8%82/id/1.html",
|
||||
"赘婿": "/index.php/vod/show/class/%E8%B5%98%E5%A9%BF/id/1.html",
|
||||
"战神": "/index.php/vod/show/class/%E6%88%98%E7%A5%9E/id/1.html",
|
||||
"古代言情": "/index.php/vod/show/class/%E5%8F%A4%E4%BB%A3%E8%A8%80%E6%83%85/id/1.html",
|
||||
"现代言情": "/index.php/vod/show/class/%E7%8E%B0%E4%BB%A3%E8%A8%80%E6%83%85/id/1.html",
|
||||
"历史": "/index.php/vod/show/class/%E5%8E%86%E5%8F%B2/id/1.html",
|
||||
"玄幻": "/index.php/vod/show/class/%E7%8E%84%E5%B9%BB/id/1.html",
|
||||
"搞笑": "/index.php/vod/show/class/%E6%90%9E%E7%AC%91/id/1.html",
|
||||
"甜宠": "/index.php/vod/show/class/%E7%94%9C%E5%AE%A0/id/1.html",
|
||||
"励志": "/index.php/vod/show/class/%E5%8A%B1%E5%BF%97/id/1.html",
|
||||
"逆袭": "/index.php/vod/show/class/%E9%80%86%E8%A2%AD/id/1.html",
|
||||
"穿越": "/index.php/vod/show/class/%E7%A9%BF%E8%B6%8A/id/1.html",
|
||||
"古装": "/index.php/vod/show/class/%E5%8F%A4%E8%A3%85/id/1.html"
|
||||
}
|
||||
|
||||
# 请求头
|
||||
self.headers = {
|
||||
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36",
|
||||
"Referer": "https://www.toule.top/",
|
||||
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
|
||||
"Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8",
|
||||
"Accept-Encoding": "gzip, deflate, br",
|
||||
"Connection": "keep-alive",
|
||||
}
|
||||
|
||||
|
||||
# 缓存
|
||||
self.cache = {}
|
||||
self.cache_timeout = {}
|
||||
|
||||
def getName(self):
|
||||
return "偷乐短剧"
|
||||
|
||||
def init(self, extend=""):
|
||||
# 初始化方法,可以留空
|
||||
return
|
||||
|
||||
def isVideoFormat(self, url):
|
||||
"""判断是否为视频格式"""
|
||||
video_formats = ['.mp4', '.m3u8', '.ts', '.flv', '.avi', '.mkv', '.mov', '.rmvb', '.3gp']
|
||||
for format in video_formats:
|
||||
if format in url.lower():
|
||||
return True
|
||||
return False
|
||||
|
||||
def manualVideoCheck(self):
|
||||
"""是否需要手动检查视频"""
|
||||
return False
|
||||
|
||||
# 工具方法 - 网络请求
|
||||
def fetch(self, url, headers=None, data=None, method="GET"):
|
||||
"""统一的网络请求方法"""
|
||||
try:
|
||||
if headers is None:
|
||||
headers = self.headers.copy()
|
||||
|
||||
if method.upper() == "GET":
|
||||
response = requests.get(url, headers=headers, params=data, timeout=10,verify=False)
|
||||
else: # POST
|
||||
response = requests.post(url, headers=headers, data=data, timeout=10,verify=False)
|
||||
|
||||
response.raise_for_status()
|
||||
response.encoding = response.apparent_encoding or 'utf-8'
|
||||
return response
|
||||
except Exception as e:
|
||||
self.log(f"请求失败: {url}, 错误: {str(e)}", "ERROR")
|
||||
return None
|
||||
|
||||
# 缓存方法
|
||||
def getCache(self, key, timeout=3600):
|
||||
"""获取缓存数据"""
|
||||
if key in self.cache and key in self.cache_timeout:
|
||||
if time.time() < self.cache_timeout[key]:
|
||||
return self.cache[key]
|
||||
else:
|
||||
del self.cache[key]
|
||||
del self.cache_timeout[key]
|
||||
return None
|
||||
|
||||
def setCache(self, key, value, timeout=3600):
|
||||
"""设置缓存数据"""
|
||||
self.cache[key] = value
|
||||
self.cache_timeout[key] = time.time() + timeout
|
||||
|
||||
# 日志方法
|
||||
def log(self, msg, level='INFO'):
|
||||
"""记录日志"""
|
||||
levels = {
|
||||
'DEBUG': 0,
|
||||
'INFO': 1,
|
||||
'WARNING': 2,
|
||||
'ERROR': 3
|
||||
}
|
||||
|
||||
current_level = 'INFO' # 可以设置为DEBUG以获取更多信息
|
||||
|
||||
if levels.get(level, 4) >= levels.get(current_level, 1):
|
||||
print(f"[{level}] {time.strftime('%Y-%m-%d %H:%M:%S')} - {msg}")
|
||||
|
||||
# 辅助方法 - 从URL中提取视频ID
|
||||
def extractVodId(self, url):
|
||||
"""从URL中提取视频ID"""
|
||||
# 路径格式: /index.php/vod/play/id/9024/sid/1/nid/1.html
|
||||
match = re.search(r'/id/(\d+)/', url)
|
||||
if match:
|
||||
return match.group(1)
|
||||
return ""
|
||||
|
||||
# 辅助方法 - 从网页内容中提取分类
|
||||
def extractCategories(self, text):
|
||||
"""从网页内容中提取分类标签"""
|
||||
cats = []
|
||||
# 匹配标签字符串,例如: "男频,逆袭,亲情,短剧"
|
||||
if "," in text:
|
||||
parts = text.split(",")
|
||||
for part in parts:
|
||||
part = part.strip()
|
||||
if part and part != "短剧":
|
||||
cats.append(part)
|
||||
return cats
|
||||
|
||||
# 主要接口实现
|
||||
def homeContent(self, filter):
|
||||
"""获取首页分类及内容"""
|
||||
result = {}
|
||||
classes = []
|
||||
|
||||
# 从缓存获取
|
||||
cache_key = 'home_classes'
|
||||
cached_classes = self.getCache(cache_key)
|
||||
if cached_classes:
|
||||
classes = cached_classes
|
||||
else:
|
||||
# 使用预定义的分类
|
||||
for k, v in self.cateManual.items():
|
||||
classes.append({
|
||||
'type_id': v, # 使用完整URL路径作为type_id
|
||||
'type_name': k
|
||||
})
|
||||
|
||||
# 保存到缓存
|
||||
self.setCache(cache_key, classes, 24*3600) # 缓存24小时
|
||||
|
||||
result['class'] = classes
|
||||
|
||||
# 获取首页推荐视频
|
||||
videos = self.homeVideoContent().get('list', [])
|
||||
result['list'] = videos
|
||||
|
||||
return result
|
||||
|
||||
def homeVideoContent(self):
|
||||
"""获取首页推荐视频内容"""
|
||||
result = {'list': []}
|
||||
videos = []
|
||||
|
||||
# 从缓存获取
|
||||
cache_key = 'home_videos'
|
||||
cached_videos = self.getCache(cache_key)
|
||||
if cached_videos:
|
||||
return {'list': cached_videos}
|
||||
|
||||
try:
|
||||
response = self.fetch(self.siteUrl)
|
||||
if response and response.status_code == 200:
|
||||
html = response.text
|
||||
soup = BeautifulSoup(html, 'html.parser')
|
||||
|
||||
# 查找最新更新区域
|
||||
latest_section = soup.find('h2', text=lambda t: t and '最新更新' in t)
|
||||
if latest_section:
|
||||
container = latest_section.parent # 获取容器
|
||||
if container:
|
||||
# 查找所有 li.item 元素
|
||||
items = container.find_all('li', class_='item')
|
||||
|
||||
for item in items:
|
||||
try:
|
||||
# 获取链接和标题
|
||||
title_link = item.find('h3')
|
||||
if not title_link:
|
||||
continue
|
||||
|
||||
title = title_link.text.strip()
|
||||
|
||||
# 获取第一个链接作为详情页链接
|
||||
link_tag = item.find('a')
|
||||
if not link_tag:
|
||||
continue
|
||||
|
||||
link = link_tag.get('href', '')
|
||||
if not link.startswith('http'):
|
||||
link = urllib.parse.urljoin(self.siteUrl, link)
|
||||
|
||||
# 提取ID
|
||||
vid = self.extractVodId(link)
|
||||
if not vid:
|
||||
continue
|
||||
|
||||
# 获取图片
|
||||
img_tag = item.find('img')
|
||||
img_url = ""
|
||||
if img_tag:
|
||||
img_url = img_tag.get('src', img_tag.get('data-src', ''))
|
||||
if img_url and not img_url.startswith('http'):
|
||||
img_url = urllib.parse.urljoin(self.siteUrl, img_url)
|
||||
|
||||
# 获取备注信息
|
||||
remarks = ""
|
||||
remarks_tag = item.find('span', class_='remarks')
|
||||
if remarks_tag:
|
||||
remarks = remarks_tag.text.strip()
|
||||
|
||||
# 获取标签信息
|
||||
tags = ""
|
||||
tags_tag = item.find('span', class_='tags')
|
||||
if tags_tag:
|
||||
tags = tags_tag.text.strip()
|
||||
|
||||
# 合并备注和标签
|
||||
if remarks and tags:
|
||||
remarks = f"{remarks} | {tags}"
|
||||
elif tags:
|
||||
remarks = tags
|
||||
|
||||
# 构建视频项
|
||||
videos.append({
|
||||
'vod_id': vid,
|
||||
'vod_name': title,
|
||||
'vod_pic': img_url,
|
||||
'vod_remarks': remarks
|
||||
})
|
||||
except Exception as e:
|
||||
self.log(f"处理视频项时出错: {str(e)}", "ERROR")
|
||||
continue
|
||||
|
||||
# 保存到缓存
|
||||
self.setCache(cache_key, videos, 3600) # 缓存1小时
|
||||
except Exception as e:
|
||||
self.log(f"获取首页视频内容发生错误: {str(e)}", "ERROR")
|
||||
|
||||
result['list'] = videos
|
||||
return result
|
||||
|
||||
def categoryContent(self, tid, pg, filter, extend):
|
||||
"""获取分类内容"""
|
||||
result = {}
|
||||
videos = []
|
||||
|
||||
# 处理页码
|
||||
if pg is None:
|
||||
pg = 1
|
||||
else:
|
||||
pg = int(pg)
|
||||
|
||||
# 构建分类URL - tid是完整的URL路径
|
||||
if tid.startswith("/"):
|
||||
# 替换页码,URL格式可能像: /index.php/vod/show/class/男频/id/1.html
|
||||
if pg > 1:
|
||||
if "html" in tid:
|
||||
category_url = tid.replace(".html", f"/page/{pg}.html")
|
||||
else:
|
||||
category_url = f"{tid}/page/{pg}.html"
|
||||
else:
|
||||
category_url = tid
|
||||
|
||||
full_url = urllib.parse.urljoin(self.siteUrl, category_url)
|
||||
else:
|
||||
# 如果tid不是URL路径,可能是旧版分类ID,尝试查找对应URL
|
||||
category_url = ""
|
||||
for name, url in self.cateManual.items():
|
||||
if name == tid:
|
||||
category_url = url
|
||||
break
|
||||
|
||||
if not category_url:
|
||||
self.log(f"未找到分类ID对应的URL: {tid}", "ERROR")
|
||||
result['list'] = []
|
||||
result['page'] = pg
|
||||
result['pagecount'] = 1
|
||||
result['limit'] = 0
|
||||
result['total'] = 0
|
||||
return result
|
||||
|
||||
# 处理页码
|
||||
if pg > 1:
|
||||
if "html" in category_url:
|
||||
category_url = category_url.replace(".html", f"/page/{pg}.html")
|
||||
else:
|
||||
category_url = f"{category_url}/page/{pg}.html"
|
||||
|
||||
full_url = urllib.parse.urljoin(self.siteUrl, category_url)
|
||||
|
||||
# 请求分类页
|
||||
try:
|
||||
response = self.fetch(full_url)
|
||||
if response and response.status_code == 200:
|
||||
html = response.text
|
||||
soup = BeautifulSoup(html, 'html.parser')
|
||||
|
||||
# 查找视频项,根据实际HTML结构调整
|
||||
items = soup.find_all('li', class_='item')
|
||||
|
||||
for item in items:
|
||||
try:
|
||||
# 获取链接和标题
|
||||
title_tag = item.find('h3')
|
||||
if not title_tag:
|
||||
continue
|
||||
|
||||
title = title_tag.text.strip()
|
||||
|
||||
# 获取链接
|
||||
link_tag = item.find('a')
|
||||
if not link_tag:
|
||||
continue
|
||||
|
||||
link = link_tag.get('href', '')
|
||||
if not link.startswith('http'):
|
||||
link = urllib.parse.urljoin(self.siteUrl, link)
|
||||
|
||||
# 提取ID
|
||||
vid = self.extractVodId(link)
|
||||
if not vid:
|
||||
continue
|
||||
|
||||
# 获取图片
|
||||
img_tag = item.find('img')
|
||||
img_url = ""
|
||||
if img_tag:
|
||||
img_url = img_tag.get('src', img_tag.get('data-src', ''))
|
||||
if img_url and not img_url.startswith('http'):
|
||||
img_url = urllib.parse.urljoin(self.siteUrl, img_url)
|
||||
|
||||
# 获取备注信息
|
||||
remarks = ""
|
||||
remarks_tag = item.find('span', class_='remarks')
|
||||
if remarks_tag:
|
||||
remarks = remarks_tag.text.strip()
|
||||
|
||||
# 获取标签信息
|
||||
tags = ""
|
||||
tags_tag = item.find('span', class_='tags')
|
||||
if tags_tag:
|
||||
tags = tags_tag.text.strip()
|
||||
|
||||
# 合并备注和标签
|
||||
if remarks and tags:
|
||||
remarks = f"{remarks} | {tags}"
|
||||
elif tags:
|
||||
remarks = tags
|
||||
|
||||
# 构建视频项
|
||||
videos.append({
|
||||
'vod_id': vid,
|
||||
'vod_name': title,
|
||||
'vod_pic': img_url,
|
||||
'vod_remarks': remarks
|
||||
})
|
||||
except Exception as e:
|
||||
self.log(f"处理分类视频项时出错: {str(e)}", "ERROR")
|
||||
continue
|
||||
|
||||
# 查找分页信息
|
||||
# 默认值
|
||||
total = len(videos)
|
||||
pagecount = 1
|
||||
limit = 20
|
||||
|
||||
# 尝试查找分页元素
|
||||
pagination = soup.find('ul', class_='page')
|
||||
if pagination:
|
||||
# 查找最后一页的链接
|
||||
last_page_links = pagination.find_all('a')
|
||||
for link in last_page_links:
|
||||
page_text = link.text.strip()
|
||||
if page_text.isdigit():
|
||||
pagecount = max(pagecount, int(page_text))
|
||||
except Exception as e:
|
||||
self.log(f"获取分类内容发生错误: {str(e)}", "ERROR")
|
||||
|
||||
result['list'] = videos
|
||||
result['page'] = pg
|
||||
result['pagecount'] = pagecount
|
||||
result['limit'] = limit
|
||||
result['total'] = total
|
||||
|
||||
return result
|
||||
|
||||
def detailContent(self, ids):
|
||||
"""获取详情内容"""
|
||||
result = {}
|
||||
|
||||
if not ids or len(ids) == 0:
|
||||
return result
|
||||
|
||||
# 视频ID
|
||||
vid = ids[0]
|
||||
|
||||
# 构建播放页URL
|
||||
play_url = f"{self.siteUrl}/index.php/vod/play/id/{vid}/sid/1/nid/1.html"
|
||||
|
||||
try:
|
||||
response = self.fetch(play_url)
|
||||
if not response or response.status_code != 200:
|
||||
return result
|
||||
|
||||
html = response.text
|
||||
soup = BeautifulSoup(html, 'html.parser')
|
||||
|
||||
# 提取视频基本信息
|
||||
# 标题
|
||||
title = ""
|
||||
title_tag = soup.find('h1', class_='items-title')
|
||||
if title_tag:
|
||||
title = title_tag.text.strip()
|
||||
|
||||
# 图片
|
||||
pic = ""
|
||||
pic_tag = soup.find('img', class_='thumb')
|
||||
if pic_tag:
|
||||
pic = pic_tag.get('src', '')
|
||||
if pic and not pic.startswith('http'):
|
||||
pic = urllib.parse.urljoin(self.siteUrl, pic)
|
||||
|
||||
# 简介
|
||||
desc = ""
|
||||
desc_tag = soup.find('div', class_='text-content')
|
||||
if desc_tag:
|
||||
desc = desc_tag.text.strip()
|
||||
|
||||
# 标签/分类
|
||||
tags = []
|
||||
tags_container = soup.find('span', class_='items-tags')
|
||||
if tags_container:
|
||||
tag_links = tags_container.find_all('a')
|
||||
for tag in tag_links:
|
||||
tag_text = tag.text.strip()
|
||||
if tag_text:
|
||||
tags.append(tag_text)
|
||||
|
||||
# 提取播放列表
|
||||
play_from = "偷乐短剧"
|
||||
play_list = []
|
||||
|
||||
# 查找播放列表区域
|
||||
play_area = soup.find('div', class_='swiper-wrapper')
|
||||
if play_area:
|
||||
# 查找所有剧集链接
|
||||
episode_links = play_area.find_all('a')
|
||||
for ep in episode_links:
|
||||
ep_title = ep.text.strip()
|
||||
ep_url = ep.get('href', '')
|
||||
|
||||
if ep_url:
|
||||
# 直接使用URL作为ID
|
||||
if not ep_url.startswith('http'):
|
||||
ep_url = urllib.parse.urljoin(self.siteUrl, ep_url)
|
||||
|
||||
# 提取集数信息
|
||||
ep_num = ep_title
|
||||
if ep_num.isdigit():
|
||||
ep_num = f"第{ep_num}集"
|
||||
|
||||
play_list.append(f"{ep_num}${ep_url}")
|
||||
|
||||
# 如果没有找到播放列表,查找播放按钮
|
||||
if not play_list:
|
||||
play_btn = soup.find('a', class_='btn-play')
|
||||
if play_btn:
|
||||
play_url = play_btn.get('href', '')
|
||||
if play_url:
|
||||
if not play_url.startswith('http'):
|
||||
play_url = urllib.parse.urljoin(self.siteUrl, play_url)
|
||||
|
||||
play_list.append(f"播放${play_url}")
|
||||
|
||||
# 如果仍然没有找到播放链接,使用播放页URL
|
||||
if not play_list:
|
||||
play_url = f"{self.siteUrl}/index.php/vod/play/id/{vid}/sid/1/nid/1.html"
|
||||
play_list.append(f"播放${play_url}")
|
||||
|
||||
# 提取更多信息(导演、演员等)
|
||||
director = ""
|
||||
actor = ""
|
||||
year = ""
|
||||
area = ""
|
||||
remarks = ""
|
||||
|
||||
# 查找备注信息
|
||||
meta_items = soup.find_all('div', class_='meta-item')
|
||||
for item in meta_items:
|
||||
item_title = item.find('span', class_='item-title')
|
||||
item_content = item.find('span', class_='item-content')
|
||||
|
||||
if item_title and item_content:
|
||||
title_text = item_title.text.strip()
|
||||
content_text = item_content.text.strip()
|
||||
|
||||
if "导演" in title_text:
|
||||
director = content_text
|
||||
elif "主演" in title_text:
|
||||
actor = content_text
|
||||
elif "年份" in title_text:
|
||||
year = content_text
|
||||
elif "地区" in title_text:
|
||||
area = content_text
|
||||
elif "简介" in title_text:
|
||||
if not desc:
|
||||
desc = content_text
|
||||
elif "状态" in title_text:
|
||||
remarks = content_text
|
||||
|
||||
# 如果没有从meta-item中获取到remarks
|
||||
if not remarks:
|
||||
remarks_tag = soup.find('span', class_='remarks')
|
||||
if remarks_tag:
|
||||
remarks = remarks_tag.text.strip()
|
||||
|
||||
# 构建标准数据结构
|
||||
vod = {
|
||||
"vod_id": vid,
|
||||
"vod_name": title,
|
||||
"vod_pic": pic,
|
||||
"vod_year": year,
|
||||
"vod_area": area,
|
||||
"vod_remarks": remarks,
|
||||
"vod_actor": actor,
|
||||
"vod_director": director,
|
||||
"vod_content": desc,
|
||||
"type_name": ",".join(tags),
|
||||
"vod_play_from": play_from,
|
||||
"vod_play_url": "#".join(play_list)
|
||||
}
|
||||
|
||||
result = {
|
||||
'list': [vod]
|
||||
}
|
||||
except Exception as e:
|
||||
self.log(f"获取详情内容时出错: {str(e)}", "ERROR")
|
||||
|
||||
return result
|
||||
|
||||
def searchContent(self, key, quick, pg=1):
|
||||
"""搜索功能"""
|
||||
result = {}
|
||||
videos = []
|
||||
|
||||
# 构建搜索URL和参数
|
||||
search_url = f"{self.siteUrl}/index.php/vod/search.html"
|
||||
params = {"wd": key}
|
||||
|
||||
try:
|
||||
response = self.fetch(search_url, data=params)
|
||||
if response and response.status_code == 200:
|
||||
html = response.text
|
||||
soup = BeautifulSoup(html, 'html.parser')
|
||||
|
||||
# 查找搜索结果项
|
||||
search_items = soup.find_all('li', class_='item')
|
||||
|
||||
for item in search_items:
|
||||
try:
|
||||
# 获取标题
|
||||
title_tag = item.find('h3')
|
||||
if not title_tag:
|
||||
continue
|
||||
|
||||
title = title_tag.text.strip()
|
||||
|
||||
# 获取链接
|
||||
link_tag = item.find('a')
|
||||
if not link_tag:
|
||||
continue
|
||||
|
||||
link = link_tag.get('href', '')
|
||||
if not link.startswith('http'):
|
||||
link = urllib.parse.urljoin(self.siteUrl, link)
|
||||
|
||||
# 提取视频ID
|
||||
vid = self.extractVodId(link)
|
||||
if not vid:
|
||||
continue
|
||||
|
||||
# 获取图片
|
||||
img_tag = item.find('img')
|
||||
img_url = ""
|
||||
if img_tag:
|
||||
img_url = img_tag.get('src', img_tag.get('data-src', ''))
|
||||
if img_url and not img_url.startswith('http'):
|
||||
img_url = urllib.parse.urljoin(self.siteUrl, img_url)
|
||||
|
||||
# 获取备注信息
|
||||
remarks = ""
|
||||
remarks_tag = item.find('span', class_='remarks')
|
||||
if remarks_tag:
|
||||
remarks = remarks_tag.text.strip()
|
||||
|
||||
# 获取标签信息
|
||||
tags = ""
|
||||
tags_tag = item.find('span', class_='tags')
|
||||
if tags_tag:
|
||||
tags = tags_tag.text.strip()
|
||||
|
||||
# 合并备注和标签
|
||||
if remarks and tags:
|
||||
remarks = f"{remarks} | {tags}"
|
||||
elif tags:
|
||||
remarks = tags
|
||||
|
||||
# 构建视频项
|
||||
videos.append({
|
||||
'vod_id': vid,
|
||||
'vod_name': title,
|
||||
'vod_pic': img_url,
|
||||
'vod_remarks': remarks
|
||||
})
|
||||
except Exception as e:
|
||||
self.log(f"处理搜索结果时出错: {str(e)}", "ERROR")
|
||||
continue
|
||||
except Exception as e:
|
||||
self.log(f"搜索功能发生错误: {str(e)}", "ERROR")
|
||||
|
||||
result['list'] = videos
|
||||
return result
|
||||
|
||||
def searchContentPage(self, key, quick, pg=1):
|
||||
return self.searchContent(key, quick, pg)
|
||||
|
||||
def playerContent(self, flag, id, vipFlags):
|
||||
"""获取播放内容"""
|
||||
result = {}
|
||||
|
||||
try:
|
||||
# 判断是否已经是视频URL
|
||||
if self.isVideoFormat(id):
|
||||
result["parse"] = 0
|
||||
result["url"] = id
|
||||
result["playUrl"] = ""
|
||||
result["header"] = json.dumps(self.headers)
|
||||
return result
|
||||
|
||||
# 判断是否是完整的页面URL
|
||||
if id.startswith(('http://', 'https://')):
|
||||
play_url = id
|
||||
# 尝试作为相对路径处理
|
||||
elif id.startswith('/'):
|
||||
play_url = urllib.parse.urljoin(self.siteUrl, id)
|
||||
# 假设是视频ID,构建播放页面URL
|
||||
else:
|
||||
# 检查是否是"视频ID_集数"格式
|
||||
parts = id.split('_')
|
||||
if len(parts) > 1 and parts[0].isdigit():
|
||||
vid = parts[0]
|
||||
nid = parts[1]
|
||||
play_url = f"{self.siteUrl}/index.php/vod/play/id/{vid}/sid/1/nid/{nid}.html"
|
||||
else:
|
||||
# 直接当作视频ID处理
|
||||
play_url = f"{self.siteUrl}/index.php/vod/play/id/{id}/sid/1/nid/1.html"
|
||||
|
||||
# 访问播放页获取真实播放地址
|
||||
try:
|
||||
self.log(f"正在解析播放页面: {play_url}")
|
||||
response = self.fetch(play_url)
|
||||
if response and response.status_code == 200:
|
||||
html = response.text
|
||||
|
||||
# 查找player_aaaa变量
|
||||
player_match = re.search(r'var\s+player_aaaa\s*=\s*({.*?});', html, re.DOTALL)
|
||||
if player_match:
|
||||
try:
|
||||
player_data = json.loads(player_match.group(1))
|
||||
if 'url' in player_data:
|
||||
video_url = player_data['url']
|
||||
if not video_url.startswith('http'):
|
||||
video_url = urllib.parse.urljoin(self.siteUrl, video_url)
|
||||
|
||||
self.log(f"从player_aaaa获取到视频地址: {video_url}")
|
||||
result["parse"] = 0
|
||||
result["url"] = video_url
|
||||
result["playUrl"] = ""
|
||||
result["header"] = json.dumps(self.headers)
|
||||
return result
|
||||
except json.JSONDecodeError as e:
|
||||
self.log(f"解析player_aaaa JSON出错: {str(e)}", "ERROR")
|
||||
|
||||
# 如果player_aaaa解析失败,尝试其他方式
|
||||
# 1. 查找video标签
|
||||
video_match = re.search(r'<video[^>]*src=["\'](.*?)["\']', html)
|
||||
if video_match:
|
||||
video_url = video_match.group(1)
|
||||
if not video_url.startswith('http'):
|
||||
video_url = urllib.parse.urljoin(self.siteUrl, video_url)
|
||||
|
||||
self.log(f"从video标签找到视频地址: {video_url}")
|
||||
result["parse"] = 0
|
||||
result["url"] = video_url
|
||||
result["playUrl"] = ""
|
||||
result["header"] = json.dumps(self.headers)
|
||||
return result
|
||||
|
||||
# 2. 查找iframe
|
||||
iframe_match = re.search(r'<iframe[^>]*src=["\'](.*?)["\']', html)
|
||||
if iframe_match:
|
||||
iframe_url = iframe_match.group(1)
|
||||
if not iframe_url.startswith('http'):
|
||||
iframe_url = urllib.parse.urljoin(self.siteUrl, iframe_url)
|
||||
|
||||
self.log(f"找到iframe,正在解析: {iframe_url}")
|
||||
# 访问iframe内容
|
||||
iframe_response = self.fetch(iframe_url)
|
||||
if iframe_response and iframe_response.status_code == 200:
|
||||
iframe_html = iframe_response.text
|
||||
|
||||
# 在iframe内容中查找视频地址
|
||||
iframe_video_match = re.search(r'(https?://[^\'"]+\.(mp4|m3u8|ts))', iframe_html)
|
||||
if iframe_video_match:
|
||||
video_url = iframe_video_match.group(1)
|
||||
|
||||
self.log(f"从iframe中找到视频地址: {video_url}")
|
||||
result["parse"] = 0
|
||||
result["url"] = video_url
|
||||
result["playUrl"] = ""
|
||||
result["header"] = json.dumps({
|
||||
"User-Agent": self.headers["User-Agent"],
|
||||
"Referer": iframe_url
|
||||
})
|
||||
return result
|
||||
|
||||
# 3. 查找任何可能的视频URL
|
||||
url_match = re.search(r'(https?://[^\'"]+\.(mp4|m3u8|ts))', html)
|
||||
if url_match:
|
||||
video_url = url_match.group(1)
|
||||
|
||||
self.log(f"找到可能的视频地址: {video_url}")
|
||||
result["parse"] = 0
|
||||
result["url"] = video_url
|
||||
result["playUrl"] = ""
|
||||
result["header"] = json.dumps(self.headers)
|
||||
return result
|
||||
except Exception as e:
|
||||
self.log(f"解析播放地址时出错: {str(e)}", "ERROR")
|
||||
|
||||
# 如果所有方式都失败,返回外部解析标志
|
||||
self.log("未找到直接可用的视频地址,需要外部解析", "WARNING")
|
||||
result["parse"] = 1 # 表示需要外部解析
|
||||
result["url"] = play_url # 返回播放页面URL
|
||||
result["playUrl"] = ""
|
||||
result["header"] = json.dumps(self.headers)
|
||||
|
||||
except Exception as e:
|
||||
self.log(f"获取播放内容时出错: {str(e)}", "ERROR")
|
||||
|
||||
return result
|
||||
|
||||
def localProxy(self, param):
|
||||
"""本地代理"""
|
||||
return [404, "text/plain", {}, "Not Found"]
|
|
@ -0,0 +1,581 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
import requests
|
||||
import re
|
||||
import json
|
||||
import traceback
|
||||
import sys
|
||||
|
||||
sys.path.append('../../')
|
||||
try:
|
||||
from base.spider import Spider
|
||||
except ImportError:
|
||||
# 定义一个基础接口类,用于本地测试
|
||||
class Spider:
|
||||
def init(self, extend=""):
|
||||
pass
|
||||
|
||||
class Spider(Spider):
|
||||
def __init__(self):
|
||||
self.siteUrl = "https://www.kuaikaw.cn"
|
||||
self.nextData = None # 缓存NEXT_DATA数据
|
||||
self.cateManual = {
|
||||
"甜宠": "462",
|
||||
"古装仙侠": "1102",
|
||||
"现代言情": "1145",
|
||||
"青春": "1170",
|
||||
"豪门恩怨": "585",
|
||||
"逆袭": "417-464",
|
||||
"重生": "439-465",
|
||||
"系统": "1159",
|
||||
"总裁": "1147",
|
||||
"职场商战": "943"
|
||||
}
|
||||
|
||||
def getName(self):
|
||||
# 返回爬虫名称
|
||||
return "河马短剧"
|
||||
|
||||
def init(self, extend=""):
|
||||
return
|
||||
|
||||
def fetch(self, url, headers=None):
|
||||
"""统一的网络请求接口"""
|
||||
if headers is None:
|
||||
headers = {
|
||||
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 Edg/120.0.0.0",
|
||||
"Referer": self.siteUrl,
|
||||
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8",
|
||||
"Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8"
|
||||
}
|
||||
|
||||
try:
|
||||
response = requests.get(url, headers=headers, timeout=10, allow_redirects=True)
|
||||
response.raise_for_status()
|
||||
return response
|
||||
except Exception as e:
|
||||
print(f"请求异常: {url}, 错误: {str(e)}")
|
||||
return None
|
||||
|
||||
def isVideoFormat(self, url):
|
||||
# 检查是否为视频格式
|
||||
video_formats = ['.mp4', '.mkv', '.avi', '.wmv', '.m3u8', '.flv', '.rmvb']
|
||||
for format in video_formats:
|
||||
if format in url.lower():
|
||||
return True
|
||||
return False
|
||||
|
||||
def manualVideoCheck(self):
|
||||
# 不需要手动检查
|
||||
return False
|
||||
|
||||
def homeContent(self, filter):
|
||||
"""获取首页分类及筛选"""
|
||||
result = {}
|
||||
# 分类列表,使用已初始化的cateManual
|
||||
classes = []
|
||||
for k in self.cateManual:
|
||||
classes.append({
|
||||
'type_name': k,
|
||||
'type_id': self.cateManual[k]
|
||||
})
|
||||
result['class'] = classes
|
||||
# 获取首页推荐视频
|
||||
try:
|
||||
result['list'] = self.homeVideoContent()['list']
|
||||
except:
|
||||
result['list'] = []
|
||||
|
||||
return result
|
||||
|
||||
def homeVideoContent(self):
|
||||
"""获取首页推荐视频内容"""
|
||||
videos = []
|
||||
try:
|
||||
response = self.fetch(self.siteUrl)
|
||||
html_content = response.text
|
||||
# 提取NEXT_DATA JSON数据
|
||||
next_data_pattern = r'<script id="__NEXT_DATA__" type="application/json">(.*?)</script>'
|
||||
next_data_match = re.search(next_data_pattern, html_content, re.DOTALL)
|
||||
if next_data_match:
|
||||
next_data_json = json.loads(next_data_match.group(1))
|
||||
page_props = next_data_json.get("props", {}).get("pageProps", {})
|
||||
# 获取轮播图数据 - 这些通常是推荐内容
|
||||
if "bannerList" in page_props and isinstance(page_props["bannerList"], list):
|
||||
banner_list = page_props["bannerList"]
|
||||
for banner in banner_list:
|
||||
book_id = banner.get("bookId", "")
|
||||
book_name = banner.get("bookName", "")
|
||||
cover_url = banner.get("coverWap", banner.get("wapUrl", ""))
|
||||
# 获取状态和章节数
|
||||
status = banner.get("statusDesc", "")
|
||||
total_chapters = banner.get("totalChapterNum", "")
|
||||
if book_id and book_name:
|
||||
videos.append({
|
||||
"vod_id": f"/drama/{book_id}",
|
||||
"vod_name": book_name,
|
||||
"vod_pic": cover_url,
|
||||
"vod_remarks": f"{status} {total_chapters}集" if total_chapters else status
|
||||
})
|
||||
|
||||
# SEO分类下的推荐
|
||||
if "seoColumnVos" in page_props and isinstance(page_props["seoColumnVos"], list):
|
||||
for column in page_props["seoColumnVos"]:
|
||||
book_infos = column.get("bookInfos", [])
|
||||
for book in book_infos:
|
||||
book_id = book.get("bookId", "")
|
||||
book_name = book.get("bookName", "")
|
||||
cover_url = book.get("coverWap", "")
|
||||
status = book.get("statusDesc", "")
|
||||
total_chapters = book.get("totalChapterNum", "")
|
||||
|
||||
if book_id and book_name:
|
||||
videos.append({
|
||||
"vod_id": f"/drama/{book_id}",
|
||||
"vod_name": book_name,
|
||||
"vod_pic": cover_url,
|
||||
"vod_remarks": f"{status} {total_chapters}集" if total_chapters else status
|
||||
})
|
||||
|
||||
# # 去重
|
||||
# seen = set()
|
||||
# unique_videos = []
|
||||
# for video in videos:
|
||||
# if video["vod_id"] not in seen:
|
||||
# seen.add(video["vod_id"])
|
||||
# unique_videos.append(video)
|
||||
# videos = unique_videos
|
||||
|
||||
except Exception as e:
|
||||
print(f"获取首页推荐内容出错: {e}")
|
||||
|
||||
result = {
|
||||
"list": videos
|
||||
}
|
||||
return result
|
||||
|
||||
def categoryContent(self, tid, pg, filter, extend):
|
||||
"""获取分类内容"""
|
||||
result = {}
|
||||
videos = []
|
||||
url = f"{self.siteUrl}/browse/{tid}/{pg}"
|
||||
response = self.fetch(url)
|
||||
html_content = response.text
|
||||
# 提取NEXT_DATA JSON数据
|
||||
next_data_pattern = r'<script id="__NEXT_DATA__" type="application/json">(.*?)</script>'
|
||||
next_data_match = re.search(next_data_pattern, html_content, re.DOTALL)
|
||||
if next_data_match:
|
||||
next_data_json = json.loads(next_data_match.group(1))
|
||||
page_props = next_data_json.get("props", {}).get("pageProps", {})
|
||||
# 获取总页数和当前页
|
||||
current_page = page_props.get("page", 1)
|
||||
total_pages = page_props.get("pages", 1)
|
||||
# 获取书籍列表
|
||||
book_list = page_props.get("bookList", [])
|
||||
# 转换为通用格式
|
||||
for book in book_list:
|
||||
book_id = book.get("bookId", "")
|
||||
book_name = book.get("bookName", "")
|
||||
cover_url = book.get("coverWap", "")
|
||||
status_desc = book.get("statusDesc", "")
|
||||
total_chapters = book.get("totalChapterNum", "")
|
||||
if book_id and book_name:
|
||||
videos.append({
|
||||
"vod_id": f"/drama/{book_id}",
|
||||
"vod_name": book_name,
|
||||
"vod_pic": cover_url,
|
||||
"vod_remarks": f"{status_desc} {total_chapters}集" if total_chapters else status_desc
|
||||
})
|
||||
# 构建返回结果
|
||||
result = {
|
||||
"list": videos,
|
||||
"page": int(current_page),
|
||||
"pagecount": total_pages,
|
||||
"limit": len(videos),
|
||||
"total": total_pages * len(videos) if videos else 0
|
||||
}
|
||||
return result
|
||||
|
||||
def switch(self, key, pg):
|
||||
# 搜索功能
|
||||
search_results = []
|
||||
# 获取第一页结果,并检查总页数
|
||||
url = f"{self.siteUrl}/search?searchValue={key}&page={pg}"
|
||||
response = self.fetch(url)
|
||||
html_content = response.text
|
||||
# 提取NEXT_DATA JSON数据
|
||||
next_data_pattern = r'<script id="__NEXT_DATA__" type="application/json">(.*?)</script>'
|
||||
next_data_match = re.search(next_data_pattern, html_content, re.DOTALL)
|
||||
if next_data_match:
|
||||
next_data_json = json.loads(next_data_match.group(1))
|
||||
page_props = next_data_json.get("props", {}).get("pageProps", {})
|
||||
# 获取总页数
|
||||
total_pages = page_props.get("pages", 1)
|
||||
# 处理所有页的数据
|
||||
all_book_list = []
|
||||
# 添加第一页的书籍列表
|
||||
book_list = page_props.get("bookList", [])
|
||||
all_book_list.extend(book_list)
|
||||
# 如果有多页,获取其他页的数据
|
||||
if total_pages > 1 : # quick模式只获取第一页
|
||||
for page in range(2, total_pages + 1):
|
||||
next_page_url = f"{self.siteUrl}/search?searchValue={key}&page={page}"
|
||||
next_page_response = self.fetch(next_page_url)
|
||||
next_page_html = next_page_response.text
|
||||
next_page_match = re.search(next_data_pattern, next_page_html, re.DOTALL)
|
||||
if next_page_match:
|
||||
next_page_json = json.loads(next_page_match.group(1))
|
||||
next_page_props = next_page_json.get("props", {}).get("pageProps", {})
|
||||
next_page_books = next_page_props.get("bookList", [])
|
||||
all_book_list.extend(next_page_books)
|
||||
# 转换为统一的搜索结果格式
|
||||
for book in all_book_list:
|
||||
book_id = book.get("bookId", "")
|
||||
book_name = book.get("bookName", "")
|
||||
cover_url = book.get("coverWap", "")
|
||||
total_chapters = book.get("totalChapterNum", "0")
|
||||
status_desc = book.get("statusDesc", "")
|
||||
# 构建视频项
|
||||
vod = {
|
||||
"vod_id": f"/drama/{book_id}",
|
||||
"vod_name": book_name,
|
||||
"vod_pic": cover_url,
|
||||
"vod_remarks": f"{status_desc} {total_chapters}集"
|
||||
}
|
||||
search_results.append(vod)
|
||||
result = {
|
||||
"list": search_results,
|
||||
"page": pg
|
||||
}
|
||||
return result
|
||||
|
||||
def searchContent(self, key, quick, pg=1):
|
||||
result = self.switch(key, pg=pg)
|
||||
result['page'] = pg
|
||||
return result
|
||||
|
||||
def searchContentPage(self, key, quick, pg=1):
|
||||
return self.searchContent(key, quick, pg)
|
||||
|
||||
def detailContent(self, ids):
|
||||
# 获取剧集信息
|
||||
vod_id = ids[0]
|
||||
episode_id = None
|
||||
chapter_id = None
|
||||
|
||||
if not vod_id.startswith('/drama/'):
|
||||
if vod_id.startswith('/episode/'):
|
||||
episode_info = vod_id.replace('/episode/', '').split('/')
|
||||
if len(episode_info) >= 2:
|
||||
episode_id = episode_info[0]
|
||||
chapter_id = episode_info[1]
|
||||
vod_id = f'/drama/{episode_id}'
|
||||
else:
|
||||
vod_id = '/drama/' + vod_id
|
||||
|
||||
drama_url = self.siteUrl + vod_id
|
||||
print(f"请求URL: {drama_url}")
|
||||
|
||||
headers = {
|
||||
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 Edg/120.0.0.0",
|
||||
"Referer": self.siteUrl,
|
||||
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8",
|
||||
"Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8"
|
||||
}
|
||||
|
||||
rsp = self.fetch(drama_url, headers=headers)
|
||||
if not rsp or rsp.status_code != 200:
|
||||
print(f"请求失败,状态码: {getattr(rsp, 'status_code', 'N/A')}")
|
||||
return {}
|
||||
|
||||
html = rsp.text
|
||||
next_data_match = re.search(r'<script id="__NEXT_DATA__" type="application/json">(.*?)</script>', html, re.DOTALL)
|
||||
|
||||
if not next_data_match:
|
||||
print("未找到NEXT_DATA内容")
|
||||
return {}
|
||||
|
||||
try:
|
||||
next_data = json.loads(next_data_match.group(1))
|
||||
page_props = next_data.get("props", {}).get("pageProps", {})
|
||||
print(f"找到页面属性,包含 {len(page_props.keys())} 个键")
|
||||
|
||||
book_info = page_props.get("bookInfoVo", {})
|
||||
chapter_list = page_props.get("chapterList", [])
|
||||
|
||||
title = book_info.get("title", "")
|
||||
sub_title = f"{book_info.get('totalChapterNum', '')}集"
|
||||
|
||||
categories = []
|
||||
for category in book_info.get("categoryList", []):
|
||||
categories.append(category.get("name", ""))
|
||||
|
||||
vod_content = book_info.get("introduction", "")
|
||||
|
||||
vod = {
|
||||
"vod_id": vod_id,
|
||||
"vod_name": title,
|
||||
"vod_pic": book_info.get("coverWap", ""),
|
||||
"type_name": ",".join(categories),
|
||||
"vod_year": "",
|
||||
"vod_area": book_info.get("countryName", ""),
|
||||
"vod_remarks": sub_title,
|
||||
"vod_actor": ", ".join([p.get("name", "") for p in book_info.get("performerList", [])]),
|
||||
"vod_director": "",
|
||||
"vod_content": vod_content
|
||||
}
|
||||
|
||||
# 处理播放列表
|
||||
play_url_list = []
|
||||
episodes = []
|
||||
|
||||
if chapter_list:
|
||||
print(f"找到 {len(chapter_list)} 个章节")
|
||||
|
||||
# 先检查是否有可以直接使用的MP4链接作为模板
|
||||
mp4_template = None
|
||||
first_mp4_chapter_id = None
|
||||
|
||||
# 先搜索第一个章节的MP4链接
|
||||
# 为提高成功率,尝试直接请求第一个章节的播放页
|
||||
if chapter_list and len(chapter_list) > 0:
|
||||
first_chapter = chapter_list[0]
|
||||
first_chapter_id = first_chapter.get("chapterId", "")
|
||||
drama_id_clean = vod_id.replace('/drama/', '')
|
||||
|
||||
if first_chapter_id and drama_id_clean:
|
||||
first_episode_url = f"{self.siteUrl}/episode/{drama_id_clean}/{first_chapter_id}"
|
||||
print(f"请求第一集播放页: {first_episode_url}")
|
||||
|
||||
first_rsp = self.fetch(first_episode_url, headers=headers)
|
||||
if first_rsp and first_rsp.status_code == 200:
|
||||
first_html = first_rsp.text
|
||||
# 直接从HTML提取MP4链接
|
||||
mp4_pattern = r'(https?://[^"\']+\.mp4)'
|
||||
mp4_matches = re.findall(mp4_pattern, first_html)
|
||||
if mp4_matches:
|
||||
mp4_template = mp4_matches[0]
|
||||
first_mp4_chapter_id = first_chapter_id
|
||||
print(f"找到MP4链接模板: {mp4_template}")
|
||||
print(f"模板对应的章节ID: {first_mp4_chapter_id}")
|
||||
|
||||
# 如果未找到模板,再检查章节对象中是否有MP4链接
|
||||
if not mp4_template:
|
||||
for chapter in chapter_list[:5]: # 只检查前5个章节以提高效率
|
||||
if "chapterVideoVo" in chapter and chapter["chapterVideoVo"]:
|
||||
chapter_video = chapter["chapterVideoVo"]
|
||||
mp4_url = chapter_video.get("mp4", "") or chapter_video.get("mp4720p", "") or chapter_video.get("vodMp4Url", "")
|
||||
if mp4_url and ".mp4" in mp4_url:
|
||||
mp4_template = mp4_url
|
||||
first_mp4_chapter_id = chapter.get("chapterId", "")
|
||||
print(f"从chapterVideoVo找到MP4链接模板: {mp4_template}")
|
||||
print(f"模板对应的章节ID: {first_mp4_chapter_id}")
|
||||
break
|
||||
|
||||
# 遍历所有章节处理播放信息
|
||||
for chapter in chapter_list:
|
||||
chapter_id = chapter.get("chapterId", "")
|
||||
chapter_name = chapter.get("chapterName", "")
|
||||
|
||||
# 1. 如果章节自身有MP4链接,直接使用
|
||||
if "chapterVideoVo" in chapter and chapter["chapterVideoVo"]:
|
||||
chapter_video = chapter["chapterVideoVo"]
|
||||
mp4_url = chapter_video.get("mp4", "") or chapter_video.get("mp4720p", "") or chapter_video.get("vodMp4Url", "")
|
||||
if mp4_url and ".mp4" in mp4_url:
|
||||
episodes.append(f"{chapter_name}${mp4_url}")
|
||||
continue
|
||||
|
||||
# 2. 如果有MP4模板,尝试替换章节ID构建MP4链接
|
||||
if mp4_template and first_mp4_chapter_id and chapter_id:
|
||||
# 替换模板中的章节ID部分
|
||||
if first_mp4_chapter_id in mp4_template:
|
||||
new_mp4_url = mp4_template.replace(first_mp4_chapter_id, chapter_id)
|
||||
episodes.append(f"{chapter_name}${new_mp4_url}")
|
||||
continue
|
||||
|
||||
# 3. 如果上述方法都不可行,回退到使用chapter_id构建中间URL
|
||||
if chapter_id and chapter_name:
|
||||
url = f"{vod_id}${chapter_id}${chapter_name}"
|
||||
episodes.append(f"{chapter_name}${url}")
|
||||
|
||||
if not episodes and vod_id:
|
||||
# 尝试构造默认的集数
|
||||
total_chapters = int(book_info.get("totalChapterNum", "0"))
|
||||
if total_chapters > 0:
|
||||
print(f"尝试构造 {total_chapters} 个默认集数")
|
||||
|
||||
# 如果知道章节ID的模式,可以构造
|
||||
if chapter_id and episode_id:
|
||||
for i in range(1, total_chapters + 1):
|
||||
chapter_name = f"第{i}集"
|
||||
url = f"{vod_id}${chapter_id}${chapter_name}"
|
||||
episodes.append(f"{chapter_name}${url}")
|
||||
else:
|
||||
# 使用普通的构造方式
|
||||
for i in range(1, total_chapters + 1):
|
||||
chapter_name = f"第{i}集"
|
||||
url = f"{vod_id}${chapter_name}"
|
||||
episodes.append(f"{chapter_name}${url}")
|
||||
|
||||
if episodes:
|
||||
play_url_list.append("#".join(episodes))
|
||||
vod['vod_play_from'] = '河马剧场'
|
||||
vod['vod_play_url'] = '$$$'.join(play_url_list)
|
||||
|
||||
result = {
|
||||
'list': [vod]
|
||||
}
|
||||
return result
|
||||
except Exception as e:
|
||||
print(f"解析详情页失败: {str(e)}")
|
||||
print(traceback.format_exc())
|
||||
return {}
|
||||
|
||||
def playerContent(self, flag, id, vipFlags):
|
||||
result = {}
|
||||
print(f"调用playerContent: flag={flag}, id={id}")
|
||||
|
||||
headers = {
|
||||
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 Edg/120.0.0.0",
|
||||
"Referer": self.siteUrl,
|
||||
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8",
|
||||
"Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8"
|
||||
}
|
||||
|
||||
# 解析id参数
|
||||
parts = id.split('$')
|
||||
drama_id = None
|
||||
chapter_id = None
|
||||
|
||||
if len(parts) >= 2:
|
||||
drama_id = parts[0]
|
||||
chapter_id = parts[1]
|
||||
chapter_name = parts[2] if len(parts) > 2 else "第一集"
|
||||
print(f"解析参数: drama_id={drama_id}, chapter_id={chapter_id}")
|
||||
else:
|
||||
# 处理旧数据格式
|
||||
print(f"使用原始URL格式: {id}")
|
||||
result["parse"] = 0
|
||||
result["url"] = id
|
||||
result["header"] = json.dumps(headers)
|
||||
return result
|
||||
|
||||
# 直接检查chapter_id是否包含http(可能已经是视频链接)
|
||||
if 'http' in chapter_id and '.mp4' in chapter_id:
|
||||
print(f"已经是MP4链接: {chapter_id}")
|
||||
result["parse"] = 0
|
||||
result["url"] = chapter_id
|
||||
result["header"] = json.dumps(headers)
|
||||
return result
|
||||
|
||||
# 构建episode页面URL
|
||||
drama_id_clean = drama_id.replace('/drama/', '')
|
||||
episode_url = f"{self.siteUrl}/episode/{drama_id_clean}/{chapter_id}"
|
||||
print(f"请求episode页面: {episode_url}")
|
||||
|
||||
try:
|
||||
rsp = self.fetch(episode_url, headers=headers)
|
||||
if not rsp or rsp.status_code != 200:
|
||||
print(f"请求失败,状态码: {getattr(rsp, 'status_code', 'N/A')}")
|
||||
result["parse"] = 0
|
||||
result["url"] = id
|
||||
result["header"] = json.dumps(headers)
|
||||
return result
|
||||
|
||||
html = rsp.text
|
||||
print(f"获取页面大小: {len(html)} 字节")
|
||||
|
||||
# 尝试从NEXT_DATA提取视频链接
|
||||
mp4_url = None
|
||||
|
||||
# 方法1: 从NEXT_DATA提取
|
||||
next_data_match = re.search(r'<script id="__NEXT_DATA__" type="application/json">(.*?)</script>', html, re.DOTALL)
|
||||
if next_data_match:
|
||||
try:
|
||||
print("找到NEXT_DATA")
|
||||
next_data = json.loads(next_data_match.group(1))
|
||||
page_props = next_data.get("props", {}).get("pageProps", {})
|
||||
|
||||
# 从chapterList中查找当前章节
|
||||
chapter_list = page_props.get("chapterList", [])
|
||||
print(f"找到章节列表,长度: {len(chapter_list)}")
|
||||
|
||||
for chapter in chapter_list:
|
||||
if chapter.get("chapterId") == chapter_id:
|
||||
print(f"找到匹配的章节: {chapter.get('chapterName')}")
|
||||
chapter_video = chapter.get("chapterVideoVo", {})
|
||||
mp4_url = chapter_video.get("mp4", "") or chapter_video.get("mp4720p", "") or chapter_video.get("vodMp4Url", "")
|
||||
if mp4_url:
|
||||
print(f"从chapterList找到MP4链接: {mp4_url}")
|
||||
break
|
||||
|
||||
# 如果未找到,尝试从当前章节获取
|
||||
if not mp4_url:
|
||||
current_chapter = page_props.get("chapterInfo", {})
|
||||
if current_chapter:
|
||||
print("找到当前章节信息")
|
||||
chapter_video = current_chapter.get("chapterVideoVo", {})
|
||||
mp4_url = chapter_video.get("mp4", "") or chapter_video.get("mp4720p", "") or chapter_video.get("vodMp4Url", "")
|
||||
if mp4_url:
|
||||
print(f"从chapterInfo找到MP4链接: {mp4_url}")
|
||||
except Exception as e:
|
||||
print(f"解析NEXT_DATA失败: {str(e)}")
|
||||
print(traceback.format_exc())
|
||||
|
||||
# 方法2: 直接从HTML中提取MP4链接
|
||||
if not mp4_url:
|
||||
mp4_pattern = r'(https?://[^"\']+\.mp4)'
|
||||
mp4_matches = re.findall(mp4_pattern, html)
|
||||
if mp4_matches:
|
||||
# 查找含有chapter_id的链接
|
||||
matched_mp4 = False
|
||||
for url in mp4_matches:
|
||||
if chapter_id in url:
|
||||
mp4_url = url
|
||||
matched_mp4 = True
|
||||
print(f"从HTML直接提取章节MP4链接: {mp4_url}")
|
||||
break
|
||||
|
||||
# 如果没找到包含chapter_id的链接,使用第一个
|
||||
if not matched_mp4 and mp4_matches:
|
||||
mp4_url = mp4_matches[0]
|
||||
print(f"从HTML直接提取MP4链接: {mp4_url}")
|
||||
|
||||
if mp4_url and ".mp4" in mp4_url:
|
||||
print(f"最终找到的MP4链接: {mp4_url}")
|
||||
result["parse"] = 0
|
||||
result["url"] = mp4_url
|
||||
result["header"] = json.dumps(headers)
|
||||
return result
|
||||
else:
|
||||
print(f"未找到有效的MP4链接,尝试再次解析页面内容")
|
||||
# 再尝试一次从HTML中广泛搜索所有可能的MP4链接
|
||||
all_mp4_pattern = r'(https?://[^"\']+\.mp4)'
|
||||
all_mp4_matches = re.findall(all_mp4_pattern, html)
|
||||
if all_mp4_matches:
|
||||
mp4_url = all_mp4_matches[0]
|
||||
print(f"从HTML广泛搜索找到MP4链接: {mp4_url}")
|
||||
result["parse"] = 0
|
||||
result["url"] = mp4_url
|
||||
result["header"] = json.dumps(headers)
|
||||
return result
|
||||
|
||||
print(f"未找到视频链接,返回原episode URL: {episode_url}")
|
||||
result["parse"] = 0
|
||||
result["url"] = episode_url
|
||||
result["header"] = json.dumps(headers)
|
||||
return result
|
||||
except Exception as e:
|
||||
print(f"请求或解析失败: {str(e)}")
|
||||
print(traceback.format_exc())
|
||||
result["parse"] = 0
|
||||
result["url"] = id
|
||||
result["header"] = json.dumps(headers)
|
||||
return result
|
||||
|
||||
def localProxy(self, param):
|
||||
# 本地代理处理,此处简单返回传入的参数
|
||||
return [200, "video/MP2T", {}, param]
|
||||
|
||||
def destroy(self):
|
||||
# 资源回收
|
||||
pass
|
Binary file not shown.
Loading…
Reference in New Issue