diff --git a/.版本.png b/.版本.png index afd006d..54dbba3 100644 Binary files a/.版本.png and b/.版本.png differ diff --git a/JS/88看球.js b/JS/88看球.js new file mode 100644 index 0000000..c552ea3 --- /dev/null +++ b/JS/88看球.js @@ -0,0 +1,61 @@ +var rule = { + title:'88看球', + // host:'http://www.88kanqiu.cc', + host:'http://www.88kanqiu.bar/', + url: "/match/fyclass/live", + searchUrl: "", + searchable: 0, + quickSearch: 0, + class_parse: ".nav-pills li;a&&Text;a&&href;/match/(\\d+)/live", + headers: { + "User-Agent": "PC_UA", + }, + timeout: 5000, + play_parse: true, + pagecount:{"1":1,"2":1,"4":1,"22":1,"8":1,"9":1,"10":1,"14":1,"15":1,"12":1,"13":1,"16":1,"28":1,"7":1,"11":1,"33":1,"27":1,"23":1,"26":1,"3":1,"21":1,"18":1}, + lazy: `js: + if(/embed=/.test(input)) { + let url = input.match(/embed=(.*?)&/)[1]; + url = base64Decode(url); + input = { + jx:0, + url: url.split('#')[0], + parse: 0 + } + } else if (/\?url=/.test(input)){ + input = { + jx:0, + url: input.split('?url=')[1].split('#')[0], + parse: 0 + } + } else { + input + } + `, + limit: 6, + double: false, + 推荐: "*", + 一级: ".list-group .group-game-item;.d-none&&Text;img&&src;.btn&&Text;a&&href", + 二级: { + title: ".game-info-container&&Text;.customer-navbar-nav li&&Text", + img: "img&&src", + desc: ";;;div.team-name:eq(0)&&Text;div.team-name:eq(1)&&Text", + content: "div.game-time&&Text", + tabs: "js:TABS=['实时直播']", + lists: `js: + LISTS = []; + let html = request(input.replace('play', 'play-url')); + let pdata = JSON.parse(html).data; + pdata = pdata.slice(6); + pdata = pdata.slice(0, -2); + pdata = base64Decode(pdata); + // log(pdata); + let jo = JSON.parse(pdata).links; + let d = jo.map(function (it) { + return it.name + '$' + urlencode(it.url) + }); + LISTS.push(d) + `, + }, + 搜索: "", +}; \ No newline at end of file diff --git a/JS/三六零弹幕.js b/JS/三六零.js similarity index 100% rename from JS/三六零弹幕.js rename to JS/三六零.js diff --git a/JS/优酷弹幕.js b/JS/优酷视频.js similarity index 99% rename from JS/优酷弹幕.js rename to JS/优酷视频.js index f335b99..fea1ad3 100644 --- a/JS/优酷弹幕.js +++ b/JS/优酷视频.js @@ -2132,14 +2132,14 @@ var rule = { parse: 0, url: bata.url, jx: 0, - danmaku: "http://103.45.162.207:25252/hbdm.php?key=7894561232&id=" + input.split("?")[0] + danmaku: "https://danmu.zxz.ee/?type=xml&id=" + input.split("?")[0] }; } else { input = { parse: 0, url: input.split("?")[0], jx: 1, - danmaku: "http://103.45.162.207:25252/hbdm.php?key=7894561232&id=" + input.split("?")[0] + danmaku: "https://danmu.zxz.ee/?type=xml&id=" + input.split("?")[0] }; } } catch { @@ -2147,7 +2147,7 @@ var rule = { parse: 0, url: input.split("?")[0], jx: 1, - danmaku: "http://103.45.162.207:25252/hbdm.php?key=7894561232&id=" + input.split("?")[0] + danmaku: "https://danmu.zxz.ee/?type=xml&id=" + input.split("?")[0] }; } }), diff --git a/JS/爱奇艺弹幕.js b/JS/爱奇艺.js similarity index 99% rename from JS/爱奇艺弹幕.js rename to JS/爱奇艺.js index 3f3c5ab..7617d4c 100644 --- a/JS/爱奇艺弹幕.js +++ b/JS/爱奇艺.js @@ -1354,14 +1354,14 @@ var rule = { parse: 0, url: bata.url, jx: 0, - danmaku: "http://103.45.162.207:25252/hbdm.php?key=7894561232&id=" + input.split("?")[0] + danmaku: "https://danmu.zxz.ee/?type=xml&id=" + input.split("?")[0] }; } else { input = { parse: 0, url: input.split("?")[0], jx: 1, - danmaku: "http://103.45.162.207:25252/hbdm.php?key=7894561232&id=" + input.split("?")[0] + danmaku: "https://danmu.zxz.ee/?type=xml&id=" + input.split("?")[0] }; } } catch { @@ -1369,7 +1369,7 @@ var rule = { parse: 0, url: input.split("?")[0], jx: 1, - danmaku: "http://103.45.162.207:25252/hbdm.php?key=7894561232&id=" + input.split("?")[0] + danmaku: "https://danmu.zxz.ee/?type=xml&id=" + input.split("?")[0] }; } }), diff --git a/JS/磁力熊.js b/JS/磁力熊.js deleted file mode 100644 index ba22280..0000000 --- a/JS/磁力熊.js +++ /dev/null @@ -1,101 +0,0 @@ -var rule = { - title:'磁力熊[磁]', - host:'https://www.cilixiong.com', - homeUrl:'/top250/index.html', - // url: '/fyclass/index_(fypage-1).html', - url: '/fyclassfyfilter-(fypage-1).html', - filter_url:'-{{fl.class or "0"}}-{{fl.area or "0"}}', - filter:{ - "1":[{"key":"class","name":"类型","value":[{"n":"全部","v":"0"},{"n":"剧情","v":"1"},{"n":"喜剧","v":"2"},{"n":"惊悚","v":"3"},{"n":"动作","v":"4"},{"n":"爱情","v":"5"},{"n":"犯罪","v":"6"},{"n":"恐怖","v":"7"},{"n":"冒险","v":"8"},{"n":"悬疑","v":"9"},{"n":"科幻","v":"10"},{"n":"家庭","v":"11"},{"n":"奇幻","v":"12"},{"n":"动画","v":"13"},{"n":"战争","v":"14"},{"n":"历史","v":"15"},{"n":"传记","v":"16"},{"n":"音乐","v":"17"},{"n":"歌舞","v":"18"},{"n":"运动","v":"19"},{"n":"西部","v":"20"},{"n":"灾难","v":"21"},{"n":"古装","v":"22"},{"n":"情色","v":"23"},{"n":"同性","v":"24"},{"n":"儿童","v":"25"},{"n":"纪录片","v":"26"}]},{"key":"area","name":"地区","value":[{"n":"全部","v":"0"},{"n":"大陆","v":"1"},{"n":"香港","v":"2"},{"n":"台湾","v":"3"},{"n":"美国","v":"4"},{"n":"日本","v":"5"},{"n":"韩国","v":"6"},{"n":"英国","v":"7"},{"n":"法国","v":"8"},{"n":"德国","v":"9"},{"n":"印度","v":"10"},{"n":"泰国","v":"11"},{"n":"丹麦","v":"12"},{"n":"瑞典","v":"13"},{"n":"巴西","v":"14"},{"n":"加拿大","v":"15"},{"n":"俄罗斯","v":"16"},{"n":"意大利","v":"17"},{"n":"比利时","v":"18"},{"n":"爱尔兰","v":"19"},{"n":"西班牙","v":"20"},{"n":"澳大利亚","v":"21"},{"n":"波兰","v":"22"},{"n":"土耳其","v":"23"},{"n":"越南","v":"24"}]}], - "2":[{"key":"class","name":"类型","value":[{"n":"全部","v":"0"},{"n":"剧情","v":"1"},{"n":"喜剧","v":"2"},{"n":"惊悚","v":"3"},{"n":"动作","v":"4"},{"n":"爱情","v":"5"},{"n":"犯罪","v":"6"},{"n":"恐怖","v":"7"},{"n":"冒险","v":"8"},{"n":"悬疑","v":"9"},{"n":"科幻","v":"10"},{"n":"家庭","v":"11"},{"n":"奇幻","v":"12"},{"n":"动画","v":"13"},{"n":"战争","v":"14"},{"n":"历史","v":"15"},{"n":"传记","v":"16"},{"n":"音乐","v":"17"},{"n":"歌舞","v":"18"},{"n":"运动","v":"19"},{"n":"西部","v":"20"},{"n":"灾难","v":"21"},{"n":"古装","v":"22"},{"n":"情色","v":"23"},{"n":"同性","v":"24"},{"n":"儿童","v":"25"},{"n":"纪录片","v":"26"}]},{"key":"area","name":"地区","value":[{"n":"全部","v":"0"},{"n":"大陆","v":"1"},{"n":"香港","v":"2"},{"n":"台湾","v":"3"},{"n":"美国","v":"4"},{"n":"日本","v":"5"},{"n":"韩国","v":"6"},{"n":"英国","v":"7"},{"n":"法国","v":"8"},{"n":"德国","v":"9"},{"n":"印度","v":"10"},{"n":"泰国","v":"11"},{"n":"丹麦","v":"12"},{"n":"瑞典","v":"13"},{"n":"巴西","v":"14"},{"n":"加拿大","v":"15"},{"n":"俄罗斯","v":"16"},{"n":"意大利","v":"17"},{"n":"比利时","v":"18"},{"n":"爱尔兰","v":"19"},{"n":"西班牙","v":"20"},{"n":"澳大利亚","v":"21"},{"n":"波兰","v":"22"},{"n":"土耳其","v":"23"},{"n":"越南","v":"24"}]}] - }, - searchUrl: '/e/search/index.php#classid=1,2&show=title&tempid=1&keyboard=**;post', - searchable:2, - quickSearch:0, - filterable:1, - headers:{ - 'User-Agent': 'MOBILE_UA' - }, - timeout:5000, - class_name:'电影&剧集&豆瓣电影Top250&IMDB Top250&高分悬疑片&高分喜剧片&高分传记片&高分爱情片&高分犯罪片&高分恐怖片&高分冒险片&高分武侠片&高分奇幻片&高分历史片&高分战争片&高分歌舞片&高分灾难片&高分情色片&高分西部片&高分音乐片&高分科幻片&高分动作片&高分动画片&高分纪录片&冷门佳片', - class_url:'1&2&/top250/&/s/imdbtop250/&/s/suspense/&/s/comedy/&/s/biopic/&/s/romance/&/s/crime/&/s/horror/&/s/adventure/&/s/martial/&/s/fantasy/&/s/history/&/s/war/&/s/musical/&/s/disaster/&/s/erotic/&/s/west/&/s/music/&/s/sci-fi/&s/action/&/s/animation/&/s/documentary/&/s/unpopular/', - play_parse:true, - lazy:'', - limit:6, - 推荐: `js: - pdfh=jsp.pdfh;pdfa=jsp.pdfa;pd=jsp.pd; - var d = []; - var html = request(input); - var list = pdfa(html, 'body&&.col'); - list.forEach(it => { - d.push({ - title: pdfh(it, 'h2&&Text'), - desc: pdfh(it, '.me-auto&&Text') + '分 / ' + pdfh(it, '.small&&Text'), - // pic_url: pd(it, '.card-img&&style'), // 只有 影视TV&爱佬版 有图片 - pic_url: /!'/.test(pd(it, '.card-img&&style'))?pd(it, '.card-img&&style'):pd(it, '.card-img&&style').replaceAll("'",""), // 兼容 影视TV&爱佬版 以外的其它壳子 - url: pd(it, 'a&&href') - }); - }) - setResult(d); - `, - 一级: `js: - pdfh=jsp.pdfh;pdfa=jsp.pdfa;pd=jsp.pd; - var d = []; - if (MY_CATE !== '1' && MY_CATE !== '2') { - let turl = (MY_PAGE === 1)? 'index' : 'index_'+ MY_PAGE; - input = HOST + MY_CATE + turl + '.html'; - } - var html = request(input); - var list = pdfa(html, 'body&&.col'); - list.forEach(it => { - d.push({ - title: pdfh(it, 'h2&&Text'), - desc: pdfh(it, '.me-auto&&Text') + '分 / ' + pdfh(it, '.small&&Text'), - // pic_url: pdfh(it, '.card-img&&style'), // 只有 影视TV&爱佬版 有图片 - pic_url: /!'/.test(pd(it, '.card-img&&style'))?pd(it, '.card-img&&style'):pd(it, '.card-img&&style').replaceAll("'",""), // 兼容 影视TV&爱佬版 以外的其它壳子 - url: pd(it, 'a&&href') - }); - }) - setResult(d); - `, - 二级:{ - title:'h1&&Text;p.mb-2:eq(4)&&Text', - desc:'p.mb-2:eq(1)&&Text;;;p.mb-2:eq(7)&&Text;p.mb-2:eq(5)&&Text', - img:'.rounded-2&&src', - content:'.mv_card_box&&Text', - // tabs:'js:TABS = ["道长磁力"]', - // lists:'.mv_down:eq(#id)&&.border-bottom', - // list_text:'a&&Text', - // list_url:'a&&href', - - tabs:'js:TABS = ["道长磁力","道长在线预览"]', - lists:`js: - log(TABS); - pdfh=jsp.pdfh;pdfa=jsp.pdfa;pd=jsp.pd; - LISTS = []; - var dd=[]; - TABS.forEach(function(tab) { - if (/道长磁力/.test(tab)) { - var d = pdfa(html, '.mv_down&&.border-bottom'); - d = d.map(function(it) { - var title = pdfh(it, 'a&&Text'); - log('title >>>>>>>>>>>>>>>>>>>>>>>>>>' + title); - var burl = pd(it, 'a&&href'); - log('burl >>>>>>>>>>>>>>>>>>>>>>>>>>' + burl); - return title + '$' + burl - }); - LISTS.push(d) - } else if (/道长在线预览/.test(tab)) { - var d = pd(html, 'iframe&&src'); - if (d) { - d=['第一集在线播放预览$' + d] - } else { - d=['没有预览不要点$http://www.sharenice.net/douyin/23852'] - } - LISTS.push(d) - } - }); - `, - }, - 搜索:'.col;h2&&Text;.card-img&&style;.me-auto&&Text;a&&href', -} \ No newline at end of file diff --git a/JS/米兔弹幕.js b/JS/米兔弹幕.js deleted file mode 100644 index 31d476a..0000000 --- a/JS/米兔弹幕.js +++ /dev/null @@ -1,224 +0,0 @@ -globalThis.h_ost = 'http://mitu.jiajiayoutian.top/'; -var key = CryptoJS.enc.Base64.parse("ZDAzMmMxMjg3NmJjNjg0OA=="); -var iv = CryptoJS.enc.Base64.parse("ZDAzMmMxMjg3NmJjNjg0OA=="); -globalThis.AES_Decrypt = function(word) { - try { - var decrypt = CryptoJS.AES.decrypt(word, key, { - iv: iv, - mode: CryptoJS.mode.CBC, - padding: CryptoJS.pad.Pkcs7, - }); - const decryptedText = decrypt.toString(CryptoJS.enc.Utf8); - if (!decryptedText) { - throw new Error("解密后的内容为空"); - } - return decryptedText; - } catch (e) { - console.error("解密失败:", e); - return null; - } -}; -globalThis.AES_Encrypt = function(word) { - var encrypted = CryptoJS.AES.encrypt(word, key, { - iv: iv, - mode: CryptoJS.mode.CBC, - padding: CryptoJS.pad.Pkcs7 - }); - return encrypted.toString(); -}; - -globalThis.vod1 = function(t, pg) { - let html1 = request(h_ost + 'api.php/getappapi.index/typeFilterVodList', { - body: { - area: '全部', - year: '全部', - type_id: t, - page: pg, - sort: '最新', - lang: '全部', - class: '全部' - }, - headers: { - 'User-Agent': 'okhttp/3.14.9', - 'Content-Type': 'application/x-www-form-urlencoded' - }, - 'method': 'POST' - }, true); - let html = JSON.parse(html1); - return (AES_Decrypt(html.data)); -} -globalThis.vodids = function(ids) { - let html1 = fetch(h_ost + 'api.php/getappapi.index/vodDetail', { - method: 'POST', - headers: { - 'User-Agent': 'okhttp/3.14.9', - 'Content-Type': 'application/x-www-form-urlencoded' - }, - body: { - vod_id: ids, - } - }); - let html = JSON.parse(html1); - const rdata = JSON.parse(AES_Decrypt(html.data)); - console.log(rdata); - const data = { - vod_id: ids, - vod_name: rdata.vod.vod_name, - vod_remarks: rdata.vod.vod_remarks, - vod_actor: rdata.vod.vod_actor, - vod_director: rdata.vod.vod_director, - vod_content: rdata.vod.vod_content, - vod_play_from: '', - vod_play_url: '' - }; - - rdata.vod_play_list.forEach((value) => { - data.vod_play_from += value.player_info.show + '$$$'; - value.urls.forEach((v) => { - data.vod_play_url += v.name + '$' + value.player_info.parse + '~' + v.url + '~' + rdata.vod.vod_name + '~' + v.name + '#'; - }); - data.vod_play_url += '$$$'; - }); - return data; -} -//搜索 -globalThis.ssvod = function(wd) { - var html1 = fetch(h_ost + 'api.php/getappapi.index/searchList', { - method: 'POST', - headers: { - 'User-Agent': 'okhttp/3.14.9', - 'Content-Type': 'application/x-www-form-urlencoded' - }, - body: { - keywords: wd, - typepage_id: 1, - } - }); - let html = JSON.parse(html1); - return AES_Decrypt(html.data); -} -//解析 -globalThis.jxx = function(id, url, name, juji) { - try { - if (id.includes('xmflv')) { - return { - parse: 1, - url: id + url, - jx: 0, - danmaku: 'http://103.45.162.207:25252/hbdm.php?key=7894561232&id=' + '&jm=' + name + '&js=' + juji + '&key=741852963' - }; - } - //log(id); - if (url.includes('m3u8')) { - return { - parse: 0, - url: url, - jx: 1, - danmaku: 'http://103.45.162.207:25252/hbdm.php?key=7894561232&id=' + '&jm=' + name + '&js=' + juji + '&key=741852963' - }; - } - if (id.includes('http')) { - let purl = JSON.parse(request(id + url)).url; - return { - parse: 0, - url: purl, - jx: 0, - danmaku: 'http://103.45.162.207:25252/hbdm.php?key=7894561232&id=' + '&jm=' + name + '&js=' + juji + '&key=741852963' - }; - } - let html1 = request(h_ost + 'api.php/getappapi.index/vodParse', { - method: 'POST', - headers: { - 'User-Agent': 'okhttp/3.14.9', - 'Content-Type': 'application/x-www-form-urlencoded' - }, - body: { - parse_api: id, - url: AES_Encrypt(url), - } - }); - let html = AES_Decrypt(JSON.parse(html1).data); - console.log(html1); - let decry = html.replace(/\n/g, '').replace(/\\/g, ''); - let matches = decry.match(/"url":"([^"]+)"/); - if (!matches || matches[1] === null) { - matches = decry.match(/"url": "([^"]+)"/); - } - return { - parse: 0, - url: matches[1], - jx: 0, - danmaku: 'http://103.45.162.207:25252/hbdm.php?key=7894561232&id=' + '&jm=' + name + '&js=' + juji + '&key=741852963' - }; - } catch { - return { - parse: 0, - url: '解析失败', - jx: 0 - }; - } -} - -var rule = { - title: '米兔[资]', - host: '', - detailUrl: 'fyid', - searchUrl: '**', - url: 'fyclass', - searchable: 2, - quickSearch: 1, - filterable: 0, - class_name: '电影&电视剧&综艺&动漫', - class_url: '1&2&3&4', - play_parse: true, - lazy: $js.toString(() => { - const parts = input.split('~'); - input = jxx(parts[0], parts[1], parts[2], parts[3]); - }), - 推荐: $js.toString(() => { - let data = vod1(0, 0); - let bata = JSON.parse(data).recommend_list; - bata.forEach(it => { - d.push({ - url: it.vod_id, - title: it.vod_name, - img: it.vod_pic, - desc: it.vod_remarks - }); - }); - setResult(d); - }), - 一级: $js.toString(() => { - let data = vod1(input, MY_PAGE); - let bata = JSON.parse(data).recommend_list; - bata.forEach(it => { - d.push({ - url: it.vod_id, - title: it.vod_name, - img: it.vod_pic, - desc: it.vod_remarks - }); - }); - setResult(d); - }), - 二级: $js.toString(() => { - console.log("调试信息2" + input); - let data = vodids(input); - //console.log(data); - VOD = data; - }), - 搜索: $js.toString(() => { - let data = ssvod(input); - let bata = JSON.parse(data).search_list; - bata.forEach(it => { - d.push({ - url: it.vod_id, - title: it.vod_name, - img: it.vod_pic, - desc: it.vod_remarks - }); - }); - // console.log(data); - setResult(d); - }), -} \ No newline at end of file diff --git a/JS/素白白.js b/JS/素白白.js deleted file mode 100644 index 56b25c7..0000000 --- a/JS/素白白.js +++ /dev/null @@ -1,743 +0,0 @@ -// 地址发布页 https://subaibai.vip/ -// 搜索数字验证 -var rule = { - title: '素白白', - // host:'https://www.subaibaiys.com', - host: 'https://subaibai.vip', - hostJs: 'print(HOST);let html=request(HOST,{headers:{"User-Agent":PC_UA}});let src = jsp.pdfh(html,".go:eq(0)&&a&&href");print(src);HOST=src', //网页域名根动态抓取js代码。通过HOST=赋值 - // url:'/fyclass/page/fypage', - url: '/fyclassfyfilter', - filterable: 1, //是否启用分类筛选, - filter_url: '{{fl.area}}{{fl.year}}{{fl.class}}{{fl.cateId}}/page/fypage', - filter: { - "movie_bt": [{ - "key": "cateId", - "name": "分类", - "value": [{ - "n": "全部", - "v": "" - }, { - "v": "/movie_bt_series/dongmanju", - "n": "动漫剧" - }, { - "v": "/movie_bt_series/dongmandy", - "n": "动漫电影" - }, { - "v": "/movie_bt_series/yindudy", - "n": "印度电影" - }, { - "v": "/movie_bt_series/guochanju", - "n": "国产剧" - }, { - "v": "/movie_bt_series/guochandy", - "n": "国产电影" - }, { - "v": "/movie_bt_series/riju", - "n": "日剧" - }, { - "v": "/movie_bt_series/rihandy", - "n": "日韩电影" - }, { - "v": "/movie_bt_series/oumeiju", - "n": "欧美剧" - }, { - "v": "/movie_bt_series/oumeidy", - "n": "欧美电影" - }, { - "v": "/movie_bt_series/taiju", - "n": "泰剧" - }, { - "v": "/movie_bt_series/thaidy", - "n": "泰国电影" - }, { - "v": "/movie_bt_series/gangju", - "n": "港台剧" - }, { - "v": "/movie_bt_series/gangtaidy", - "n": "港台电影" - }, { - "v": "/movie_bt_series/documentary", - "n": "纪录片" - }, { - "v": "/movie_bt_series/zongyi", - "n": "综艺" - }, { - "v": "/movie_bt_series/hanju", - "n": "韩剧" - }, { - "v": "/movie_bt_series/xianggangdy", - "n": "香港经典电影" - }] - }, { - "key": "class", - "name": "类型", - "value": [{ - "n": "全部", - "v": "" - }, { - "v": "/movie_bt_tags/pop-popular", - "n": "POP流行" - }, { - "v": "/movie_bt_tags/biography", - "n": "传记" - }, { - "v": "/movie_bt_tags/child", - "n": "儿童" - }, { - "v": "/movie_bt_tags/adventure", - "n": "冒险" - }, { - "v": "/movie_bt_tags/plot", - "n": "剧情" - }, { - "v": "/movie_bt_tags/action", - "n": "动作" - }, { - "v": "/movie_bt_tags/anime", - "n": "动漫" - }, { - "v": "/movie_bt_tags/animation", - "n": "动画" - }, { - "v": "/movie_bt_tags/history", - "n": "历史" - }, { - "v": "/movie_bt_tags/costume", - "n": "古装" - }, { - "v": "/movie_bt_tags/antiquity", - "n": "古风" - }, { - "v": "/movie_bt_tags/homosexual", - "n": "同性" - }, { - "v": "/movie_bt_tags/comedy", - "n": "喜剧" - }, { - "v": "/movie_bt_tags/fantasy", - "n": "奇幻" - }, { - "v": "/movie_bt_tags/family", - "n": "家庭" - }, { - "v": "/movie_bt_tags/terror", - "n": "恐怖" - }, { - "v": "/movie_bt_tags/suspense", - "n": "悬疑" - }, { - "v": "/movie_bt_tags/erotic", - "n": "情色" - }, { - "v": "/movie_bt_tags/thriller", - "n": "惊悚" - }, { - "v": "/movie_bt_tags/drama", - "n": "戏曲" - }, { - "v": "/movie_bt_tags/war", - "n": "战争" - }, { - "v": "/movie_bt_tags/latin", - "n": "拉丁" - }, { - "v": "/movie_bt_tags/funny", - "n": "搞笑" - }, { - "v": "/movie_bt_tags/campus", - "n": "校园" - }, { - "v": "/movie_bt_tags/song-and-dance", - "n": "歌舞" - }, { - "v": "/movie_bt_tags/martial-arts", - "n": "武侠" - }, { - "v": "/movie_bt_tags/disaster", - "n": "灾难" - }, { - "v": "/movie_bt_tags/love", - "n": "爱情" - }, { - "v": "/movie_bt_tags/crime", - "n": "犯罪" - }, { - "v": "/movie_bt_tags/fancy", - "n": "玄幻" - }, { - "v": "/movie_bt_tags/reality-show", - "n": "真人秀" - }, { - "v": "/movie_bt_tags/short-film", - "n": "短片" - }, { - "v": "/movie_bt_tags/kehuan", - "n": "科幻" - }, { - "v": "/movie_bt_tags/documentary", - "n": "纪录片" - }, { - "v": "/movie_bt_tags/talkshow", - "n": "脱口秀" - }, { - "v": "/movie_bt_tags/stageart", - "n": "舞台艺术" - }, { - "v": "/movie_bt_tags/west", - "n": "西部" - }, { - "v": "/movie_bt_tags/sport", - "n": "运动" - }, { - "v": "/movie_bt_tags/youth", - "n": "青春" - }, { - "v": "/movie_bt_tags/music", - "n": "音乐" - }, { - "v": "/movie_bt_tags/ghost", - "n": "鬼怪" - }, { - "v": "/movie_bt_tags/black-film", - "n": "黑色电影" - }] - }, { - "key": "area", - "name": "地区", - "value": [{ - "n": "全部", - "v": "" - }, { - "v": "/movie_bt_cat/bhutan", - "n": "不丹" - }, { - "v": "/movie_bt_cat/china", - "n": "中国" - }, { - "v": "/movie_bt_cat/china-taiwan", - "n": "中国台湾" - }, { - "v": "/movie_bt_cat/china-mainland", - "n": "中国大陆" - }, { - "v": "/movie_bt_cat/china-hongkong", - "n": "中国香港" - }, { - "v": "/movie_bt_cat/denmark", - "n": "丹麦" - }, { - "v": "/movie_bt_cat/ukraine", - "n": "乌克兰" - }, { - "v": "/movie_bt_cat/uruguay", - "n": "乌拉圭" - }, { - "v": "/movie_bt_cat/israel", - "n": "以色列" - }, { - "v": "/movie_bt_cat/iraq", - "n": "伊拉克" - }, { - "v": "/movie_bt_cat/iran", - "n": "伊朗" - }, { - "v": "/movie_bt_cat/russia", - "n": "俄罗斯" - }, { - "v": "/movie_bt_cat/bulgaria", - "n": "保加利亚" - }, { - "v": "/movie_bt_cat/croatia", - "n": "克罗地亚" - }, { - "v": "/movie_bt_cat/iceland", - "n": "冰岛" - }, { - "v": "/movie_bt_cat/canada", - "n": "加拿大" - }, { - "v": "/movie_bt_cat/hungary", - "n": "匈牙利" - }, { - "v": "/movie_bt_cat/south-africa", - "n": "南非" - }, { - "v": "/movie_bt_cat/botswana", - "n": "博茨瓦纳" - }, { - "v": "/movie_bt_cat/qatar", - "n": "卡塔尔" - }, { - "v": "/movie_bt_cat/luxembourg", - "n": "卢森堡" - }, { - "v": "/movie_bt_cat/india", - "n": "印度" - }, { - "v": "/movie_bt_cat/indonesia", - "n": "印度尼西亚" - }, { - "v": "/movie_bt_cat/kazakhstan", - "n": "哈萨克斯坦" - }, { - "v": "/movie_bt_cat/colombia", - "n": "哥伦比亚" - }, { - "v": "/movie_bt_cat/turkey", - "n": "土耳其" - }, { - "v": "/movie_bt_cat/serbia", - "n": "塞尔维亚" - }, { - "v": "/movie_bt_cat/cyprus", - "n": "塞浦路斯" - }, { - "v": "/movie_bt_cat/mexico", - "n": "墨西哥" - }, { - "v": "/movie_bt_cat/dominica", - "n": "多米尼加" - }, { - "v": "/movie_bt_cat/austria", - "n": "奥地利" - }, { - "v": "/movie_bt_cat/venezuela", - "n": "委内瑞拉" - }, { - "v": "/movie_bt_cat/nigeria", - "n": "尼日利亚" - }, { - "v": "/movie_bt_cat/巴基斯坦", - "n": "巴基斯坦" - }, { - "v": "/movie_bt_cat/paraguay", - "n": "巴拉圭" - }, { - "v": "/movie_bt_cat/brazil", - "n": "巴西" - }, { - "v": "/movie_bt_cat/greece", - "n": "希腊" - }, { - "v": "/movie_bt_cat/germany", - "n": "德国" - }, { - "v": "/movie_bt_cat/italy", - "n": "意大利" - }, { - "v": "/movie_bt_cat/latvia", - "n": "拉脱维亚" - }, { - "v": "/movie_bt_cat/norway", - "n": "挪威" - }, { - "v": "/movie_bt_cat/chech", - "n": "捷克" - }, { - "v": "/movie_bt_cat/摩洛哥", - "n": "摩洛哥" - }, { - "v": "/movie_bt_cat/斯洛伐克", - "n": "斯洛伐克" - }, { - "v": "/movie_bt_cat/slovenia", - "n": "斯洛文尼亚" - }, { - "v": "/movie_bt_cat/singapore", - "n": "新加坡" - }, { - "v": "/movie_bt_cat/zealand", - "n": "新西兰" - }, { - "v": "/movie_bt_cat/japan", - "n": "日本" - }, { - "v": "/movie_bt_cat/chile", - "n": "智利" - }, { - "v": "/movie_bt_cat/north-korea", - "n": "朝鲜" - }, { - "v": "/movie_bt_cat/cambodia", - "n": "柬埔寨" - }, { - "v": "/movie_bt_cat/georgia", - "n": "格鲁吉亚" - }, { - "v": "/movie_bt_cat/belgium", - "n": "比利时" - }, { - "v": "/movie_bt_cat/saudi-arabia", - "n": "沙特阿拉伯" - }, { - "v": "/movie_bt_cat/france", - "n": "法国" - }, { - "v": "/movie_bt_cat/poland", - "n": "波兰" - }, { - "v": "/movie_bt_cat/puertorco", - "n": "波多黎各" - }, { - "v": "/movie_bt_cat/bohei", - "n": "波黑" - }, { - "v": "/movie_bt_cat/thailand", - "n": "泰国" - }, { - "v": "/movie_bt_cat/australia", - "n": "澳大利亚" - }, { - "v": "/movie_bt_cat/ireland", - "n": "爱尔兰" - }, { - "v": "/movie_bt_cat/estonia", - "n": "爱沙尼亚" - }, { - "v": "/movie_bt_cat/sweden", - "n": "瑞典" - }, { - "v": "/movie_bt_cat/switzerland", - "n": "瑞士" - }, { - "v": "/movie_bt_cat/belarus", - "n": "白俄罗斯" - }, { - "v": "/movie_bt_cat/peru", - "n": "秘鲁" - }, { - "v": "/movie_bt_cat/tunisia", - "n": "突尼斯" - }, { - "v": "/movie_bt_cat/lithuania", - "n": "立陶宛" - }, { - "v": "/movie_bt_cat/romania", - "n": "罗马尼亚" - }, { - "v": "/movie_bt_cat/america", - "n": "美国" - }, { - "v": "/movie_bt_cat/finland", - "n": "芬兰" - }, { - "v": "/movie_bt_cat/sovietunion", - "n": "苏联" - }, { - "v": "/movie_bt_cat/england", - "n": "英国" - }, { - "v": "/movie_bt_cat/netherlands", - "n": "荷兰" - }, { - "v": "/movie_bt_cat/philippines", - "n": "菲律宾" - }, { - "v": "/movie_bt_cat/葡萄牙", - "n": "葡萄牙" - }, { - "v": "/movie_bt_cat/west-germany", - "n": "西德" - }, { - "v": "/movie_bt_cat/spain", - "n": "西班牙" - }, { - "v": "/movie_bt_cat/vietnam", - "n": "越南" - }, { - "v": "/movie_bt_cat/argentina", - "n": "阿根廷" - }, { - "v": "/movie_bt_cat/korea", - "n": "韩国" - }, { - "v": "/movie_bt_cat/malaysia", - "n": "马来西亚" - }, { - "v": "/movie_bt_cat/马耳他", - "n": "马耳他" - }] - }, { - "key": "year", - "name": "年份", - "value": [{ - "n": "全部", - "v": "" - }, { - "v": "/year/2024", - "n": "2024" - }, { - "v": "/year/2023", - "n": "2023" - }, { - "v": "/year/2022", - "n": "2022" - }, { - "v": "/year/2021", - "n": "2021" - }, { - "v": "/year/2020", - "n": "2020" - }, { - "v": "/year/2019", - "n": "2019" - }, { - "v": "/year/2018", - "n": "2018" - }, { - "v": "/year/2017", - "n": "2017" - }, { - "v": "/year/2016", - "n": "2016" - }, { - "v": "/year/2015", - "n": "2015" - }, { - "v": "/year/2014", - "n": "2014" - }, { - "v": "/year/2013", - "n": "2013" - }, { - "v": "/year/2012", - "n": "2012" - }, { - "v": "/year/2011", - "n": "2011" - }, { - "v": "/year/2010", - "n": "2010" - }, { - "v": "/year/2009", - "n": "2009" - }, { - "v": "/year/2008", - "n": "2008" - }, { - "v": "/year/2007", - "n": "2007" - }, { - "v": "/year/2006", - "n": "2006" - }, { - "v": "/year/2005", - "n": "2005" - }, { - "v": "/year/2004", - "n": "2004" - }, { - "v": "/year/2003", - "n": "2003" - }, { - "v": "/year/2002", - "n": "2002" - }, { - "v": "/year/2001", - "n": "2001" - }, { - "v": "/year/2000", - "n": "2000" - }, { - "v": "/year/1999", - "n": "1999" - }, { - "v": "/year/1998", - "n": "1998" - }, { - "v": "/year/1997", - "n": "1997" - }, { - "v": "/year/1996", - "n": "1996" - }, { - "v": "/year/1995", - "n": "1995" - }, { - "v": "/year/1994", - "n": "1994" - }, { - "v": "/year/1993", - "n": "1993" - }, { - "v": "/year/1992", - "n": "1992" - }, { - "v": "/year/1991", - "n": "1991" - }, { - "v": "/year/1990", - "n": "1990" - }, { - "v": "/year/1989", - "n": "1989" - }, { - "v": "/year/1988", - "n": "1988" - }, { - "v": "/year/1987", - "n": "1987" - }, { - "v": "/year/1986", - "n": "1986" - }, { - "v": "/year/1985", - "n": "1985" - }, { - "v": "/year/1984", - "n": "1984" - }, { - "v": "/year/1983", - "n": "1983" - }, { - "v": "/year/1982", - "n": "1982" - }, { - "v": "/year/1981", - "n": "1981" - }, { - "v": "/year/1980", - "n": "1980" - }, { - "v": "/year/1979", - "n": "1979" - }, { - "v": "/year/1978", - "n": "1978" - }, { - "v": "/year/1977", - "n": "1977" - }, { - "v": "/year/1976", - "n": "1976" - }, { - "v": "/year/1975", - "n": "1975" - }, { - "v": "/year/1974", - "n": "1974" - }, { - "v": "/year/1973", - "n": "1973" - }, { - "v": "/year/1972", - "n": "1972" - }, { - "v": "/year/1971", - "n": "1971" - }, { - "v": "/year/1970", - "n": "1970" - }, { - "v": "/year/1969", - "n": "1969" - }, { - "v": "/year/1968", - "n": "1968" - }, { - "v": "/year/1967", - "n": "1967" - }, { - "v": "/year/1966", - "n": "1966" - }, { - "v": "/year/1965", - "n": "1965" - }, { - "v": "/year/1964", - "n": "1964" - }, { - "v": "/year/1963", - "n": "1963" - }, { - "v": "/year/1962", - "n": "1962" - }, { - "v": "/year/1960", - "n": "1960" - }, { - "v": "/year/1959", - "n": "1959" - }, { - "v": "/year/1954", - "n": "1954" - }, { - "v": "/year/1952", - "n": "1952" - }, { - "v": "/year/1950", - "n": "1950" - }, { - "v": "/year/1949", - "n": "1949" - }, { - "v": "/year/1948", - "n": "1948" - }, { - "v": "/year/1940", - "n": "1940" - }, { - "v": "/year/1939", - "n": "1939" - }, { - "v": "/year/1925", - "n": "1925" - }] - }] - }, - // searchUrl:'/search?q=**', - searchUrl: '/search?q=**', - searchable: 2, //是否启用全局搜索, - quickSearch: 0, //是否启用快速搜索, - headers: { - 'User-Agent': 'UC_UA', - }, - class_parse: '.navlist&&li;a&&Text;a&&href;.*/([^/]+)', - play_parse: true, - // lazy:'', - lazy: `js: - pdfh = jsp.pdfh; - var html = request(input); - var ohtml = pdfh(html, '.videoplay&&Html'); - var url = pdfh(ohtml, "body&&iframe&&src"); - if (/Cloud/.test(url)) { - var ifrwy = request(url); - let code = ifrwy.match(/var url = '(.*?)'/)[1].split('').reverse().join(''); - let temp = ''; - for (let i = 0x0; i < code.length; i = i + 0x2) { - temp += String.fromCharCode(parseInt(code[i] + code[i + 0x1], 0x10)) - } - input = { - jx: 0, - url: temp.substring(0x0, (temp.length - 0x7) / 0x2) + temp.substring((temp.length - 0x7) / 0x2 + 0x7), - parse: 0 - } - } else if (/decrypted/.test(ohtml)) { - var phtml = pdfh(ohtml, "body&&script:not([src])&&Html"); - eval(getCryptoJS()); - var scrpt = phtml.match(/var.*?\\)\\);/g)[0]; - var data = []; - eval(scrpt.replace(/md5/g, 'CryptoJS').replace('eval', 'data = ')); - input = { - jx: 0, - url: data.match(/url:.*?[\\'\\"](.*?)[\\'\\"]/)[1], - parse: 0 - } - } else { - input - } - `, - limit: 6, - 推荐: '.leibox&&li;*;*;*;*', - // double:true, // 推荐内容是否双层定位 - 一级: '.mrb&&li;img&&alt;img&&data-original;.jidi&&Text;a&&href', - 二级: { - "title": "h1&&Text;.moviedteail_list&&li:eq(0)&&Text", - "img": ".dyimg&&img&&src", - "desc": ".moviedteail_list&&li:eq(-1)&&Text;;;.moviedteail_list&&li:eq(7)&&Text;.moviedteail_list&&li:eq(5)&&Text", - "content": ".yp_context&&p&&Text", - "tabs": ".mi_paly_box .ypxingq_t--span", - "lists": ".paly_list_btn:eq(#id) a" - }, - 搜索: '.search_list&&li;img&&alt;img&&data-original;.nostag&&Text;a&&href', -} \ No newline at end of file diff --git a/JS/腾讯弹幕.js b/JS/腾讯视频.js similarity index 98% rename from JS/腾讯弹幕.js rename to JS/腾讯视频.js index a3ebd8a..753d991 100644 --- a/JS/腾讯弹幕.js +++ b/JS/腾讯视频.js @@ -670,14 +670,14 @@ var rule = { parse: 0, url: bata.url, jx: 0, - danmaku: "http://103.45.162.207:25252/hbdm.php?key=7894561232&id=" + input.split("?")[0] + danmaku: "https://danmu.zxz.ee/?type=xml&id=" + input.split("?")[0] }; } else { input = { parse: 0, url: input.split("?")[0], jx: 1, - danmaku: "http://103.45.162.207:25252/hbdm.php?key=7894561232&id=" + input.split("?")[0] + danmaku: "https://danmu.zxz.ee/?type=xml&id=" + input.split("?")[0] }; } } catch { @@ -685,7 +685,7 @@ var rule = { parse: 0, url: input.split("?")[0], jx: 1, - danmaku: "http://103.45.162.207:25252/hbdm.php?key=7894561232&id=" + input.split("?")[0] + danmaku: "https://danmu.zxz.ee/?type=xml&id=" + input.split("?")[0] }; } }), diff --git a/JS/芒果弹幕.js b/JS/芒果视频.js similarity index 98% rename from JS/芒果弹幕.js rename to JS/芒果视频.js index 3f517be..d7bd5e7 100644 --- a/JS/芒果弹幕.js +++ b/JS/芒果视频.js @@ -679,14 +679,14 @@ var rule = { parse: 0, url: bata.url, jx: 0, - danmaku: "http://103.45.162.207:25252/hbdm.php?key=7894561232&id=" + input.split("?")[0] + danmaku: "https://danmu.zxz.ee/?type=xml&id=" + input.split("?")[0] }; } else { input = { parse: 0, url: input.split("?")[0], jx: 1, - danmaku: "http://103.45.162.207:25252/hbdm.php?key=7894561232&id=" + input.split("?")[0] + danmaku: "https://danmu.zxz.ee/?type=xml&id=" + input.split("?")[0] }; } } catch { @@ -694,7 +694,7 @@ var rule = { parse: 0, url: input.split("?")[0], jx: 1, - danmaku: "http://103.45.162.207:25252/hbdm.php?key=7894561232&id=" + input.split("?")[0] + danmaku: "https://danmu.zxz.ee/?type=xml&id=" + input.split("?")[0] }; } }), diff --git a/JS/追剧弹幕.js b/JS/追剧影视.js similarity index 100% rename from JS/追剧弹幕.js rename to JS/追剧影视.js diff --git a/JS/追剧迷.js b/JS/追剧迷.js deleted file mode 100644 index 3031e38..0000000 --- a/JS/追剧迷.js +++ /dev/null @@ -1,37 +0,0 @@ -var rule = { - title: '追剧迷', - 模板: 'vfed', - host: 'https://www.zhuijumi.cc', - // url:'/videotype/fyclass-fypage.html', - url: '/mp4type/fyclass-fypage.html', - searchUrl: '/mp4search/-.html?wd=**', - class_parse: '.fed-part-tips li;a&&Text;a&&href;.*/(.*?).html', - cate_exclude: '更多|申请', - lazy: `js: - var html = JSON.parse(request(input).match(/r player_.*?=(.*?) len(pdata): + batch_size = len(pdata) + total_batches = ((index + batch_size - 1) // batch_size) - 1 + ssj = json.loads(sdata['data']['session']) + with ThreadPoolExecutor(max_workers=total_batches) as executor: + futures = [] + for batch in range(total_batches): + start = batch_size + 1 + (batch * batch_size) + end = start + batch_size - 1 + next_session = ssj.copy() + next_session.update({ + "itemStartStage": start, + "itemEndStage": min(end, index) + }) + current_params = params.copy() + current_params['nextSession'] = json.dumps(next_session) + futures.append((start, executor.submit(self.getvinfo, current_params))) + futures.sort(key=lambda x: x[0]) + + for _, future in futures: + try: + result = future.result() + pdata.extend(result['nodes']) + except Exception as e: + print(f"Error fetching data: {str(e)}") + vod['vod_play_url'] = '#'.join([f"{i['data'].get('title')}${i['data']['action'].get('value')}" for i in pdata]) + return {'list': [vod]} + except Exception as e: + print(e) + return {'list': [{'vod_play_from': '哎呀翻车啦', 'vod_play_url': f'呜呜呜${self.host}'}]} + + def searchContent(self, key, quick, pg="1"): + data=self.session.get(f'{self.shost}/api/search?pg={pg}&keyword={key}').json() + vlist = [] + for i in data['pageComponentList']: + if i.get('commonData') and (i['commonData'].get('showId') or i['commonData'].get('realShowId')): + i=i['commonData'] + vlist.append({ + 'vod_id': i.get('showId') or i.get('realShowId'), + 'vod_name': i['titleDTO'].get('displayName'), + 'vod_pic': i['posterDTO'].get('vThumbUrl'), + 'vod_year': i.get('feature'), + 'vod_remarks': i.get('updateNotice') + }) + return {'list': vlist, 'page': pg} + + def playerContent(self, flag, id, vipFlags): + return {'jx':1,'parse': 1, 'url': f"{self.ihost}/video?vid={id}", 'header': ''} + + def localProxy(self, param): + pass + + def cf(self,params,b=False): + response = self.session.get(f'{self.host}/category/data?params={quote(json.dumps(params))}&optionRefresh=1&pageNo=1').json() + data=response['data']['filterData'] + session=quote(json.dumps(data['session'])) + if b: + return session,self.get_filter_data(data['filter']['filterData'][1:]) + return session + + def process_key(self, key): + if '_' not in key: + return key + parts = key.split('_') + result = parts[0] + for part in parts[1:]: + if part: + result += part[0].upper() + part[1:] + return result + + def get_filter_data(self, data): + result = [] + try: + for item in data: + if not item.get('subFilter'): + continue + first_sub = item['subFilter'][0] + if not first_sub.get('filterType'): + continue + filter_item = { + 'key': self.process_key(first_sub['filterType']), + 'name': first_sub['title'], + 'value': [] + } + for sub in item['subFilter']: + if 'value' in sub: + filter_item['value'].append({ + 'n': sub['title'], + 'v': sub['value'] + }) + if filter_item['value']: + result.append(filter_item) + + except Exception as e: + print(f"处理筛选数据时出错: {str(e)}") + + return result + + def get_ctoken(self): + data=self.session.get(f'{self.h5host}/h5/mtop.ykrec.recommendservice.recommend/1.0/?jsv=2.6.1&appKey=24679788') + + def md5(self,t,text): + h = MD5.new() + token=self.session.cookies.get('_m_h5_tk').split('_')[0] + data=f"{token}&{t}&24679788&{text}" + h.update(data.encode('utf-8')) + return h.hexdigest() + + def getdata(self, url, params, recursion_count=0, max_recursion=3): + data = json.dumps(params) + t = int(time.time() * 1000) + jsdata = { + 'appKey': '24679788', + 't': t, + 'sign': self.md5(t, data), + 'data': data + } + response = self.session.get(url, params=jsdata) + if '令牌过期' in response.text: + if recursion_count >= max_recursion: + raise Exception("达到最大递归次数,无法继续请求") + self.get_ctoken() + return self.getdata(url, params, recursion_count + 1, max_recursion) + else: + return response.json() + + def getvinfo(self,params): + body = { + "ms_codes": "2019030100", + "params": json.dumps(params), + "system_info": "{\"os\":\"iku\",\"device\":\"iku\",\"ver\":\"9.2.9\",\"appPackageKey\":\"com.youku.iku\",\"appPackageId\":\"pcweb\"}" + } + data = self.getdata(f'{self.h5host}/h5/mtop.youku.columbus.gateway.new.execute/1.0/', body) + okey = list(data['data'].keys())[0] + i = data['data'][okey]['data'] + return i + + def getinfo(self,params): + i = self.getvinfo(params) + jdata=i['nodes'][0]['nodes'][3] + info=i['data']['extra']['episodeTotal'] + if i['data']['extra']['showCategory'] in ['电影','游戏']: + jdata = i['nodes'][0]['nodes'][4] + return jdata,info + diff --git a/PY/光速影视.py b/PY/光速影视.py index 4a58f39..33b1204 100644 --- a/PY/光速影视.py +++ b/PY/光速影视.py @@ -111,21 +111,21 @@ class Spider(Spider): def playerContent(self, flag, id, vipFlags): ids = json.loads(self.d64(id)) - h={"User-Agent": (ids['user_agent'] or "okhttp/3.14.9")} - url = ids['url'] - p=1 + h = {"User-Agent": (ids['user_agent'] or "okhttp/3.14.9")} try: - if re.search(r'\?url=', ids['parse_api_url']): - data=self.fetch(ids['parse_api_url'], headers=h, timeout=10).json() - url=data.get('url') or data['data'].get('url') - elif not re.search(r'\.m3u8|\.mp4', ids.get('url')): - body = f"parse_api={ids.get('parse') or ids['parse_api_url'].replace(ids['url'], '')}&url={quote(self.aes('encrypt', ids['url']))}&token={ids.get('token')}" + if re.search(r'url=', ids['parse_api_url']): + data = self.fetch(ids['parse_api_url'], headers=h, timeout=10).json() + url = data.get('url') or data['data'].get('url') + else: + body = f"parse_api={ids.get('parse') or ids['parse_api_url'].replace(ids['url'], '')}&url={quote(self.aes(ids['url'], True))}&token={ids.get('token')}" b = self.getdata("/api.php/getappapi.index/vodParse", body)['json'] url = json.loads(b)['url'] - p=0 + if 'error' in url: raise ValueError(f"解析失败: {url}") + p = 0 except Exception as e: - print('错误信息:',e) - pass + print('错误信息:', e) + url, p = ids['url'], 1 + if re.search(r'\.jpg|\.png|\.jpeg', url): url = self.Mproxy(url) result = {} diff --git a/PY/哔哩视频.py b/PY/哔哩视频.py new file mode 100644 index 0000000..2b8a7cf --- /dev/null +++ b/PY/哔哩视频.py @@ -0,0 +1,468 @@ +#coding=utf-8 +#!/usr/bin/python +import sys +import json +import time +from datetime import datetime +from difflib import SequenceMatcher +from urllib.parse import quote, unquote +sys.path.append('..') +from base.spider import Spider + +class Spider(Spider): # 元类 默认的元类 type + def getName(self): + return "B站番剧" + + def init(self, extend): + try: + self.extendDict = json.loads(extend) + except: + self.extendDict = {} + + def destroy(self): + pass + + def isVideoFormat(self, url): + pass + + def manualVideoCheck(self): + pass + + def homeContent(self, filter): + result = {} + cateManual = { + "番剧": "1", + "国创": "4", + "电影": "2", + "综艺": "7", + "电视剧": "5", + } + classes = [] + for k in cateManual: + classes.append({ + 'type_name': k, + 'type_id': cateManual[k] + }) + result['class'] = classes + if filter: + result['filters'] = self.config['filter'] + currentYear = datetime.now().year + for resultfilter in result['filters']: + for rf in result['filters'][resultfilter]: + if rf['key'] == 'year': + for rfv in rf['value']: + if rfv['n'].isdigit(): + if int(rfv['n']) < currentYear: + pos = rf['value'].index(rfv) + for year in range(currentYear, int(rfv['n']), -1): + rf['value'].insert(pos, {'v': f'[{str(year)},{str(year+1)})', 'n': str(year)}) + pos += 1 + break + else: + break + elif rf['key'] == 'release_date': + for rfv in rf['value']: + if rfv['n'].isdigit(): + if int(rfv['n']) < currentYear: + pos = rf['value'].index(rfv) + for year in range(currentYear, int(rfv['n']), -1): + rf['value'].insert(pos, {'v': f'[{str(year)}-01-01 00:00:00,{str(year+1)}-01-01 00:00:00)', 'n': str(year)}) + pos += 1 + break + else: + break + return result + + def homeVideoContent(self): + return self.categoryContent('1', '1', False, {}) + + def categoryContent(self, cid, page, filter, ext): + page = int(page) + result = {} + videos = [] + cookie, _, _ = self.getCookie('{}') + url = 'https://api.bilibili.com/pgc/season/index/result?order=2&sort=0&pagesize=20&type=1&st={}&season_type={}&page={}'.format(cid, cid, page) + for key in ext: + url += f'&{key}={quote(ext[key])}' + r = self.fetch(url, headers=self.header, cookies=cookie, timeout=5) + data = json.loads(self.cleanText(r.text)) + vodList = data['data']['list'] + for vod in vodList: + aid = str(vod['season_id']).strip() + title = self.removeHtmlTags(self.cleanText(vod['title'])) + img = vod['cover'].strip() + remark = vod['index_show'].strip() + videos.append({ + "vod_id": aid, + "vod_name": title, + "vod_pic": img, + "vod_remarks": remark + }) + lenvideos = len(videos) + if data['data']['has_next'] == 1: + pagecount = page + 1 + else: + pagecount = page + result['list'] = videos + result['page'] = page + result['pagecount'] = pagecount + result['limit'] = lenvideos + result['total'] = lenvideos + return result + + def detailContent(self, did): + did = did[0] + url = "http://api.bilibili.com/pgc/view/web/season?season_id={0}".format(did) + r = self.fetch(url, headers=self.header, timeout=10) + data = json.loads(self.cleanText(r.text)) + vod = { + "vod_id": did, + "vod_name": self.removeHtmlTags(data['result']['title']), + "vod_pic": data['result']['cover'], + "type_name": data['result']['share_sub_title'], + "vod_actor": data['result']['actors'].replace('\n', ','), + "vod_content": self.removeHtmlTags(data['result']['evaluate']) + } + videoList = data['result']['episodes'] + playUrl = '' + for video in videoList: + eid = video['id'] + cid = video['cid'] + name = self.removeHtmlTags(video['share_copy']).replace("#", "-").replace('$', '*') + remark = time.strftime('%H:%M:%S', time.gmtime(video['duration']/1000)) + if remark.startswith('00:'): + remark = remark[3:] + playUrl = playUrl + '[{}]/{}${}_{}#'.format(remark, name, eid, cid) + vod['vod_play_from'] = 'B站番剧' + vod['vod_play_url'] = playUrl.strip('#') + result = { + 'list': [ + vod + ] + } + return result + + def searchContent(self, key, quick): + return self.searchContentPage(key, quick, '1') + + def searchContentPage(self, key, quick, page): + videos = [] + cookie = '' + if 'cookie' in self.extendDict: + cookie = self.extendDict['cookie'] + if 'json' in self.extendDict: + r = self.fetch(self.extendDict['json'], timeout=10) + if 'cookie' in r.json(): + cookie = r.json()['cookie'] + if cookie == '': + cookie = '{}' + elif type(cookie) == str and cookie.startswith('http'): + cookie = self.fetch(cookie, timeout=10).text.strip() + try: + if type(cookie) == dict: + cookie = json.dumps(cookie, ensure_ascii=False) + except: + pass + cookie, _, _ = self.getCookie(cookie) + url = f'https://api.bilibili.com/x/web-interface/search/type?search_type=media_bangumi&keyword={key}&page={page}' + r = self.fetch(url, headers=self.header, cookies=cookie, timeout=5) + data = json.loads(self.cleanText(r.text)) + if 'result' not in data['data']: + return {'list': videos}, 1 + vodList = data['data']['result'] + for vod in vodList: + sid = str(vod['season_id']).strip() + title = self.removeHtmlTags(self.cleanText(vod['title'])) + if SequenceMatcher(None, title, key).ratio() < 0.6 and key not in title: + continue + img = vod['eps'][0]['cover'].strip() + remark = self.removeHtmlTags(vod['index_show']).strip() + videos.append({ + "vod_id": sid, + "vod_name": title, + "vod_pic": img, + "vod_remarks": remark + }) + result = { + 'list': videos + } + return result + + def playerContent(self, flag, pid, vipFlags): + result = {} + pidList = pid.split("_") + aid = pidList[0] + cid = pidList[1] + url = 'https://api.bilibili.com/pgc/player/web/playurl?ep_id={0}&cid={1}&qn=120&fnval=4048&fnver=0&fourk=1'.format(aid, cid) + cookie = '' + extendDict = self.extendDict + if 'cookie' in extendDict: + cookie = extendDict['cookie'] + if 'json' in extendDict: + r = self.fetch(extendDict['json'], timeout=10) + if 'cookie' in r.json(): + cookie = r.json()['cookie'] + if cookie == '': + cookie = '{}' + elif type(cookie) == str and cookie.startswith('http'): + cookie = self.fetch(cookie, timeout=10).text.strip() + try: + if type(cookie) == dict: + cookie = json.dumps(cookie, ensure_ascii=False) + except: + pass + cookiesDict, _, _ = self.getCookie(cookie) + cookies = quote(json.dumps(cookiesDict)) + if 'thread' in extendDict: + thread = str(extendDict['thread']) + else: + thread = '0' + result["parse"] = '0' + result["playUrl"] = '' + result["url"] = f'http://127.0.0.1:9978/proxy?do=py&type=mpd&cookies={cookies}&url={quote(url)}&aid={aid}&cid={cid}&thread={thread}' + result["header"] = self.header + result['danmaku'] = 'https://api.bilibili.com/x/v1/dm/list.so?oid={}'.format(cid) + result["format"] = 'application/dash+xml' + return result + + def localProxy(self, params): + if params['type'] == "mpd": + return self.proxyMpd(params) + if params['type'] == "media": + return self.proxyMedia(params) + return None + + def proxyMpd(self, params): + content, durlinfos, mediaType = self.getDash(params) + if mediaType == 'mpd': + return [200, "application/dash+xml", content] + else: + url = content + durlinfo = durlinfos['durl'][0]['backup_url'] + try: + r = self.fetch(url, headers=self.header, stream=True, timeout=1) + statusCode = r.status_code + try: + r.close() + except: + pass + except: + try: + r.close() + except: + pass + statusCode = 404 + for url in durlinfo: + try: + r = self.fetch(url, headers=self.header, stream=True, timeout=1) + statusCode = r.status_code + except: + statusCode = 404 + if statusCode == 200: + break + try: + r.close() + except: + pass + if statusCode != 200 and self.retry == 0: + self.retry += 1 + self.proxyMedia(params, True) + header = self.header.copy() + if 'range' in params: + header['Range'] = params['range'] + if '127.0.0.1:7777' in url: + header['Location'] = url + return [302, "video/MP2T", None, header] + return [206, "application/octet-stream", self.fetch(content, headers=header, stream=True).content] + + def proxyMedia(self, params, forceRefresh=False): + _, dashinfos, _ = self.getDash(params) + if 'videoid' in params: + videoid = int(params['videoid']) + dashinfo = dashinfos['video'][videoid] + url = dashinfo['baseUrl'] + elif 'audioid' in params: + audioid = int(params['audioid']) + dashinfo = dashinfos['audio'][audioid] + url = dashinfo['baseUrl'] + else: + return [404, "text/plain", ""] + try: + r = self.fetch(url, headers=params['headers'], stream=True) + statusCode = r.status_code + try: + r.close() + except: + pass + except: + try: + r.close() + except: + pass + statusCode = 404 + for url in dashinfo['backupUrl']: + try: + r = self.fetch(url, headers=self.header, stream=True, timeout=1) + statusCode = r.status_code + except: + statusCode = 404 + if statusCode == 200: + break + try: + r.close() + except: + pass + if statusCode != 200 and self.retry == 0: + self.retry += 1 + self.proxyMedia(params, True) + header = self.header.copy() + if 'range' in params: + header['Range'] = params['range'] + return [206, "application/octet-stream", self.fetch(url, headers=header, stream=True).content] + + def getDash(self, params, forceRefresh=False): + aid = params['aid'] + cid = params['cid'] + url = unquote(params['url']) + if 'thread' in params: + thread = params['thread'] + else: + thread = 0 + header = self.header.copy() + self.setCache('debug', params['cookies']) + cookieDict = json.loads(params['cookies']) + key = f'bilimdmpdCache_{aid}_{cid}' + if forceRefresh: + self.delCache(key) + else: + data = self.getCache(key) + if data: + return data['content'], data['dashinfos'], data['type'] + + cookies = cookieDict.copy() + r = self.fetch(url, cookies=cookies, headers=header, timeout=5) + data = json.loads(self.cleanText(r.text)) + if data['code'] != 0: + return '', {}, '' + if not 'dash' in data['result']: + purl = data['result']['durl'][0]['url'] + try: + expiresAt = int(self.regStr(reg='deadline=(\d+)', src=purl).group(1)) - 60 + except: + expiresAt = int(time.time()) + 600 + if int(thread) > 0: + try: + self.fetch('http://127.0.0.1:7777') + except: + self.fetch('http://127.0.0.1:9978/go') + purl = f'http://127.0.0.1:7777?url={quote(purl)}&thread={thread}' + self.setCache(key, {'content': purl, 'type': 'mp4', 'dashinfos': data['result'], 'expiresAt': expiresAt}) + return purl, data['result'], 'mp4' + + dashinfos = data['result']['dash'] + duration = dashinfos['duration'] + minBufferTime = dashinfos['minBufferTime'] + videoinfo = '' + videoid = 0 + deadlineList = [] + # videoList = sorted(dashinfos['video'], key=lambda x: x['bandwidth'], reverse=True) + for video in dashinfos['video']: + try: + deadline = int(self.regStr(reg='deadline=(\d+)', src=video['baseUrl']).group(1)) + except: + deadline = int(time.time()) + 600 + deadlineList.append(deadline) + codecs = video['codecs'] + bandwidth = video['bandwidth'] + frameRate = video['frameRate'] + height = video['height'] + width = video['width'] + void = video['id'] + vidparams = params.copy() + vidparams['videoid'] = videoid + baseUrl = f'http://127.0.0.1:9978/proxy?do=py&type=media&cookies={quote(json.dumps(cookies))}&url={quote(url)}&aid={aid}&cid={cid}&videoid={videoid}' + videoinfo = videoinfo + f""" + {baseUrl} + + + + \n""" + videoid += 1 + audioinfo = '' + audioid = 0 + # audioList = sorted(dashinfos['audio'], key=lambda x: x['bandwidth'], reverse=True) + for audio in dashinfos['audio']: + try: + deadline = int(self.regStr(reg='deadline=(\d+)', src=audio['baseUrl']).group(1)) + except: + deadline = int(time.time()) + 600 + deadlineList.append(deadline) + bandwidth = audio['bandwidth'] + codecs = audio['codecs'] + aoid = audio['id'] + aidparams = params.copy() + aidparams['audioid'] = audioid + baseUrl = f'http://127.0.0.1:9978/proxy?do=py&type=media&cookies={quote(json.dumps(cookies))}&url={quote(url)}&aid={aid}&cid={cid}&audioid={audioid}' + audioinfo = audioinfo + f""" + {baseUrl} + + + + \n""" + audioid += 1 + mpd = f""" + + + + {videoinfo.strip()} + + + {audioinfo.strip()} + + + """ + expiresAt = min(deadlineList) - 60 + self.setCache(key, {'type': 'mpd', 'content': mpd.replace('&', '&'), 'dashinfos': dashinfos, 'expiresAt': expiresAt}) + return mpd.replace('&', '&'), dashinfos, 'mpd' + + def getCookie(self, cookie): + if '{' in cookie and '}' in cookie: + cookies = json.loads(cookie) + else: + cookies = dict([co.strip().split('=', 1) for co in cookie.strip(';').split(';')]) + bblogin = self.getCache('bblogin') + if bblogin: + imgKey = bblogin['imgKey'] + subKey = bblogin['subKey'] + return cookies, imgKey, subKey + + header = { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.54 Safari/537.36" + } + r = self.fetch("http://api.bilibili.com/x/web-interface/nav", cookies=cookies, headers=header, timeout=10) + data = json.loads(r.text) + code = data["code"] + if code == 0: + imgKey = data['data']['wbi_img']['img_url'].rsplit('/', 1)[1].split('.')[0] + subKey = data['data']['wbi_img']['sub_url'].rsplit('/', 1)[1].split('.')[0] + self.setCache('bblogin', {'imgKey': imgKey, 'subKey': subKey, 'expiresAt': int(time.time()) + 1200}) + return cookies, imgKey, subKey + r = self.fetch("https://www.bilibili.com/", headers=header, timeout=5) + cookies = r.cookies.get_dict() + imgKey = '' + subKey = '' + return cookies, imgKey, subKey + + def removeHtmlTags(self, src): + from re import sub, compile + clean = compile('<.*?>') + return sub(clean, '', src) + + retry = 0 + header = { + "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.54 Safari/537.36", + "Referer": "https://www.bilibili.com" + } + config = { + "filter": {"1":[{"key":"season_version","name":"类型","value":[{"v":'-1',"n":"全部"},{"v":'1',"n":"正片"},{"v":'2',"n":"电影"},{"v":'3',"n":"其他"}]},{"key":"area","name":"地区","value":[{"v":'-1',"n":"全部"},{"v":'2',"n":"日本"},{"v":'3',"n":"美国"},{"v":"1,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70","n":"其他"}]},{"key":"is_finish","name":"状态","value":[{"v":'-1',"n":"全部"},{"v":'1',"n":"完结"},{"v":'0',"n":"连载"}]},{"key":"copyright","name":"版权","value":[{"v":'-1',"n":"全部"},{"v":'3',"n":"独家"},{"v":"1,2,4","n":"其他"}]},{"key":"season_status","name":"付费","value":[{"v":'-1',"n":"全部"},{"v":'1',"n":"免费"},{"v":"2,6","n":"付费"},{"v":"4,6","n":"大会员"}]},{"key":"season_month","name":"季度","value":[{"v":'-1',"n":"全部"},{"v":'1',"n":"1月"},{"v":'4',"n":"4月"},{"v":'7',"n":"7月"},{"v":'10',"n":"10月"}]},{"key":"year","name":"年份","value":[{"v":'-1',"n":"全部"},{"v":"[2023,2024)","n":"2023"},{"v":"[2022,2023)","n":"2022"},{"v":"[2021,2022)","n":"2021"},{"v":"[2020,2021)","n":"2020"},{"v":"[2019,2020)","n":"2019"},{"v":"[2018,2019)","n":"2018"},{"v":"[2017,2018)","n":"2017"},{"v":"[2016,2017)","n":"2016"},{"v":"[2015,2016)","n":"2015"},{"v":"[2010,2015)","n":"2014-2010"},{"v":"[2005,2010)","n":"2009-2005"},{"v":"[2000,2005)","n":"2004-2000"},{"v":"[1990,2000)","n":"90年代"},{"v":"[1980,1990)","n":"80年代"},{"v":"[,1980)","n":"更早"}]},{"key":"style_id","name":"风格","value":[{"v":'-1',"n":"全部"},{"v":'10010',"n":"原创"},{"v":'10011',"n":"漫画改"},{"v":'10012',"n":"小说改"},{"v":'10013',"n":"游戏改"},{"v":'10102',"n":"特摄"},{"v":'10015',"n":"布袋戏"},{"v":'10016',"n":"热血"},{"v":'10017',"n":"穿越"},{"v":'10018',"n":"奇幻"},{"v":'10020',"n":"战斗"},{"v":'10021',"n":"搞笑"},{"v":'10022',"n":"日常"},{"v":'10023',"n":"科幻"},{"v":'10024',"n":"萌系"},{"v":'10025',"n":"治愈"},{"v":'10026',"n":"校园"},{"v":'10027',"n":"少儿"},{"v":'10028',"n":"泡面"},{"v":'10029',"n":"恋爱"},{"v":'10030',"n":"少女"},{"v":'10031',"n":"魔法"},{"v":'10032',"n":"冒险"},{"v":'10033',"n":"历史"},{"v":'10034',"n":"架空"},{"v":'10035',"n":"机战"},{"v":'10036',"n":"神魔"},{"v":'10037',"n":"声控"},{"v":'10038',"n":"运动"},{"v":'10039',"n":"励志"},{"v":'10040',"n":"音乐"},{"v":'10041',"n":"推理"},{"v":'10042',"n":"社团"},{"v":'10043',"n":"智斗"},{"v":'10044',"n":"催泪"},{"v":'10045',"n":"美食"},{"v":'10046',"n":"偶像"},{"v":'10047',"n":"乙女"},{"v":'10048',"n":"职场"}]}],"4":[{"key":"season_version","name":"类型","value":[{"v":'-1',"n":"全部"},{"v":'1',"n":"正片"},{"v":'2',"n":"电影"},{"v":'3',"n":"其他"}]},{"key":"area","name":"地区","value":[{"v":'-1',"n":"全部"},{"v":'2',"n":"日本"},{"v":'3',"n":"美国"},{"v":"1,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70","n":"其他"}]},{"key":"is_finish","name":"状态","value":[{"v":'-1',"n":"全部"},{"v":'1',"n":"完结"},{"v":'0',"n":"连载"}]},{"key":"copyright","name":"版权","value":[{"v":'-1',"n":"全部"},{"v":'3',"n":"独家"},{"v":"1,2,4","n":"其他"}]},{"key":"season_status","name":"付费","value":[{"v":'-1',"n":"全部"},{"v":'1',"n":"免费"},{"v":"2,6","n":"付费"},{"v":"4,6","n":"大会员"}]},{"key":"year","name":"年份","value":[{"v":'-1',"n":"全部"},{"v":"[2023,2024)","n":"2023"},{"v":"[2022,2023)","n":"2022"},{"v":"[2021,2022)","n":"2021"},{"v":"[2020,2021)","n":"2020"},{"v":"[2019,2020)","n":"2019"},{"v":"[2018,2019)","n":"2018"},{"v":"[2017,2018)","n":"2017"},{"v":"[2016,2017)","n":"2016"},{"v":"[2015,2016)","n":"2015"},{"v":"[2010,2015)","n":"2014-2010"},{"v":"[2005,2010)","n":"2009-2005"},{"v":"[2000,2005)","n":"2004-2000"},{"v":"[1990,2000)","n":"90年代"},{"v":"[1980,1990)","n":"80年代"},{"v":"[,1980)","n":"更早"}]},{"key":"style_id","name":"风格","value":[{"v":'-1',"n":"全部"},{"v":'10010',"n":"原创"},{"v":'10011',"n":"漫画改"},{"v":'10012',"n":"小说改"},{"v":'10013',"n":"游戏改"},{"v":'10014',"n":"动态漫"},{"v":'10015',"n":"布袋戏"},{"v":'10016',"n":"热血"},{"v":'10018',"n":"奇幻"},{"v":'10019',"n":"玄幻"},{"v":'10020',"n":"战斗"},{"v":'10021',"n":"搞笑"},{"v":'10078',"n":"武侠"},{"v":'10022',"n":"日常"},{"v":'10023',"n":"科幻"},{"v":'10024',"n":"萌系"},{"v":'10025',"n":"治愈"},{"v":'10057',"n":"悬疑"},{"v":'10026',"n":"校园"},{"v":'10027',"n":"少儿"},{"v":'10028',"n":"泡面"},{"v":'10029',"n":"恋爱"},{"v":'10030',"n":"少女"},{"v":'10031',"n":"魔法"},{"v":'10033',"n":"历史"},{"v":'10035',"n":"机战"},{"v":'10036',"n":"神魔"},{"v":'10037',"n":"声控"},{"v":'10038',"n":"运动"},{"v":'10039',"n":"励志"},{"v":'10040',"n":"音乐"},{"v":'10041',"n":"推理"},{"v":'10042',"n":"社团"},{"v":'10043',"n":"智斗"},{"v":'10044',"n":"催泪"},{"v":'10045',"n":"美食"},{"v":'10046',"n":"偶像"},{"v":'10047',"n":"乙女"},{"v":'10048',"n":"职场"},{"v":'10049',"n":"古风"}]}],"2":[{"key":"area","name":"地区","value":[{"v":'-1',"n":"全部"},{"v":'1',"n":"中国大陆"},{"v":"6,7","n":"中国港台"},{"v":'3',"n":"美国"},{"v":'2',"n":"日本"},{"v":'8',"n":"韩国"},{"v":'9',"n":"法国"},{"v":'4',"n":"英国"},{"v":'15',"n":"德国"},{"v":'10',"n":"泰国"},{"v":'35',"n":"意大利"},{"v":'13',"n":"西班牙"},{"v":"5,11,12,14,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70","n":"其他"}]},{"key":"season_status","name":"付费","value":[{"v":'-1',"n":"全部"},{"v":'1',"n":"免费"},{"v":"2,6","n":"付费"},{"v":"4,6","n":"大会员"}]},{"key":"style_id","name":"风格","value":[{"v":'-1',"n":"全部"},{"v":'10104',"n":"短片"},{"v":'10050',"n":"剧情"},{"v":'10051',"n":"喜剧"},{"v":'10052',"n":"爱情"},{"v":'10053',"n":"动作"},{"v":'10054',"n":"恐怖"},{"v":'10023',"n":"科幻"},{"v":'10055',"n":"犯罪"},{"v":'10056',"n":"惊悚"},{"v":'10057',"n":"悬疑"},{"v":'10018',"n":"奇幻"},{"v":'10058',"n":"战争"},{"v":'10059',"n":"动画"},{"v":'10060',"n":"传记"},{"v":'10061',"n":"家庭"},{"v":'10062',"n":"歌舞"},{"v":'10033',"n":"历史"},{"v":'10032',"n":"冒险"},{"v":'10063',"n":"纪实"},{"v":'10064',"n":"灾难"},{"v":'10011',"n":"漫画改"},{"v":'10012',"n":"小说改"}]},{"key":"release_date","name":"年份","value":[{"v":'-1',"n":"全部"},{"v":"[2023-01-01 00:00:00,2024-01-01 00:00:00)","n":"2023"},{"v":"[2022-01-01 00:00:00,2023-01-01 00:00:00)","n":"2022"},{"v":"[2021-01-01 00:00:00,2022-01-01 00:00:00)","n":"2021"},{"v":"[2020-01-01 00:00:00,2021-01-01 00:00:00)","n":"2020"},{"v":"[2019-01-01 00:00:00,2020-01-01 00:00:00)","n":"2019"},{"v":"[2018-01-01 00:00:00,2019-01-01 00:00:00)","n":"2018"},{"v":"[2017-01-01 00:00:00,2018-01-01 00:00:00)","n":"2017"},{"v":"[2016-01-01 00:00:00,2017-01-01 00:00:00)","n":"2016"},{"v":"[2010-01-01 00:00:00,2016-01-01 00:00:00)","n":"2015-2010"},{"v":"[2005-01-01 00:00:00,2010-01-01 00:00:00)","n":"2009-2005"},{"v":"[2000-01-01 00:00:00,2005-01-01 00:00:00)","n":"2004-2000"},{"v":"[1990-01-01 00:00:00,2000-01-01 00:00:00)","n":"90年代"},{"v":"[1980-01-01 00:00:00,1990-01-01 00:00:00)","n":"80年代"},{"v":"[,1980-01-01 00:00:00)","n":"更早"}]}],"5":[{"key":"area","name":"地区","value":[{"v":'-1',"n":"全部"},{"v":"1,6,7","n":"中国"},{"v":'2',"n":"日本"},{"v":'3',"n":"美国"},{"v":'4',"n":"英国"},{"v":'10',"n":"泰国"},{"v":"5,8,9,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70","n":"其他"}]},{"key":"season_status","name":"付费","value":[{"v":'-1',"n":"全部"},{"v":'1',"n":"免费"},{"v":"2,6","n":"付费"},{"v":"4,6","n":"大会员"}]},{"key":"style_id","name":"风格","value":[{"v":'-1',"n":"全部"},{"v":'10021',"n":"搞笑"},{"v":'10018',"n":"奇幻"},{"v":'10058',"n":"战争"},{"v":'10078',"n":"武侠"},{"v":'10079',"n":"青春"},{"v":'10103',"n":"短剧"},{"v":'10080',"n":"都市"},{"v":'10081',"n":"古装"},{"v":'10082',"n":"谍战"},{"v":'10083',"n":"经典"},{"v":'10084',"n":"情感"},{"v":'10057',"n":"悬疑"},{"v":'10039',"n":"励志"},{"v":'10085',"n":"神话"},{"v":'10017',"n":"穿越"},{"v":'10086',"n":"年代"},{"v":'10087',"n":"农村"},{"v":'10088',"n":"刑侦"},{"v":'10050',"n":"剧情"},{"v":'10061',"n":"家庭"},{"v":'10033',"n":"历史"},{"v":'10089',"n":"军旅"},{"v":'10023',"n":"科幻"}]},{"key":"release_date","name":"年份","value":[{"v":'-1',"n":"全部"},{"v":"[2023-01-01 00:00:00,2024-01-01 00:00:00)","n":"2023"},{"v":"[2022-01-01 00:00:00,2023-01-01 00:00:00)","n":"2022"},{"v":"[2021-01-01 00:00:00,2022-01-01 00:00:00)","n":"2021"},{"v":"[2020-01-01 00:00:00,2021-01-01 00:00:00)","n":"2020"},{"v":"[2019-01-01 00:00:00,2020-01-01 00:00:00)","n":"2019"},{"v":"[2018-01-01 00:00:00,2019-01-01 00:00:00)","n":"2018"},{"v":"[2017-01-01 00:00:00,2018-01-01 00:00:00)","n":"2017"},{"v":"[2016-01-01 00:00:00,2017-01-01 00:00:00)","n":"2016"},{"v":"[2010-01-01 00:00:00,2016-01-01 00:00:00)","n":"2015-2010"},{"v":"[2005-01-01 00:00:00,2010-01-01 00:00:00)","n":"2009-2005"},{"v":"[2000-01-01 00:00:00,2005-01-01 00:00:00)","n":"2004-2000"},{"v":"[1990-01-01 00:00:00,2000-01-01 00:00:00)","n":"90年代"},{"v":"[1980-01-01 00:00:00,1990-01-01 00:00:00)","n":"80年代"},{"v":"[,1980-01-01 00:00:00)","n":"更早"}]}],"7":[{"key":"season_status","name":"付费","value":[{"v":'-1',"n":"全部"},{"v":'1',"n":"免费"},{"v":"2,6","n":"付费"},{"v":"4,6","n":"大会员"}]},{"key":"style_id","name":"风格","value":[{"v":'-1',"n":"全部"},{"v":'10040',"n":"音乐"},{"v":'10090',"n":"访谈"},{"v":'10091',"n":"脱口秀"},{"v":'10092',"n":"真人秀"},{"v":'10094',"n":"选秀"},{"v":'10045',"n":"美食"},{"v":'10095',"n":"旅游"},{"v":'10098',"n":"晚会"},{"v":'10096',"n":"演唱会"},{"v":'10084',"n":"情感"},{"v":'10051',"n":"喜剧"},{"v":'10097',"n":"亲子"},{"v":'10100',"n":"文化"},{"v":'10048',"n":"职场"},{"v":'10069',"n":"萌宠"},{"v":'10099',"n":"养成"}]}]} + } \ No newline at end of file diff --git a/PY/爱奇艺.py b/PY/爱奇艺.py new file mode 100644 index 0000000..2b0af3d --- /dev/null +++ b/PY/爱奇艺.py @@ -0,0 +1,248 @@ +# -*- coding: utf-8 -*- +# by @嗷呜 +import random +import sys +from base64 import b64encode, b64decode +from concurrent.futures import ThreadPoolExecutor, as_completed +from urllib.parse import urlencode +sys.path.append('..') +from base.spider import Spider + + +class Spider(Spider): + + def init(self, extend=""): + self.did = self.random_str(32) + pass + + def getName(self): + pass + + def isVideoFormat(self, url): + pass + + def manualVideoCheck(self): + pass + + def destroy(self): + pass + + rhost = 'https://www.iqiyi.com' + + hhost='https://mesh.if.iqiyi.com' + + dhost='https://miniapp.iqiyi.com' + + headers = { + 'Origin': rhost, + 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36', + 'Referer': f'{rhost}/', + } + + def homeContent(self, filter): + result = {} + cateManual = { + "全部": "1009", + "电影": "1", + "剧集": "2", + "综艺": "6", + "动漫": "4", + "儿童": "15", + "微剧": "35", + "纪录片": "3" + } + classes = [] + filters = {} + for k in cateManual: + classes.append({ + 'type_name': k, + 'type_id': cateManual[k] + }) + with ThreadPoolExecutor(max_workers=len(classes)) as executor: + results = executor.map(self.getf, classes) + for id, ft in results: + if len(ft):filters[id] = ft + result['class'] = classes + result['filters'] = filters + return result + + def homeVideoContent(self): + data=self.fetch(f'{self.hhost}/portal/lw/v5/channel/recommend?v=13.014.21150', headers=self.headers).json() + vlist = [] + for i in data['items'][1:]: + for j in i['video'][0]['data']: + id = j.get('firstId') + pic=j.get('prevue',{}).get('image_url') or j.get('album_image_url_hover') + if id and pic: + pu=j.get('prevue',{}).get('page_url') or j.get('page_url').split('?')[0] + id = f'{id}@{self.e64(pu)}' + vlist.append({ + 'vod_id': id, + 'vod_name': j.get('display_name'), + 'vod_pic': pic, + 'vod_year': j.get('sns_score'), + 'vod_remarks': j.get('dq_updatestatus') or j.get('rank_prefix') + }) + return {'list':vlist} + + def categoryContent(self, tid, pg, filter, extend): + if pg == "1": + self.sid = '' + new_data = {'mode':'24'} + for key, value in extend.items(): + if value: + key_value_pairs = self.d64(value).split(',') + for pair in key_value_pairs: + k, v = pair.split('=') + if k in new_data: + new_data[k] += "," + v + else: + new_data[k] = v + path=f'/portal/lw/videolib/data?uid=&passport_id=&ret_num=60&version=13.014.21150&device_id={self.did}&channel_id={tid}&page_id={pg}&session={self.sid}&os=&conduit_id=&vip=0&auth&recent_selected_tag=&ad=%5B%7B%22lm%22:%225%22,%22ai%22:%225%22,%22fp%22:%226%22,%22sei%22:%22Sa867aa9d326e2bd8654d8c2a8636055e%22,%22position%22:%22library%22%7D%5D&adExt=%7B%22r%22:%221.2.1-ares6-pure%22%7D&dfp=a12f96215b2f7842a98c082799ca0c3d9236be00946701b106829754d8ece3aaf8&filter={urlencode(new_data)}' + data=self.fetch(f'{self.hhost}{path}', headers=self.headers).json() + self.sid = data['session'] + videos = [] + for i in data['data']: + id = i.get('firstId') or i.get('tv_id') + if not id: + id=i.get('play_url').split(';')[0].split('=')[-1] + if id and not i.get('h'): + id=f'{id}@{self.e64(i.get("page_url"))}' + videos.append({ + 'vod_id': id, + 'vod_name': i.get('display_name'), + 'vod_pic': i.get('album_image_url_hover'), + 'vod_year': i.get('sns_score'), + 'vod_remarks': i.get('dq_updatestatus') or i.get('pay_mark') + }) + result = {} + result['list'] = videos + result['page'] = pg + result['pagecount'] = 9999 + result['limit'] = 90 + result['total'] = 999999 + return result + + def detailContent(self, ids): + ids = ids[0].split('@') + ids[-1] = self.d64(ids[-1]) + data = self.fetch(f'{self.dhost}/h5/mina/baidu/play/body/v1/{ids[0]}/', headers=self.headers).json() + v=data['data']['playInfo'] + vod = { + 'vod_name': v.get('albumName'), + 'type_name': v.get('tags'), + 'vod_year': v.get('albumYear'), + 'vod_remarks': v.get('updateStrategy'), + 'vod_actor': v.get('mainActors'), + 'vod_director': v.get('directors'), + 'vod_content': v.get('albumDesc'), + 'vod_play_from': '爱奇艺', + 'vod_play_url': '' + } + if data.get('data') and data['data'].get('videoList') and data['data']['videoList'].get('videos'): + purl=[f'{i["shortTitle"]}${i["pageUrl"]}' for i in data['data']['videoList']['videos']] + pg=data['data']['videoList'].get('totalPages') + if pg and pg > 1: + id = v['albumId'] + pages = list(range(2, pg + 1)) + page_results = {} + with ThreadPoolExecutor(max_workers=10) as executor: + future_to_page = { + executor.submit(self.fetch_page_data, page, id): page + for page in pages + } + for future in as_completed(future_to_page): + page = future_to_page[future] + try: + result = future.result() + page_results[page] = result + except Exception as e: + print(f"Error fetching page {page}: {e}") + for page in sorted(page_results.keys()): + purl.extend(page_results[page]) + vod['vod_play_url'] = '#'.join(purl) + else: + vdata=self.fetch(f'{self.dhost}/h5/mina/baidu/play/head/v1/{ids[0]}/', headers=self.headers).json() + v=vdata['data']['playInfo'] + vod = { + 'vod_name': v.get('shortTitle'), + 'type_name': v.get('channelName'), + 'vod_year': v.get('year'), + 'vod_remarks': v.get('focus'), + 'vod_actor': v.get('mainActors'), + 'vod_director': v.get('directors'), + 'vod_content': v.get('desc'), + 'vod_play_from': '爱奇艺', + 'vod_play_url': f'{v.get("shortTitle")}${ids[-1]}' + } + return {'list':[vod]} + + def searchContent(self, key, quick, pg="1"): + data=self.fetch(f'{self.hhost}/portal/lw/search/homePageV3?key={key}¤t_page={pg}&mode=1&source=input&suggest=&version=13.014.21150&pageNum={pg}&pageSize=25&pu=&u={self.did}&scale=150&token=&userVip=0&conduit=&vipType=-1&os=&osShortName=win10&dataType=&appMode=', headers=self.headers).json() + videos = [] + vdata=data['data']['templates'] + for i in data['data']['templates']: + if i.get('intentAlbumInfos'): + vdata=[{'albumInfo': c} for c in i['intentAlbumInfos']]+vdata + + for i in vdata: + if i.get('albumInfo') and (i['albumInfo'].get('playQipuId','') or i['albumInfo'].get('qipuId')) and i['albumInfo'].get('pageUrl'): + b=i['albumInfo'] + id=f"{(b.get('playQipuId','') or b.get('qipuId'))}@{self.e64(b.get('pageUrl'))}" + videos.append({ + 'vod_id': id, + 'vod_name': b.get('title'), + 'vod_pic': b.get('img'), + 'vod_year': (b.get('year',{}) or {}).get('value'), + 'vod_remarks': b.get('subscriptContent') or b.get('channel') or b.get('vipTips') + }) + return {'list':videos,'page':pg} + + def playerContent(self, flag, id, vipFlags): + return {'jx':1,'parse': 1, 'url': id, 'header': ''} + + def localProxy(self, param): + pass + + def fetch_page_data(self, page, id): + try: + url = f'{self.dhost}/h5/mina/avlist/{page}/{id}/' + data = self.fetch(url, headers=self.headers).json() + return [f'{i["shortTitle"]}${i["pageUrl"]}' for i in data['data']['videoList']['videos']] + except: + return [] + + def getf(self,body): + data=self.fetch(f'{self.hhost}/portal/lw/videolib/tag?channel_id={body["type_id"]}&tagAdd=&selected_tag_name=&version=13.014.21150&device={self.did}&uid=', headers=self.headers).json() + ft = [] + # for i in data[:-1]: + for i in data: + try: + value_array = [{"n": value['text'], "v": self.e64(value['tag_param'])} for value in i['tags'] if + value.get('tag_param')] + ft.append({"key": i['group'], "name": i['group'], "value": value_array}) + except: + print(i) + return (body['type_id'], ft) + + def e64(self, text): + try: + text_bytes = text.encode('utf-8') + encoded_bytes = b64encode(text_bytes) + return encoded_bytes.decode('utf-8') + except Exception as e: + print(f"Base64编码错误: {str(e)}") + return "" + + def d64(self,encoded_text: str): + try: + encoded_bytes = encoded_text.encode('utf-8') + decoded_bytes = b64decode(encoded_bytes) + return decoded_bytes.decode('utf-8') + except Exception as e: + print(f"Base64解码错误: {str(e)}") + return "" + + def random_str(self,length=16): + hex_chars = '0123456789abcdef' + return ''.join(random.choice(hex_chars) for _ in range(length)) diff --git a/PY/网络直播.py b/PY/网络直播.py new file mode 100644 index 0000000..5fbeeaa --- /dev/null +++ b/PY/网络直播.py @@ -0,0 +1,768 @@ +# -*- coding: utf-8 -*- +# by @嗷呜 +import json +import re +import sys +import time +from base64 import b64decode, b64encode +from urllib.parse import parse_qs +import requests +from pyquery import PyQuery as pq +sys.path.append('..') +from base.spider import Spider +from concurrent.futures import ThreadPoolExecutor + + +class Spider(Spider): + + def init(self, extend=""): + tid = 'douyin' + headers = self.gethr(0, tid) + response = requests.head(self.hosts[tid], headers=headers) + ttwid = response.cookies.get('ttwid') + headers.update({ + 'authority': self.hosts[tid].split('//')[-1], + 'cookie': f'ttwid={ttwid}' if ttwid else '' + }) + self.dyheaders = headers + pass + + def getName(self): + pass + + def isVideoFormat(self, url): + pass + + def manualVideoCheck(self): + pass + + def destroy(self): + pass + + headers = [ + { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36 Edg/126.0.0.0" + }, + { + "User-Agent": "Dart/3.4 (dart:io)" + } + ] + + excepturl = 'https://www.baidu.com' + + hosts = { + "huya": ["https://www.huya.com","https://mp.huya.com"], + "douyin": "https://live.douyin.com", + "douyu": "https://www.douyu.com", + "wangyi": "https://cc.163.com", + "bili": ["https://api.live.bilibili.com", "https://api.bilibili.com"] + } + + referers = { + "huya": "https://live.cdn.huya.com", + "douyin": "https://live.douyin.com", + "douyu": "https://m.douyu.com", + "bili": "https://live.bilibili.com" + } + + playheaders = { + "wangyi": { + "User-Agent": "ExoPlayer", + "Connection": "Keep-Alive", + "Icy-MetaData": "1" + }, + "bili": { + 'Accept': '*/*', + 'Icy-MetaData': '1', + 'referer': referers['bili'], + 'user-agent': headers[0]['User-Agent'] + }, + 'douyin': { + 'User-Agent': 'libmpv', + 'Icy-MetaData': '1' + }, + 'huya': { + 'User-Agent': 'ExoPlayer', + 'Connection': 'Keep-Alive', + 'Icy-MetaData': '1' + }, + 'douyu': { + 'User-Agent': 'libmpv', + 'Icy-MetaData': '1' + } + } + + def process_bili(self): + try: + self.blfdata = self.fetch( + f'{self.hosts["bili"][0]}/room/v1/Area/getList?need_entrance=1&parent_id=0', + headers=self.gethr(0, 'bili') + ).json() + return ('bili', [{'key': 'cate', 'name': '分类', + 'value': [{'n': i['name'], 'v': str(i['id'])} + for i in self.blfdata['data']]}]) + except Exception as e: + print(f"bili处理错误: {e}") + return 'bili', None + + def process_douyin(self): + try: + data = self.getpq(self.hosts['douyin'], headers=self.dyheaders)('script') + for i in data.items(): + if 'categoryData' in i.text(): + content = i.text() + start = content.find('{') + end = content.rfind('}') + 1 + if start != -1 and end != -1: + json_str = content[start:end] + json_str = json_str.replace('\\"', '"') + try: + self.dyifdata = json.loads(json_str) + return ('douyin', [{'key': 'cate', 'name': '分类', + 'value': [{'n': i['partition']['title'], + 'v': f"{i['partition']['id_str']}@@{i['partition']['title']}"} + for i in self.dyifdata['categoryData']]}]) + except json.JSONDecodeError as e: + print(f"douyin解析错误: {e}") + return 'douyin', None + except Exception as e: + print(f"douyin请求或处理错误: {e}") + return 'douyin', None + + def process_douyu(self): + try: + self.dyufdata = self.fetch( + f'{self.referers["douyu"]}/api/cate/list', + headers=self.headers[1] + ).json() + return ('douyu', [{'key': 'cate', 'name': '分类', + 'value': [{'n': i['cate1Name'], 'v': str(i['cate1Id'])} + for i in self.dyufdata['data']['cate1Info']]}]) + except Exception as e: + print(f"douyu错误: {e}") + return 'douyu', None + + def homeContent(self, filter): + result = {} + cateManual = { + "虎牙": "huya", + "哔哩": "bili", + "抖音": "douyin", + "斗鱼": "douyu", + "网易": "wangyi" + } + classes = [] + filters = { + 'huya': [{'key': 'cate', 'name': '分类', + 'value': [{'n': '网游', 'v': '1'}, {'n': '单机', 'v': '2'}, + {'n': '娱乐', 'v': '8'}, {'n': '手游', 'v': '3'}]}] + } + + with ThreadPoolExecutor(max_workers=3) as executor: + futures = { + executor.submit(self.process_bili): 'bili', + executor.submit(self.process_douyin): 'douyin', + executor.submit(self.process_douyu): 'douyu' + } + + for future in futures: + platform, filter_data = future.result() + if filter_data: + filters[platform] = filter_data + + for k in cateManual: + classes.append({ + 'type_name': k, + 'type_id': cateManual[k] + }) + + result['class'] = classes + result['filters'] = filters + return result + + def homeVideoContent(self): + pass + + def categoryContent(self, tid, pg, filter, extend): + vdata = [] + result = {} + pagecount = 9999 + result['page'] = pg + result['limit'] = 90 + result['total'] = 999999 + if tid == 'wangyi': + vdata, pagecount = self.wyccContent(tid, pg, filter, extend, vdata) + elif 'bili' in tid: + vdata, pagecount = self.biliContent(tid, pg, filter, extend, vdata) + elif 'huya' in tid: + vdata, pagecount = self.huyaContent(tid, pg, filter, extend, vdata) + elif 'douyin' in tid: + vdata, pagecount = self.douyinContent(tid, pg, filter, extend, vdata) + elif 'douyu' in tid: + vdata, pagecount = self.douyuContent(tid, pg, filter, extend, vdata) + result['list'] = vdata + result['pagecount'] = pagecount + return result + + def wyccContent(self, tid, pg, filter, extend, vdata): + params = { + 'format': 'json', + 'start': (int(pg) - 1) * 20, + 'size': '20', + } + response = self.fetch(f'{self.hosts[tid]}/api/category/live/', params=params, headers=self.headers[0]).json() + for i in response['lives']: + if i.get('cuteid'): + bvdata = self.buildvod( + vod_id=f"{tid}@@{i['cuteid']}", + vod_name=i.get('title'), + vod_pic=i.get('cover'), + vod_remarks=i.get('nickname'), + style={"type": "rect", "ratio": 1.33} + ) + vdata.append(bvdata) + return vdata, 9999 + + def biliContent(self, tid, pg, filter, extend, vdata): + if extend.get('cate') and pg == '1' and 'click' not in tid: + for i in self.blfdata['data']: + if str(i['id']) == extend['cate']: + for j in i['list']: + v = self.buildvod( + vod_id=f"click_{tid}@@{i['id']}@@{j['id']}", + vod_name=j.get('name'), + vod_pic=j.get('pic'), + vod_tag=1, + style={"type": "oval", "ratio": 1} + ) + vdata.append(v) + return vdata, 1 + else: + path = f'/xlive/web-interface/v1/second/getListByArea?platform=web&sort=online&page_size=30&page={pg}' + if 'click' in tid: + ids = tid.split('_')[1].split('@@') + tid = ids[0] + path = f'/xlive/web-interface/v1/second/getList?platform=web&parent_area_id={ids[1]}&area_id={ids[-1]}&sort_type=&page={pg}' + data = self.fetch(f'{self.hosts[tid][0]}{path}', headers=self.gethr(0, tid)).json() + for i in data['data']['list']: + if i.get('roomid'): + data = self.buildvod( + f"{tid}@@{i['roomid']}", + i.get('title'), + i.get('cover'), + i.get('watched_show', {}).get('text_large'), + 0, + i.get('uname'), + style={"type": "rect", "ratio": 1.33} + ) + vdata.append(data) + return vdata, 9999 + + def huyaContent(self, tid, pg, filter, extend, vdata): + if extend.get('cate') and pg == '1' and 'click' not in tid: + id = extend.get('cate') + data = self.fetch(f'{self.referers[tid]}/liveconfig/game/bussLive?bussType={id}', + headers=self.headers[1]).json() + for i in data['data']: + v = self.buildvod( + vod_id=f"click_{tid}@@{int(i['gid'])}", + vod_name=i.get('gameFullName'), + vod_pic=f'https://huyaimg.msstatic.com/cdnimage/game/{int(i["gid"])}-MS.jpg', + vod_tag=1, + style={"type": "oval", "ratio": 1} + ) + vdata.append(v) + return vdata, 1 + else: + gid = '' + if 'click' in tid: + ids = tid.split('_')[1].split('@@') + tid = ids[0] + gid = f'&gameId={ids[1]}' + data = self.fetch(f'{self.hosts[tid][0]}/cache.php?m=LiveList&do=getLiveListByPage&tagAll=0{gid}&page={pg}', + headers=self.headers[1]).json() + for i in data['data']['datas']: + if i.get('profileRoom'): + v = self.buildvod( + f"{tid}@@{i['profileRoom']}", + i.get('introduction'), + i.get('screenshot'), + str(int(i.get('totalCount', '1')) / 10000) + '万', + 0, + i.get('nick'), + style={"type": "rect", "ratio": 1.33} + + ) + 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']: + if str(i['cate1Id']) == extend['cate']: + v = self.buildvod( + vod_id=f"click_{tid}@@{i['cate2Id']}", + vod_name=i.get('cate2Name'), + vod_pic=i.get('icon'), + vod_remarks=i.get('count'), + vod_tag=1, + style={"type": "oval", "ratio": 1} + ) + vdata.append(v) + return vdata, 1 + else: + path = f'/japi/weblist/apinc/allpage/6/{pg}' + if 'click' in tid: + ids = tid.split('_')[1].split('@@') + tid = ids[0] + path = f'/gapi/rkc/directory/mixList/2_{ids[1]}/{pg}' + url = f'{self.hosts[tid]}{path}' + data = self.fetch(url, headers=self.headers[1]).json() + for i in data['data']['rl']: + v = self.buildvod( + vod_id=f"{tid}@@{i['rid']}", + vod_name=i.get('rn'), + vod_pic=i.get('rs16'), + vod_year=str(int(i.get('ol', 1)) / 10000) + '万', + vod_remarks=i.get('nn'), + style={"type": "rect", "ratio": 1.33} + ) + vdata.append(v) + return vdata, 9999 + + def detailContent(self, ids): + ids = ids[0].split('@@') + if ids[0] == 'wangyi': + vod = self.wyccDetail(ids) + elif ids[0] == 'bili': + 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]} + + def wyccDetail(self, ids): + try: + vdata = self.getpq(f'{self.hosts[ids[0]]}/{ids[1]}', self.headers[0])('script').eq(-1).text() + + def get_quality_name(vbr): + if vbr <= 600: + return "标清" + elif vbr <= 1000: + return "高清" + elif vbr <= 2000: + return "超清" + else: + return "蓝光" + + data = json.loads(vdata)['props']['pageProps']['roomInfoInitData'] + name = data['live'].get('title', ids[0]) + vod = self.buildvod(vod_name=data.get('keywords_suffix'), vod_remarks=data['live'].get('title'), + vod_content=data.get('description_suffix')) + resolution_data = data['live']['quickplay']['resolution'] + all_streams = {} + sorted_qualities = sorted(resolution_data.items(), + key=lambda x: x[1]['vbr'], + reverse=True) + for quality, data in sorted_qualities: + vbr = data['vbr'] + quality_name = get_quality_name(vbr) + for cdn_name, url in data['cdn'].items(): + if cdn_name not in all_streams and type(url) == str and url.startswith('http'): + all_streams[cdn_name] = [] + if isinstance(url, str) and url.startswith('http'): + all_streams[cdn_name].extend([quality_name, url]) + plists = [] + names = [] + for i, (cdn_name, stream_list) in enumerate(all_streams.items(), 1): + names.append(f'线路{i}') + pstr = f"{name}${ids[0]}@@{self.e64(json.dumps(stream_list))}" + plists.append(pstr) + vod['vod_play_from'] = "$$$".join(names) + vod['vod_play_url'] = "$$$".join(plists) + return vod + except Exception as e: + return self.handle_exception(e) + + def biliDetail(self, ids): + 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'] + 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'), + ) + 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) + return vod + except Exception as e: + return self.handle_exception(e) + + def huyaDetail(self, ids): + 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'] + vod = self.buildvod( + vod_name=v.get('introduction'), + type_name=v.get('gameFullName'), + vod_director=v.get('nick'), + vod_remarks=v.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 + ) + 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) + 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 douyuDetail(self, ids): + headers = self.gethr(0, zr=f'{self.hosts[ids[0]]}/{ids[1]}') + try: + data = self.fetch(f'{self.hosts[ids[0]]}/betard/{ids[1]}', headers=headers).json() + vname = data['room']['room_name'] + vod = self.buildvod( + vod_name=vname, + vod_remarks=data['room'].get('second_lvl_name'), + vod_director=data['room'].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) + return vod + except Exception as e: + return self.handle_exception(e) + + 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 searchContent(self, key, quick, pg="1"): + pass + + def playerContent(self, flag, id, vipFlags): + try: + ids = id.split('@@') + p = 1 + if ids[0] in ['wangyi', 'douyin','huya']: + 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])) + elif ids[0] == 'douyu': + p, url = self.douyuplay(ids) + return {'parse': p, 'url': url, 'header': self.playheaders[ids[0]]} + except Exception as e: + return {'parse': 1, 'url': self.excepturl, 'header': self.headers[0]} + + def biliplay(self, ids): + 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() + 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 + return 0, urls + except Exception as e: + return 1, self.excepturl + + def douyuplay(self, ids): + 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() + + result = [] + for bit in sorted(result_obj.keys(), reverse=True): + result.extend(result_obj[bit]) + + if result: + return 0, result + return 1, self.excepturl + + except Exception as 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 + + def e64(self, text): + try: + text_bytes = text.encode('utf-8') + encoded_bytes = b64encode(text_bytes) + return encoded_bytes.decode('utf-8') + except Exception as e: + print(f"Base64编码错误: {str(e)}") + return "" + + def d64(self, encoded_text): + try: + encoded_bytes = encoded_text.encode('utf-8') + decoded_bytes = b64decode(encoded_bytes) + return decoded_bytes.decode('utf-8') + except Exception as e: + print(f"Base64解码错误: {str(e)}") + return "" + + def josn_to_params(self, params, skip_empty=False): + query = [] + for k, v in params.items(): + if skip_empty and not v: + continue + query.append(f"{k}={v}") + return "&".join(query) + + def params_to_json(self, query_string): + parsed_data = parse_qs(query_string) + result = {key: value[0] for key, value in parsed_data.items()} + return result + + def buildvod(self, vod_id='', vod_name='', vod_pic='', vod_year='', vod_tag='', vod_remarks='', style='', + type_name='', vod_area='', vod_actor='', vod_director='', + vod_content='', vod_play_from='', vod_play_url=''): + vod = { + 'vod_id': vod_id, + 'vod_name': vod_name, + 'vod_pic': vod_pic, + 'vod_year': vod_year, + 'vod_tag': 'folder' if vod_tag else '', + 'vod_remarks': vod_remarks, + 'style': style, + 'type_name': type_name, + 'vod_area': vod_area, + 'vod_actor': vod_actor, + 'vod_director': vod_director, + 'vod_content': vod_content, + 'vod_play_from': vod_play_from, + 'vod_play_url': vod_play_url + } + vod = {key: value for key, value in vod.items() if value} + return vod + + def getpq(self, url, headers=None, cookies=None): + data = self.fetch(url, headers=headers, cookies=cookies).text + try: + return pq(data) + except Exception as e: + print(f"解析页面错误: {str(e)}") + return pq(data.encode('utf-8')) + + def gethr(self, index, rf='', zr=''): + headers = self.headers[index] + if zr: + headers['referer'] = zr + else: + headers['referer'] = f"{self.referers[rf]}/" + return headers + + def handle_exception(self, e): + print(f"报错: {str(e)}") + return {'vod_play_from': '哎呀翻车啦', 'vod_play_url': f'翻车啦${self.excepturl}'} + diff --git a/PY/腾讯视频.py b/PY/腾讯视频.py new file mode 100644 index 0000000..7a5218f --- /dev/null +++ b/PY/腾讯视频.py @@ -0,0 +1,323 @@ +# -*- coding: utf-8 -*- +# by @嗷呜 +import json +import sys +import uuid +import copy +sys.path.append('..') +from base.spider import Spider +from concurrent.futures import ThreadPoolExecutor, as_completed + + +class Spider(Spider): + + def init(self, extend=""): + self.dbody = { + "page_params": { + "channel_id": "", + "filter_params": "sort=75", + "page_type": "channel_operation", + "page_id": "channel_list_second_page" + } + } + self.body = self.dbody + pass + + def getName(self): + pass + + def isVideoFormat(self, url): + pass + + def manualVideoCheck(self): + pass + + def destroy(self): + pass + + host = 'https://v.qq.com' + + apihost = 'https://pbaccess.video.qq.com' + + headers = { + 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.5410.0 Safari/537.36', + 'origin': host, + 'referer': f'{host}/' + } + + def homeContent(self, filter): + cdata = { + "电视剧": "100113", + "电影": "100173", + "综艺": "100109", + "纪录片": "100105", + "动漫": "100119", + "少儿": "100150", + "短剧": "110755" + } + result = {} + classes = [] + filters = {} + for k in cdata: + classes.append({ + 'type_name': k, + 'type_id': cdata[k] + }) + with ThreadPoolExecutor(max_workers=len(classes)) as executor: + futures = [executor.submit(self.get_filter_data, item['type_id']) for item in classes] + for future in futures: + cid, data = future.result() + if not data.get('data', {}).get('module_list_datas'): + continue + filter_dict = {} + try: + items = data['data']['module_list_datas'][-1]['module_datas'][-1]['item_data_lists']['item_datas'] + for item in items: + if not item.get('item_params', {}).get('index_item_key'): + continue + params = item['item_params'] + filter_key = params['index_item_key'] + if filter_key not in filter_dict: + filter_dict[filter_key] = { + 'key': filter_key, + 'name': params['index_name'], + 'value': [] + } + filter_dict[filter_key]['value'].append({ + 'n': params['option_name'], + 'v': params['option_value'] + }) + except (IndexError, KeyError): + continue + filters[cid] = list(filter_dict.values()) + result['class'] = classes + result['filters'] = filters + return result + + def homeVideoContent(self): + json_data = {'page_context':None,'page_params':{'page_id':'100101','page_type':'channel','skip_privacy_types':'0','support_click_scan':'1','new_mark_label_enabled':'1','ams_cookies':'',},'page_bypass_params':{'params':{'caller_id':'','data_mode':'default','page_id':'','page_type':'channel','platform_id':'2','user_mode':'default',},'scene':'channel','abtest_bypass_id':'',}} + data = self.post(f'{self.apihost}/trpc.vector_layout.page_view.PageService/getPage',headers=self.headers, json=json_data).json() + vlist = [] + for it in data['data']['CardList'][0]['children_list']['list']['cards']: + if it.get('params'): + p = it['params'] + tag = json.loads(p.get('uni_imgtag', '{}') or p.get('imgtag', '{}') or '{}') + id = it.get('id') or p.get('cid') + name = p.get('mz_title') or p.get('title') + if name and 'http' not in id: + vlist.append({ + 'vod_id': id, + 'vod_name': name, + 'vod_pic': p.get('image_url'), + 'vod_year': tag.get('tag_2', {}).get('text'), + 'vod_remarks': tag.get('tag_4', {}).get('text') + }) + return {'list': vlist} + + def categoryContent(self, tid, pg, filter, extend): + result = {} + params = { + "sort": extend.get('sort', '75'), + "attr": extend.get('attr', '-1'), + "itype": extend.get('itype', '-1'), + "ipay": extend.get('ipay', '-1'), + "iarea": extend.get('iarea', '-1'), + "iyear": extend.get('iyear', '-1'), + "theater": extend.get('theater', '-1'), + "award": extend.get('award', '-1'), + "recommend": extend.get('recommend', '-1') + } + if pg == '1': + self.body = self.dbody.copy() + self.body['page_params']['channel_id'] = tid + self.body['page_params']['filter_params'] = self.josn_to_params(params) + data = self.post( + f'{self.apihost}/trpc.universal_backend_service.page_server_rpc.PageServer/GetPageData?video_appid=1000005&vplatform=2&vversion_name=8.9.10&new_mark_label_enabled=1', + json=self.body, headers=self.headers).json() + ndata = data['data'] + if ndata['has_next_page']: + result['pagecount'] = 9999 + self.body['page_context'] = ndata['next_page_context'] + else: + result['pagecount'] = int(pg) + vlist = [] + for its in ndata['module_list_datas'][-1]['module_datas'][-1]['item_data_lists']['item_datas']: + id = its.get('item_params', {}).get('cid') + if id: + p = its['item_params'] + tag = json.loads(p.get('uni_imgtag', '{}') or p.get('imgtag', '{}') or '{}') + name = p.get('mz_title') or p.get('title') + pic = p.get('new_pic_hz') or p.get('new_pic_vt') + vlist.append({ + 'vod_id': id, + 'vod_name': name, + 'vod_pic': pic, + 'vod_year': tag.get('tag_2', {}).get('text'), + 'vod_remarks': tag.get('tag_4', {}).get('text') + }) + result['list'] = vlist + result['page'] = pg + result['limit'] = 90 + result['total'] = 999999 + return result + + def detailContent(self, ids): + vbody = {"page_params":{"req_from":"web","cid":ids[0],"vid":"","lid":"","page_type":"detail_operation","page_id":"detail_page_introduction"},"has_cache":1} + body = {"page_params":{"req_from":"web_vsite","page_id":"vsite_episode_list","page_type":"detail_operation","id_type":"1","page_size":"","cid":ids[0],"vid":"","lid":"","page_num":"","page_context":"","detail_page_type":"1"},"has_cache":1} + with ThreadPoolExecutor(max_workers=2) as executor: + future_detail = executor.submit(self.get_vdata, vbody) + future_episodes = executor.submit(self.get_vdata, body) + vdata = future_detail.result() + data = future_episodes.result() + + pdata = self.process_tabs(data, body, ids) + if not pdata: + return self.handle_exception(None, "No pdata available") + + try: + star_list = vdata['data']['module_list_datas'][0]['module_datas'][0]['item_data_lists']['item_datas'][ + 0].get('sub_items', {}).get('star_list', {}).get('item_datas', []) + actors = [star['item_params']['name'] for star in star_list] + names = ['腾讯视频', '预告片'] + plist, ylist = self.process_pdata(pdata, ids) + if not plist: + del names[0] + if not ylist: + del names[1] + vod = self.build_vod(vdata, actors, plist, ylist, names) + return {'list': [vod]} + except Exception as e: + return self.handle_exception(e, "Error processing detail") + + def searchContent(self, key, quick, pg="1"): + headers = self.headers.copy() + headers.update({'Content-Type': 'application/json'}) + body = {'version':'25021101','clientType':1,'filterValue':'','uuid':str(uuid.uuid4()),'retry':0,'query':key,'pagenum':int(pg)-1,'pagesize':30,'queryFrom':0,'searchDatakey':'','transInfo':'','isneedQc':True,'preQid':'','adClientInfo':'','extraInfo':{'isNewMarkLabel':'1','multi_terminal_pc':'1','themeType':'1',},} + data = self.post(f'{self.apihost}/trpc.videosearch.mobile_search.MultiTerminalSearch/MbSearch?vplatform=2', + json=body, headers=headers).json() + vlist = [] + vname=["电视剧", "电影", "综艺", "纪录片", "动漫", "少儿", "短剧"] + v=data['data']['normalList']['itemList'] + d=data['data']['areaBoxList'][0]['itemList'] + q=v+d + if v[0].get('doc') and v[0]['doc'].get('id') =='MainNeed':q=d+v + for k in q: + if k.get('doc') and k.get('videoInfo') and k['doc'].get('id') and '外站' not in k['videoInfo'].get('subTitle') and k['videoInfo'].get('title') and k['videoInfo'].get('typeName') in vname: + img_tag = k.get('videoInfo', {}).get('imgTag') + if img_tag is not None and isinstance(img_tag, str): + try: + tag = json.loads(img_tag) + except json.JSONDecodeError as e: + tag = {} + else: + tag = {} + pic = k.get('videoInfo', {}).get('imgUrl') + vlist.append({ + 'vod_id': k['doc']['id'], + 'vod_name': self.removeHtmlTags(k['videoInfo']['title']), + 'vod_pic': pic, + 'vod_year': k['videoInfo'].get('typeName') +' '+ tag.get('tag_2', {}).get('text', ''), + 'vod_remarks': tag.get('tag_4', {}).get('text', '') + }) + return {'list': vlist, 'page': pg} + + def playerContent(self, flag, id, vipFlags): + ids = id.split('@') + url = f"{self.host}/x/cover/{ids[0]}/{ids[1]}.html" + return {'jx':1,'parse': 1, 'url': url, 'header': ''} + + def localProxy(self, param): + pass + + def get_filter_data(self, cid): + hbody = self.dbody.copy() + hbody['page_params']['channel_id'] = cid + data = self.post( + f'{self.apihost}/trpc.universal_backend_service.page_server_rpc.PageServer/GetPageData?video_appid=1000005&vplatform=2&vversion_name=8.9.10&new_mark_label_enabled=1', + json=hbody, headers=self.headers).json() + return cid, data + + def get_vdata(self, body): + try: + vdata = self.post( + f'{self.apihost}/trpc.universal_backend_service.page_server_rpc.PageServer/GetPageData?video_appid=3000010&vplatform=2&vversion_name=8.2.96', + json=body, headers=self.headers + ).json() + return vdata + except Exception as e: + print(f"Error in get_vdata: {str(e)}") + return {'data': {'module_list_datas': []}} + + def process_pdata(self, pdata, ids): + plist = [] + ylist = [] + for k in pdata: + if k.get('item_id'): + pid = f"{k['item_params']['union_title']}${ids[0]}@{k['item_id']}" + if '预告' in k['item_params']['union_title']: + ylist.append(pid) + else: + plist.append(pid) + return plist, ylist + + def build_vod(self, vdata, actors, plist, ylist, names): + d = vdata['data']['module_list_datas'][0]['module_datas'][0]['item_data_lists']['item_datas'][0]['item_params'] + urls = [] + if plist: + urls.append('#'.join(plist)) + if ylist: + urls.append('#'.join(ylist)) + vod = { + 'type_name': d.get('sub_genre', ''), + 'vod_name': d.get('title', ''), + 'vod_year': d.get('year', ''), + 'vod_area': d.get('area_name', ''), + 'vod_remarks': d.get('holly_online_time', '') or d.get('hotval', ''), + 'vod_actor': ','.join(actors), + 'vod_content': d.get('cover_description', ''), + 'vod_play_from': '$$$'.join(names), + 'vod_play_url': '$$$'.join(urls) + } + return vod + + def handle_exception(self, e, message): + print(f"{message}: {str(e)}") + return {'list': [{'vod_play_from': '哎呀翻车啦', 'vod_play_url': '翻车啦#555'}]} + + def process_tabs(self, data, body, ids): + try: + pdata = data['data']['module_list_datas'][-1]['module_datas'][-1]['item_data_lists']['item_datas'] + tabs = data['data']['module_list_datas'][-1]['module_datas'][-1]['module_params'].get('tabs') + if tabs and len(json.loads(tabs)): + tabs = json.loads(tabs) + remaining_tabs = tabs[1:] + task_queue = [] + for tab in remaining_tabs: + nbody = copy.deepcopy(body) + nbody['page_params']['page_context'] = tab['page_context'] + task_queue.append(nbody) + with ThreadPoolExecutor(max_workers=10) as executor: + future_map = {executor.submit(self.get_vdata, task): idx for idx, task in enumerate(task_queue)} + results = [None] * len(task_queue) + for future in as_completed(future_map.keys()): + idx = future_map[future] + results[idx] = future.result() + for result in results: + if result: + page_data = result['data']['module_list_datas'][-1]['module_datas'][-1]['item_data_lists'][ + 'item_datas'] + pdata.extend(page_data) + return pdata + except Exception as e: + print(f"Error processing episodes: {str(e)}") + return [] + + def josn_to_params(self, params, skip_empty=False): + query = [] + for k, v in params.items(): + if skip_empty and not v: + continue + query.append(f"{k}={v}") + return "&".join(query) + + diff --git a/PY/芒果视频.py b/PY/芒果视频.py new file mode 100644 index 0000000..6ba8e34 --- /dev/null +++ b/PY/芒果视频.py @@ -0,0 +1,205 @@ +# -*- coding: utf-8 -*- +# by @嗷呜 +import sys +import time +from concurrent.futures import ThreadPoolExecutor, as_completed +sys.path.append('..') +from base.spider import Spider + +class Spider(Spider): + + def init(self, extend=""): + pass + + def getName(self): + pass + + def isVideoFormat(self, url): + pass + + def manualVideoCheck(self): + pass + + def destroy(self): + pass + + rhost='https://www.mgtv.com' + + host='https://pianku.api.mgtv.com' + + vhost='https://pcweb.api.mgtv.com' + + mhost='https://dc.bz.mgtv.com' + + shost='https://mobileso.bz.mgtv.com' + + headers = { + 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; ) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.6478.61 Chrome/126.0.6478.61 Not/A)Brand/8 Safari/537.36', + 'origin': rhost, + 'referer': f'{rhost}/' + } + + def homeContent(self, filter): + result = {} + cateManual = { + "电影": "3", + "电视剧": "2", + "综艺": "1", + "动画": "50", + "少儿": "10", + "纪录片": "51", + "教育": "115" + } + classes = [] + filters = {} + for k in cateManual: + classes.append({ + 'type_name': k, + 'type_id': cateManual[k] + }) + with ThreadPoolExecutor(max_workers=len(classes)) as executor: + results = executor.map(self.getf, classes) + for id, ft in results: + if len(ft):filters[id] = ft + result['class'] = classes + result['filters'] = filters + return result + + def homeVideoContent(self): + data=self.fetch(f'{self.mhost}/dynamic/v1/channel/index/0/0/0/1000000/0/0/17/1354?type=17&version=5.0&t={str(int(time.time()*1000))}&_support=10000000', headers=self.headers).json() + videoList = [] + for i in data['data']: + if i.get('DSLList') and len(i['DSLList']): + for j in i['DSLList']: + if j.get('data') and j['data'].get('items') and len(j['data']['items']): + for k in j['data']['items']: + videoList.append({ + 'vod_id': k["videoId"], + 'vod_name': k['videoName'], + 'vod_pic': k['img'], + 'vod_year': k.get('cornerTitle'), + 'vod_remarks': k.get('time') or k.get('desc'), + }) + return {'list':videoList} + + def categoryContent(self, tid, pg, filter, extend): + body={ + 'allowedRC': '1', + 'platform': 'pcweb', + 'channelId': tid, + 'pn': pg, + 'pc': '80', + 'hudong': '1', + '_support': '10000000' + } + body.update(extend) + data=self.fetch(f'{self.host}/rider/list/pcweb/v3', params=body, headers=self.headers).json() + videoList = [] + for i in data['data']['hitDocs']: + videoList.append({ + 'vod_id': i["playPartId"], + 'vod_name': i['title'], + 'vod_pic': i['img'], + 'vod_year': (i.get('rightCorner',{}) or {}).get('text') or i.get('year'), + 'vod_remarks': i['updateInfo'] + }) + result = {} + result['list'] = videoList + result['page'] = pg + result['pagecount'] = 9999 + result['limit'] = 90 + result['total'] = 999999 + return result + + def detailContent(self, ids): + vbody={'allowedRC': '1', 'vid': ids[0], 'type': 'b', '_support': '10000000'} + vdata=self.fetch(f'{self.vhost}/video/info', params=vbody, headers=self.headers).json() + d=vdata['data']['info']['detail'] + vod = { + 'vod_name': vdata['data']['info']['title'], + 'type_name': d.get('kind'), + 'vod_year': d.get('releaseTime'), + 'vod_area': d.get('area'), + 'vod_lang': d.get('language'), + 'vod_remarks': d.get('updateInfo'), + 'vod_actor': d.get('leader'), + 'vod_director': d.get('director'), + 'vod_content': d.get('story'), + 'vod_play_from': '芒果TV', + 'vod_play_url': '' + } + data,pdata=self.fetch_page_data('1', ids[0],True) + pagecount=data['data'].get('total_page') or 1 + if int(pagecount)>1: + pages = list(range(2, pagecount+1)) + page_results = {} + with ThreadPoolExecutor(max_workers=10) as executor: + future_to_page = { + executor.submit(self.fetch_page_data, page, ids[0]): page + for page in pages + } + for future in as_completed(future_to_page): + page = future_to_page[future] + try: + result = future.result() + page_results[page] = result + except Exception as e: + print(f"Error fetching page {page}: {e}") + for page in sorted(page_results.keys()): + pdata.extend(page_results[page]) + vod['vod_play_url'] = '#'.join(pdata) + return {'list':[vod]} + + def searchContent(self, key, quick, pg="1"): + data=self.fetch(f'{self.shost}/applet/search/v1?channelCode=mobile-wxap&q={key}&pn={pg}&pc=10&_support=10000000', headers=self.headers).json() + videoList = [] + for i in data['data']['contents']: + if i.get('data') and len(i['data']): + k = i['data'][0] + if k.get('vid') and k.get('img'): + try: + videoList.append({ + 'vod_id': k['vid'], + 'vod_name': k['title'], + 'vod_pic': k['img'], + 'vod_year': (i.get('rightTopCorner',{}) or {}).get('text') or i.get('year'), + 'vod_remarks': '/'.join(i.get('desc',[])), + }) + except: + print(k) + return {'list':videoList,'page':pg} + + def playerContent(self, flag, id, vipFlags): + id=f'{self.rhost}{id}' + return {'jx':1,'parse': 1, 'url': id, 'header': ''} + + def localProxy(self, param): + pass + + def getf(self, body): + params = { + 'allowedRC': '1', + 'channelId': body['type_id'], + 'platform': 'pcweb', + '_support': '10000000', + } + data = self.fetch(f'{self.host}/rider/config/channel/v1', params=params, headers=self.headers).json() + ft = [] + for i in data['data']['listItems']: + try: + value_array = [{"n": value['tagName'], "v": value['tagId']} for value in i['items'] if + value.get('tagName')] + ft.append({"key": i['eName'], "name": i['typeName'], "value": value_array}) + except: + print(i) + return body['type_id'], ft + + def fetch_page_data(self, page, id, b=False): + body = {'version': '5.5.35', 'video_id': id, 'page': page, 'size': '30', + 'platform': '4', 'src': 'mgtv', 'allowedRC': '1', '_support': '10000000'} + data = self.fetch(f'{self.vhost}/episode/list', params=body, headers=self.headers).json() + ldata = [f'{i["t3"]}${i["url"]}' for i in data['data']['list']] + if b: + return data, ldata + else: + return ldata diff --git a/PY/金牌影视.py b/PY/金牌影视.py new file mode 100644 index 0000000..815951a --- /dev/null +++ b/PY/金牌影视.py @@ -0,0 +1,225 @@ +# -*- coding: utf-8 -*- +# by @嗷呜 +import json +import sys +import threading +import uuid +import requests +sys.path.append('..') +from base.spider import Spider +import time +from Crypto.Hash import MD5, SHA1 + +class Spider(Spider): + ''' + 配置示例: + { + "key": "xxxx", + "name": "xxxx", + "type": 3, + "api": ".所在路径/金牌.py", + "searchable": 1, + "quickSearch": 1, + "filterable": 1, + "changeable": 1, + "ext": { + "site": "https://www.jiabaide.cn,域名2,域名3" + } + }, + ''' + def init(self, extend=""): + if extend: + hosts=json.loads(extend)['site'] + self.host = self.host_late(hosts) + pass + + def getName(self): + pass + + def isVideoFormat(self, url): + pass + + def manualVideoCheck(self): + pass + + def destroy(self): + pass + + def homeContent(self, filter): + cdata = self.fetch(f"{self.host}/api/mw-movie/anonymous/get/filer/type", headers=self.getheaders()).json() + fdata = self.fetch(f"{self.host}/api/mw-movie/anonymous/v1/get/filer/list", headers=self.getheaders()).json() + result = {} + classes = [] + filters={} + for k in cdata['data']: + classes.append({ + 'type_name': k['typeName'], + 'type_id': str(k['typeId']), + }) + sort_values = [{"n": "最近更新", "v": "2"},{"n": "人气高低", "v": "3"}, {"n": "评分高低", "v": "4"}] + for tid, d in fdata['data'].items(): + current_sort_values = sort_values.copy() + if tid == '1': + del current_sort_values[0] + filters[tid] = [ + {"key": "type", "name": "类型", + "value": [{"n": i["itemText"], "v": i["itemValue"]} for i in d["typeList"]]}, + + *([] if not d["plotList"] else [{"key": "v_class", "name": "剧情", + "value": [{"n": i["itemText"], "v": i["itemText"]} + for i in d["plotList"]]}]), + + {"key": "area", "name": "地区", + "value": [{"n": i["itemText"], "v": i["itemText"]} for i in d["districtList"]]}, + + {"key": "year", "name": "年份", + "value": [{"n": i["itemText"], "v": i["itemText"]} for i in d["yearList"]]}, + + {"key": "lang", "name": "语言", + "value": [{"n": i["itemText"], "v": i["itemText"]} for i in d["languageList"]]}, + + {"key": "sort", "name": "排序", "value": current_sort_values} + ] + result['class'] = classes + result['filters'] = filters + return result + + def homeVideoContent(self): + data1 = self.fetch(f"{self.host}/api/mw-movie/anonymous/v1/home/all/list", headers=self.getheaders()).json() + data2=self.fetch(f"{self.host}/api/mw-movie/anonymous/home/hotSearch",headers=self.getheaders()).json() + data=[] + for i in data1['data'].values(): + data.extend(i['list']) + data.extend(data2['data']) + vods=self.getvod(data) + return {'list':vods} + + def categoryContent(self, tid, pg, filter, extend): + + params = { + "area": extend.get('area', ''), + "filterStatus": "1", + "lang": extend.get('lang', ''), + "pageNum": pg, + "pageSize": "30", + "sort": extend.get('sort', '1'), + "sortBy": "1", + "type": extend.get('type', ''), + "type1": tid, + "v_class": extend.get('v_class', ''), + "year": extend.get('year', '') + } + data = self.fetch(f"{self.host}/api/mw-movie/anonymous/video/list?{self.js(params)}", headers=self.getheaders(params)).json() + result = {} + result['list'] = self.getvod(data['data']['list']) + result['page'] = pg + result['pagecount'] = 9999 + result['limit'] = 90 + result['total'] = 999999 + return result + + def detailContent(self, ids): + data=self.fetch(f"{self.host}/api/mw-movie/anonymous/video/detail?id={ids[0]}",headers=self.getheaders({'id':ids[0]})).json() + vod=self.getvod([data['data']])[0] + vod['vod_play_from']='金牌' + vod['vod_play_url'] = '#'.join( + f"{i['name'] if len(vod['episodelist']) > 1 else vod['vod_name']}${ids[0]}@@{i['nid']}" for i in + vod['episodelist']) + vod.pop('episodelist', None) + return {'list':[vod]} + + def searchContent(self, key, quick, pg="1"): + params = { + "keyword": key, + "pageNum": pg, + "pageSize": "8", + "sourceCode": "1" + } + data=self.fetch(f"{self.host}/api/mw-movie/anonymous/video/searchByWord?{self.js(params)}",headers=self.getheaders(params)).json() + vods=self.getvod(data['data']['result']['list']) + return {'list':vods,'page':pg} + + def playerContent(self, flag, id, vipFlags): + self.header = { + 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; ) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.6478.61 Chrome/126.0.6478.61 Not/A)Brand/8 Safari/537.36', + 'sec-ch-ua-platform': '"Windows"', + 'DNT': '1', + 'sec-ch-ua': '"Not/A)Brand";v="8", "Chromium";v="126", "Google Chrome";v="126"', + 'sec-ch-ua-mobile': '?0', + 'Origin': self.host, + 'Referer': f'{self.host}/' + } + ids=id.split('@@') + pdata = self.fetch(f"{self.host}/api/mw-movie/anonymous/v2/video/episode/url?clientType=1&id={ids[0]}&nid={ids[1]}",headers=self.getheaders({'clientType':'1','id': ids[0], 'nid': ids[1]})).json() + vlist=[] + for i in pdata['data']['list']:vlist.extend([i['resolutionName'],i['url']]) + return {'parse':0,'url':vlist,'header':self.header} + + def localProxy(self, param): + pass + + def host_late(self, url_list): + if isinstance(url_list, str): + urls = [u.strip() for u in url_list.split(',')] + else: + urls = url_list + if len(urls) <= 1: + return urls[0] if urls else '' + + results = {} + threads = [] + + def test_host(url): + try: + start_time = time.time() + response = requests.head(url, timeout=1.0, allow_redirects=False) + delay = (time.time() - start_time) * 1000 + results[url] = delay + except Exception as e: + results[url] = float('inf') + for url in urls: + t = threading.Thread(target=test_host, args=(url,)) + threads.append(t) + t.start() + for t in threads: + t.join() + return min(results.items(), key=lambda x: x[1])[0] + + def md5(self, sign_key): + md5_hash = MD5.new() + md5_hash.update(sign_key.encode('utf-8')) + md5_result = md5_hash.hexdigest() + return md5_result + + def js(self, param): + return '&'.join(f"{k}={v}" for k, v in param.items()) + + def getheaders(self, param=None): + if param is None:param = {} + t=str(int(time.time()*1000)) + param['key']='cb808529bae6b6be45ecfab29a4889bc' + param['t']=t + sha1_hash = SHA1.new() + sha1_hash.update(self.md5(self.js(param)).encode('utf-8')) + sign = sha1_hash.hexdigest() + deviceid = str(uuid.uuid4()) + headers = { + 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; ) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.6478.61 Chrome/126.0.6478.61 Not/A)Brand/8 Safari/537.36', + 'Accept': 'application/json, text/plain, */*', + 'sign': sign, + 't': t, + 'deviceid':deviceid + } + return headers + + def convert_field_name(self, field): + field = field.lower() + if field.startswith('vod') and len(field) > 3: + field = field.replace('vod', 'vod_') + if field.startswith('type') and len(field) > 4: + field = field.replace('type', 'type_') + return field + + def getvod(self, array): + return [{self.convert_field_name(k): v for k, v in item.items()} for item in array] + diff --git a/XBPQ/修罗影视.json b/XBPQ/修罗影视.json index 88d0f73..b94ea54 100644 --- a/XBPQ/修罗影视.json +++ b/XBPQ/修罗影视.json @@ -1,35 +1,15 @@ { - "站名": "修罗影视", - "请求头": "User-Agent@Mozilla/5.0 (Linux;; Android 12;; PEHM00 Build/SKQ1.210216.001;; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.108 Mobile Safari/537.36", - "编码": "UTF-8", - "图片代理": "0", - "直接播放": "0", - "主页url": "http://v.xlys.ltd.ua", - "分类url": "http://v.xlys.ltd.ua/s/{cateId}/{catePg}", - "分类": "动作$dongzuo#爱情$aiqing#喜剧$xiju#科幻$kehuan#恐怖$kongbu#战争$zhanzheng#武侠$wuxia#魔幻$mohuan#剧情$juqing#动画$donghua#惊悚$jingsong#灾难$zainan#悬疑$xuanyi#警匪$jingfei#文艺$wenyi#青春$qingchun#冒险$maoxian#犯罪$fanzui#纪录$jilu#古装$guzhuang#奇幻$qihuan#国语$guoyu#综艺$zongyi#历史$lishi#运动$yundong#原创压制$yuanchuang#美剧$meiju#韩剧$hanju#国产电视剧$guoju#日剧$riju#英剧$yingju#德剧$deju#俄剧$eju#巴剧$baju#加剧$jiaju#西剧$spanish#意大利剧$yidaliju#泰剧$taiju#港台剧$gangtaiju#法剧$faju#澳剧$aoju", - "数组": "card-link&&/h3>", - "标题": "&&<", + "数组": "card card-sm card-link&&", "图片": "src=\"&&\"", - "副标题": "red-fg\">&&<", + "标题": "mb-0 card-title text-truncate\">&&<", + "副标题": "start-0 text-red-fg\">&&", "链接": "href=\"&&\"", - "影片年代": "上映日期:&&

", - "影片地区": "地区:&&

", - "影片类型": "类型:&&

", - "状态": "豆瓣 :&&", - "导演": "导演:&&

", - "主演": "主演:&&", - "线路数组": "download-list\">&&", - "线路标题": "磁力", - "播放二次截取": "", - "播放数组": "&&", - "倒序": "0", - "播放列表": "", - "播放标题": ">&&<", - "播放链接": "", - "解析": "", - "跳转播放链接": "", - "跳转解析": "", - "搜索请求头": "User-Agent$MOBILE_UA", - "搜索url": "http://v.xlys.ltd.ua/search/{wd}/{pg}" + "简介": "剧情简介:&&\"", + "线路标题": "磁力+>&&<", + "播放数组": "download-list&&", + "播放列表": "", + "播放标题": "text-muted\">&&[不包含:网盘下载]", + "跳转播放链接": "href=\"&&\"", + "分类url": "https://v.xlys.ltd.ua/s/all/{catePg}?type={cateId};;d0", + "分类": "电影$0#电视剧$1" } \ No newline at end of file diff --git a/api.json b/api.json index 1b504ce..d51a876 100644 --- a/api.json +++ b/api.json @@ -14,7 +14,7 @@ "key": "预告", "name": "新片|预告", "type": 3, - "api": "csp_YGP", + "api": "csp_DouBan", "searchable": 0 }, { @@ -37,468 +37,370 @@ } }, { - "key": "影视配置", - "name": "影视|配置", + "key": "热播影视", + "name": "热播|影视", "type": 3, - "api": "csp_Wexconfig", - "searchable": 0, - "changeable": 0, - "indexs": 0, - "style": { - "type": "rect", - "ratio": 1.597 - }, - "jar": "./wex.jar" - }, - { - "key": "厂长弹幕", - "name": "厂长|弹幕", - "type": 3, - "api": "csp_Czzy", + "api": "csp_AppRJ", "searchable": 1, "quickSearch": 1, - "filterable": 1, + "filterable": 0, "ext": { - "danmu": true + "url": "http://v.rbotv.cn" } }, { - "key": "天天弹幕", - "name": "天天|弹幕", + "key": "天天影视", + "name": "天天|影视", "type": 3, - "api": "csp_TianTian", + "api": "csp_AppRJ", "searchable": 1, "quickSearch": 1, - "filterable": 1, - "playerType": 1, + "filterable": 0, "ext": { - "danmu": true, - "site": "aHR0cDovL3R0LnlzZHFqcy5jbg==" + "url": "http://tt.ysdqjs.cn" } }, { - "key": "热播弹幕", - "name": "热播|弹幕", + "key": "浪酷影视", + "name": "浪酷|影视", "type": 3, - "api": "csp_TianTian", + "api": "csp_AppRJ", "searchable": 1, "quickSearch": 1, - "filterable": 1, - "playerType": 1, + "filterable": 0, "ext": { - "danmu": true, - "site": "aHR0cDovL3YucmJvdHYuY24=" + "url": "http://v.lkuys.cn" } }, { - "key": "浪酷弹幕", - "name": "浪酷|弹幕", + "key": "菲儿影视", + "name": "菲菲|影视", "type": 3, - "api": "csp_TianTian", + "api": "csp_AppFerr", + "ext": "sHR2rlsfjI4L3t4RXQMkn/M3t4AXAKTrZj3tfhm1t/gMT3dOrHqIzUNqLUEOIDMvllTbX6e1hMhB2mfpOaCmHNOL1yBB3SmxNyqXlai90EIpdnwOOgCR9Z+YwCTj6ySjzJ2VBiH3eXeOGcavcNeVRA==" + }, + { + "key": "影探影视", + "name": "影探|影视", + "type": 3, + "api": "csp_AppYsV2", "searchable": 1, "quickSearch": 1, "filterable": 1, - "playerType": 1, + "ext": "http://cmsyt114.lyyytv.cn/api.php/app/" + }, + { + "key": "哔哩视频", + "name": "哔哩|视频", + "type": 3, + "api": "./py/哔哩视频.py", "ext": { - "danmu": true, - "site": "aHR0cDovL3YubGt1eXMuY24=" + "json": "http://127.0.0.1:9978/file/TVBox/bili_cookie.txt" } }, { - "key": "文才弹幕", - "name": "文才|弹幕", + "key": "腾讯视频", + "name": "腾讯|视频", "type": 3, - "api": "csp_Jpys", - "searchable": 1, - "quickSearch": 1, - "filterable": 1, - "ext": { - "danmu": true - } + "api": "./js/drpy2.min.js", + "ext": "./js/腾讯视频.js" }, { - "key": "哔哩弹幕", - "name": "哔哩|弹幕", + "key": "优酷视频", + "name": "优酷|视频", "type": 3, - "api": "csp_Bilimd", - "searchable": 1, - "quickSearch": 1, - "filterable": 1, - "style": { - "type": "rect", - "ratio": 1.597 - }, - "ext": { - "cookie": "http://127.0.0.1:9978/file/TVBox/bilibili.txt" - }, - "timeout": 10 + "api": "./js/drpy2.min.js", + "ext": "./js/优酷视频.js" + }, + { + "key": "芒果视频", + "name": "芒果|视频", + "type": 3, + "api": "./js/drpy2.min.js", + "ext": "./js/芒果视频.js" + }, + { + "key": "爱奇艺", + "name": "爱奇异|视频", + "type": 3, + "api": "./js/drpy2.min.js", + "ext": "./js/爱奇艺.js" + }, + { + "key": "三六零", + "name": "三六零|视频", + "type": 3, + "api": "csp_SP360" }, { "key": "哔哩合集", - "name": "哔哩合集|弹幕", + "name": "哔哩|合集", "type": 3, "api": "csp_Bili", "searchable": 1, - "quickSearch": 1, - "filterable": 1, + "quickSearch": 0, + "filterable": 0, + "changeable": 0, + "style": { + "type": "rect", + "ratio": 1.433 + }, + "ext": { + "json": "./json/哔哩合集.json", + "cookie": "http://127.0.0.1:9978/file/TVBox/bili_cookie.txt" + } + }, + { + "key": "西瓜视频", + "name": "西瓜|视频", + "type": 3, + "api": "csp_AmuXiguaV2", + "searchable": 1, + "quickSearch": 0, + "filterable": 0, + "changeable": 0, "style": { "type": "rect", "ratio": 1.597 - }, - "ext": { - "cookie": "http://127.0.0.1:9978/file/TVBox/bilibili.txt", - "json": "./JSON/哔哩合集.json" - }, - "timeout": 10 - }, - { - "key": "立播弹幕", - "name": "立播|弹幕", - "type": 3, - "api": "csp_Libvio", - "searchable": 1, - "filterable": 1, - "changeable": 1, - "ext": { - "token": "http://127.0.0.1:9978/file/TVBox/token.txt", - "cookie": "http://127.0.0.1:9978/file/TVBox/quark.txt", - "uc_cookie": "http://127.0.0.1:9978/file/TVBox/uc.txt", - "site": "https://www.libvio.cc", - "danmu": true } }, { - "key": "腾讯弹幕", - "name": "腾讯|弹幕", - "type": 3, - "api": "./JS/drpy2.min.js", - "ext": "./JS/腾讯弹幕.js" - }, - { - "key": "优酷弹幕", - "name": "优酷|弹幕", - "type": 3, - "api": "./JS/drpy2.min.js", - "ext": "./JS/优酷弹幕.js" - }, - { - "key": "芒果弹幕", - "name": "芒果|弹幕", - "type": 3, - "api": "./JS/drpy2.min.js", - "ext": "./JS/芒果弹幕.js" - }, - { - "key": "爱奇艺弹幕", - "name": "爱奇艺|弹幕", - "type": 3, - "api": "./JS/drpy2.min.js", - "ext": "./JS/爱奇艺弹幕.js" - }, - { - "key": "追剧弹幕", - "name": "追剧|弹幕", - "type": 3, - "api": "./JS/drpy2.min.js", - "ext": "./JS/追剧弹幕.js" - }, - { - "key": "三六零弹幕", - "name": "三六零|弹幕", - "type": 3, - "api": "csp_Sp360", - "searchable": 1, - "filterable": 1, - "changeable": 1, - "ext": { - "danmu": true - } - }, - { - "key": "机器人弹幕", - "name": "机器人|弹幕", - "type": 3, - "api": "csp_Ikanbot", - "searchable": 1, - "quickSearch": 1, - "filterable": 1, - "ext": { - "danmu": true - } - }, - { - "key": "小苹果弹幕", - "name": "小苹果|弹幕", - "type": 3, - "api": "csp_Xpg", - "searchable": 1, - "quickSearch": 1, - "filterable": 1, - "ext": { - "danmu": true - } - }, - { - "key": "玩偶弹幕", + "key": "玩偶哥哥", "name": "玩偶|4K弹幕", "type": 3, - "api": "csp_Wogg", + "api": "csp_PanWebShare", "searchable": 1, "quickSearch": 1, "filterable": 1, - "ext": { - "token": "http://127.0.0.1:9978/file/TVBox/token.txt", - "cookie": "http://127.0.0.1:9978/file/TVBox/quark.txt", - "uc_cookie": "http://127.0.0.1:9978/file/TVBox/uc.txt", - "wogg": true, - "danmu": true - } + "ext": "./json/wogg.json?" }, { - "key": "夸克欧歌弹幕", - "name": "欧哥|4K弹幕", - "type": 3, - "api": "csp_Wobg", - "searchable": 1, - "quickSearch": 1, - "filterable": 1, - "changeable": 1, - "ext": { - "token": "http://127.0.0.1:9978/file/TVBox/token.txt", - "cookie": "http://127.0.0.1:9978/file/TVBox/quark.txt", - "uc_cookie": "http://127.0.0.1:9978/file/TVBox/uc.txt", - "site": "https://ouge.banye.tech:7086", - "danmu": true - } - }, - { - "key": "夸克小米弹幕", - "name": "小米|4K弹幕", - "type": 3, - "api": "csp_Wobg", - "quickSearch": 1, - "changeable": 1, - "filterable": 1, - "ext": { - "token": "http://127.0.0.1:9978/file/TVBox/token.txt", - "cookie": "http://127.0.0.1:9978/file/TVBox/quark.txt", - "uc_cookie": "http://127.0.0.1:9978/file/TVBox/uc.txt", - "site": "https://xiaomi.banye.tech:7086", - "danmu": true - } - }, - { - "key": "夸克多多弹幕", - "name": "多多|4K弹幕", - "type": 3, - "api": "csp_Wobg", - "quickSearch": 1, - "changeable": 1, - "filterable": 1, - "ext": { - "token": "http://127.0.0.1:9978/file/TVBox/token.txt", - "cookie": "http://127.0.0.1:9978/file/TVBox/quark.txt", - "uc_cookie": "http://127.0.0.1:9978/file/TVBox/uc.txt", - "site": "https://duoduo.banye.tech:7086", - "danmu": true - } - }, - { - "key": "夸克蜡笔弹幕", - "name": "蜡笔|4K弹幕", - "type": 3, - "api": "csp_Wobg", - "quickSearch": 1, - "changeable": 1, - "filterable": 1, - "ext": { - "token": "http://127.0.0.1:9978/file/TVBox/token.txt", - "cookie": "http://127.0.0.1:9978/file/TVBox/quark.txt", - "uc_cookie": "http://127.0.0.1:9978/file/TVBox/uc.txt", - "site": "https://labi.banye.tech:7086", - "danmu": true - } - }, - { - "key": "夸克至臻弹幕", - "name": "至臻|4K弹幕", - "type": 3, - "api": "csp_Wobg", - "quickSearch": 1, - "changeable": 1, - "filterable": 1, - "ext": { - "token": "http://127.0.0.1:9978/file/TVBox/token.txt", - "cookie": "http://127.0.0.1:9978/file/TVBox/quark.txt", - "uc_cookie": "http://127.0.0.1:9978/file/TVBox/uc.txt", - "site": "https://zhizhen.banye.tech:7086", - "danmu": true - } - }, - { - "key": "夸克木偶弹幕", + "key": "木偶", "name": "木偶|4K弹幕", "type": 3, - "api": "csp_Wobg", + "api": "csp_PanWebShare", + "searchable": 1, "quickSearch": 1, - "changeable": 1, "filterable": 1, - "ext": { - "token": "http://127.0.0.1:9978/file/TVBox/token.txt", - "cookie": "http://127.0.0.1:9978/file/TVBox/quark.txt", - "uc_cookie": "http://127.0.0.1:9978/file/TVBox/uc.txt", - "site": "https://mogg.banye.tech:7086", - "danmu": true - } + "ext": "./json/mogg.json?" }, { - "key": "夸克六趣弹幕", - "name": "六趣|4K弹幕", + "key": "蜡笔", + "name": "蜡笔|4K弹幕", "type": 3, - "api": "csp_Wobg", + "api": "csp_PanWebShare", "searchable": 1, "quickSearch": 1, "filterable": 1, "changeable": 1, - "ext": { - "token": "http://127.0.0.1:9978/file/TVBox/token.txt", - "cookie": "http://127.0.0.1:9978/file/TVBox/quark.txt", - "uc_cookie": "http://127.0.0.1:9978/file/TVBox/uc.txt", - "site": "https://liuqu.banye.tech:7086", - "danmu": true - } + "ext": "./json/lb.json?" }, { - "key": "夸克下饭弹幕", - "name": "下饭|4K弹幕", + "key": "小米", + "name": "小米|4K弹幕", "type": 3, - "api": "csp_Wobg", + "api": "csp_PanWebShare", + "searchable": 1, "quickSearch": 1, - "changeable": 1, "filterable": 1, - "ext": { - "token": "http://127.0.0.1:9978/file/TVBox/token.txt", - "cookie": "http://127.0.0.1:9978/file/TVBox/quark.txt", - "uc_cookie": "http://127.0.0.1:9978/file/TVBox/uc.txt", - "site": "https://xiafan.banye.tech:7086", - "danmu": true - } + "changeable": 1, + "ext": "./json/xm.json?" }, { - "key": "夸克二小弹幕", + "key": "至臻", + "name": "至臻|4K弹幕", + "type": 3, + "api": "csp_PanWebShare", + "searchable": 1, + "quickSearch": 1, + "filterable": 1, + "changeable": 1, + "ext": "./json/zz.json?" + }, + { + "key": "多多", + "name": "多多|4K弹幕", + "type": 3, + "api": "csp_PanWebShare", + "searchable": 1, + "quickSearch": 1, + "filterable": 1, + "changeable": 1, + "ext": "./json/yyds.json?" + }, + { + "key": "欧哥", + "name": "欧哥|4K弹幕", + "type": 3, + "api": "csp_PanWebShare", + "searchable": 1, + "quickSearch": 1, + "filterable": 1, + "changeable": 1, + "ext": "./json/og.json?" + }, + { + "key": "二小", "name": "二小|4K弹幕", "type": 3, - "api": "csp_Wobg", + "api": "csp_PanWebShare", + "searchable": 1, "quickSearch": 1, - "changeable": 1, "filterable": 1, - "ext": { - "token": "http://127.0.0.1:9978/file/TVBox/token.txt", - "cookie": "http://127.0.0.1:9978/file/TVBox/quark.txt", - "uc_cookie": "http://127.0.0.1:9978/file/TVBox/uc.txt", - "site": "https://erxiao.banye.tech:7086", - "danmu": true - } + "changeable": 1, + "ext": "./json/ex.json?" }, { - "key": "夸克百家弹幕", + "key": "百家", "name": "百家|4K弹幕", "type": 3, - "api": "csp_Wobg", + "api": "csp_PanWebShare", + "searchable": 1, "quickSearch": 1, - "changeable": 1, "filterable": 1, - "ext": { - "token": "http://127.0.0.1:9978/file/TVBox/token.txt", - "cookie": "http://127.0.0.1:9978/file/TVBox/quark.txt", - "uc_cookie": "http://127.0.0.1:9978/file/TVBox/uc.txt", - "site": "http://cj.jiexi.news", - "danmu": true - } + "changeable": 1, + "ext": "./json/bj.json?" }, { - "key": "夸克叔叔弹幕", - "name": "叔叔|4K弹幕", - "type": 3, - "api": "csp_Wobg", - "quickSearch": 1, - "changeable": 1, - "filterable": 1, - "ext": { - "token": "http://127.0.0.1:9978/file/TVBox/token.txt", - "cookie": "http://127.0.0.1:9978/file/TVBox/quark.txt", - "uc_cookie": "http://127.0.0.1:9978/file/TVBox/uc.txt", - "site": "https://woss.banye.tech:7086", - "danmu": true - } - }, - { - "key": "夸克大玩弹幕", + "key": "大玩", "name": "大玩|4K弹幕", "type": 3, - "api": "csp_Wobg", + "api": "csp_PanWebShare", + "searchable": 1, "quickSearch": 1, - "changeable": 1, "filterable": 1, - "ext": { - "token": "http://127.0.0.1:9978/file/TVBox/token.txt", - "cookie": "http://127.0.0.1:9978/file/TVBox/quark.txt", - "uc_cookie": "http://127.0.0.1:9978/file/TVBox/uc.txt", - "site": "https://dawo.banye.tech:7086", - "danmu": true - } + "changeable": 1, + "ext": "./json/dawo.json?" }, { - "key": "夸克虎斑弹幕", + "key": "虎斑", "name": "虎斑|4K弹幕", "type": 3, - "api": "csp_Wobg", + "api": "csp_PanWebShare", + "searchable": 1, "quickSearch": 1, - "changeable": 1, "filterable": 1, - "ext": { - "token": "http://127.0.0.1:9978/file/TVBox/token.txt", - "cookie": "http://127.0.0.1:9978/file/TVBox/quark.txt", - "uc_cookie": "http://127.0.0.1:9978/file/TVBox/uc.txt", - "site": "https://huban.banye.tech:7086", - "danmu": true - } + "changeable": 1, + "ext": "./json/hb.json?" + }, + { + "key": "闪电", + "name": "闪电|4K弹幕", + "type": 3, + "api": "csp_PanWebShare", + "searchable": 1, + "quickSearch": 1, + "filterable": 1, + "changeable": 1, + "ext": "./json/sd.json?" + }, + { + "key": "下饭", + "name": "下饭|4K弹幕", + "type": 3, + "api": "csp_PanWebShare", + "searchable": 1, + "quickSearch": 1, + "filterable": 1, + "changeable": 1, + "ext": "./json/xf.json?" + }, + { + "key": "团长", + "name": "团长|4K弹幕", + "type": 3, + "api": "csp_PanWebTz", + "searchable": 1, + "quickSearch": 1, + "filterable": 1, + "changeable": 1 }, { "key": "雷鲸", "name": "雷鲸|4K", "type": 3, - "api": "csp_Wexleijing", + "api": "csp_PanWebShareCloudLJ", "searchable": 1, + "quickSearch": 1, + "filterable": 1, "changeable": 1, - "jar": "./wex.jar" + "style": { + "type": "list", + "ratio": 1.433 + }, + "ext": "./json/lj.json?" }, { - "key": "天翼", - "name": "天翼|4K", + "key": "海绵", + "name": "海绵|4K", "type": 3, - "api": "csp_Wextyso", + "api": "csp_PanWebShareCloudHM", "searchable": 1, + "quickSearch": 1, + "filterable": 1, + "changeable": 1, + "style": { + "type": "list", + "ratio": 1.433 + }, + "ext": "./json/hm.json?" + }, + { + "key": "Pan1", + "name": "123|4K", + "type": 3, + "api": "csp_PanWebShareCloud123", + "searchable": 1, + "quickSearch": 1, + "filterable": 1, + "changeable": 1, + "style": { + "type": "list", + "ratio": 1.433 + }, + "ext": "./json/pan1.json?" + }, + { + "key": "趣盘", + "name": "趣盘|4K", + "type": 3, + "api": "csp_PanWebQu", + "searchable": 1, + "quickSearch": 1, + "filterable": 1, + "style": { + "type": "list", + "ratio": 1.433 + }, + "ext": { + "url": "https://www.qupanshe.com" + } + }, + { + "key": "聚搜", + "name": "聚搜|4K", + "type": 3, + "api": "csp_PanWebSearch", + "searchable": 1, + "quickSearch": 1, + "filterable": 1, + "style": { + "type": "list", + "ratio": 1.433 + }, + "ext": "./json/aliyunpansearch.json" + }, + { + "key": "盘库", + "name": "盘库|4K", + "type": 3, + "api": "csp_PanWebKuBa", + "searchable": 1, + "filterable": 0, "changeable": 0, - "jar": "./wex.jar" - }, - { - "key": "盘他", - "name": "盘他|4K‍", - "type": 3, - "api": "csp_WexYDpanta", - "searchable": 1, - "changeable": 1, - "jar": "./wex.jar" - }, - { - "key": "Emby", - "name": "Emby|4K", - "type": 3, - "api": "csp_Wexemby", - "searchable": 1, - "changeable": 1, - "jar": "./wex.jar" + "ext": { + "url": "https://panku8.com" + } }, { "key": "星芽短剧", @@ -516,14 +418,13 @@ "api": "csp_AppHMDJ", "searchable": 1, "quickSearch": 0, - "filterable": 0, - "ext": "KhY021WelCEl+6MsvwnzaPussky/EAoc9z7C4keyHaEQ+sKbXhMKd83VjTL7Ls6+m7XDIcGdziOxPv79y/h4QCvmOEJmZ1VD6dopzAVxkFzEFw==" + "filterable": 0 }, { "key": "爱看短剧", "name": "爱看|短剧", "type": 3, - "api": "./PY/爱看短剧.py", + "api": "./py/爱看短剧.py", "searchable": 1, "changeable": 1, "quickSearch": 1, @@ -764,7 +665,7 @@ "quickSearch": 1, "filterable": 1, "ext": "./XBPQ/剧白白.json" - }, + }, { "key": "红果短剧", "name": "红果|短剧", @@ -785,15 +686,6 @@ "filterable": 1, "ext": "./XYQHiker/短剧屋.json" }, - { - "key": "韩小圈", - "name": "韩小圈|APP", - "type": 3, - "api": "csp_HanXiaoQuan", - "searchable": 1, - "quickSearch": 1, - "filterable": 1 - }, { "key": "HG影视", "name": "HG影视|APP", @@ -804,11 +696,24 @@ "filterable": 1, "ext": "https://cs.hgyx.vip/api2/api.php/app/" }, + { + "key": "金牌影视", + "name": "金牌|影视", + "type": 3, + "api": "./py/金牌影视.py", + "searchable": 1, + "quickSearch": 1, + "filterable": 1, + "playerType": 2, + "ext": { + "site": "https://www.hkybqufgh.com,https://www.sizhengxt.com,https://0996zp.com,https://9zhoukj.com/,https://www.sizhengxt.com,https://www.tjrongze.com,https://www.jiabaide.cn,https://cqzuoer.com" + } + }, { "key": "猎手影视", "name": "猎手|APP", "type": 3, - "api": "./PY/猎手影视.py", + "api": "./py/猎手影视.py", "searchable": 1, "changeable": 1, "quickSearch": 1, @@ -819,7 +724,7 @@ "key": "火车影视", "name": "火车|APP", "type": 3, - "api": "./PY/火车影视.py", + "api": "./py/火车影视.py", "searchable": 1, "changeable": 1, "quickSearch": 1, @@ -830,7 +735,7 @@ "key": "美帕影视", "name": "美帕|APP", "type": 3, - "api": "./PY/美帕影视.py", + "api": "./py/美帕影视.py", "searchable": 1, "changeable": 1, "quickSearch": 1, @@ -841,7 +746,7 @@ "key": "嗨皮影视", "name": "嗨皮|APP", "type": 3, - "api": "./PY/嗨皮影视.py", + "api": "./py/嗨皮影视.py", "searchable": 1, "changeable": 1, "quickSearch": 1, @@ -862,7 +767,7 @@ "type": 3, "api": "csp_Shark", "playerType": 1, - "ext": "saHR0cDovL21pdG8ubWlub3R2LmNuL3xhYXNzZGR3d3h4bGxzeDF4fGJic3NxZGJic3NsbDI1c3g=" + "ext": "saHR0cDovL2Ntcy5taXRvdHYuY29tL3xhYXNzZGR3d3h4bGxzeDF4fGJic3NxZGJic3NsbDI1c3g=" }, { "key": "永夜", @@ -870,7 +775,7 @@ "type": 3, "api": "csp_Muou", "playerType": 2, - "ext": "caHR0cDovLzExMC40MC42NC4yMjU6ODk0NXxHOGt6QjF2WHdRcDlaN21GfEc4a3pCMXZYd1FwOVo3bUZ8MTAw" + "ext": "caHR0cHM6Ly9yeHlzeXlkcy5vc3MtY24tY2hlbmdkdS5hbGl5dW5jcy5jb20vZ2V0YXBwLnR4dHxlYmFkM2YxYTU4YjEzOTMzfGViYWQzZjFhNThiMTM5MzN8MTAw" }, { "key": "星河", @@ -878,15 +783,7 @@ "type": 3, "api": "csp_Muou", "playerType": 2, - "ext": "caHR0cDovL2EubXVxaXhoLnRvcDo1NjIzfOW5leWQr+aYn+ays3w0LjEuOA==" - }, - { - "key": "二三", - "name": "二三|APP", - "type": 3, - "api": "csp_Muou", - "playerType": 2, - "ext": "caHR0cHM6Ly8xMjN5c3cuY29tfDIz5b2x6KeGfDQuMS44" + "ext": "caHR0cDovL3Rlbmd4dW55dW5hbGl5dW4ub3NzLWNuLXNoYW5naGFpLmFsaXl1bmNzLmNvbS90ZW5neHVueXVuLnR4dHxmNWUydHg1M3lrcDZzMmM5fGY1ZTJ0eDUzeWtwNnMyYzl8MzYx" }, { "key": "油条", @@ -894,15 +791,79 @@ "type": 3, "api": "csp_Muou", "playerType": 2, - "ext": "caHR0cDovL2FwcC53dWlxLmNufOS8mOS8mOWFlHw0LjEuOA==" + "ext": "caHR0cDovLzU5LjE1My4xNjcuMTM3Ojg4OTl8NGQ4M2I4N2M0YzVlYTExMXw0ZDgzYjg3YzRjNWVhMTExfDQ2Mg==" }, { - "key": "龙虾", - "name": "龙虾|APP", + "key": "二三", + "name": "二三|App", + "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": "jaHR0cDovL3BweC5iangzNjUudG9wfHBpcGl4aWEyMTc1MjIzMjR8cGlwaXhpYTIxNzUyMjMyNHw1MDY=" + "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": "起点", @@ -942,7 +903,15 @@ "type": 3, "api": "csp_Xdai", "playerType": 1, - "ext": "jaHR0cDovLzExMS4xODAuMTk4LjQwOjExMTB8NDk0ODA4MDgwbGdneXNjb3w0OTQ4MDgwODBsZ2d5c2NvfDY2Ng==" + "ext": "jaHR0cDovLzU5LjE1My4xNjcuMTg2OjEwMDk5fFBNS2Faa0F2NFFwNTNFV258UE1LYVprQXY0UXA1M0VXbnw0MjU=" + }, + { + "key": "电影", + "name": "电影|APP", + "type": 3, + "api": "csp_Xdai", + "playerType": 1, + "ext": "jaHR0cHM6Ly9jOHcyb3Y3dTV3ZzJ6MW84cDIxYy5hbGl5dW5jcy5jbGljazoyNzg5OXxrOW8zcDJjOGI3bTN6MG84fGs5bzNwMmM4YjdtM3owbzh8MTAw" }, { "key": "奇妙", @@ -953,52 +922,36 @@ "ext": "jaHR0cDovLzE1NC4xMi45MS4yMTE6NjY4fDEyMzQ1Njc4OUFCQ0RFRkd8MTIzNDU2Nzg5QUJDREVGR3wxMDY=" }, { - "key": "时常", - "name": "时常|APP", + "key": "人人", + "name": "人人|APP", "type": 3, "api": "csp_Xdai", "playerType": 1, - "ext": "jaHR0cHM6Ly9zYzEwODAudG9wfGU1OWQ0NGIyZWVmMDNiYTJ8ZTU5ZDQ0YjJlZWYwM2JhMnwxMzQ=" + "ext": "jaHR0cHM6Ly9zdmlwMS5mdW58bGFvZGllc2Rhd3Nzd2FzZHxsYW9kaWVzZGF3c3N3YXNkfDI5OGU1ZmUyOWM3NGIzNWFhYmI5ODM2ZWUyZjZmNDQ5ZnwxMDU=" }, { - "key": "雨滴", - "name": "雨滴|APP", - "type": 3, - "api": "csp_Xdai", - "playerType": 1, - "ext": "jaHR0cHM6Ly95ZHlzZHluYW1pY2RvbWFpbm5hbWUuNjguZ3k6MTA2NzgvYzltMmpzMjk4eDgyaDYvbDltOGJ4MjNqMm8ycDlxL2R5bmFtaWNkb21haW5uYW1lLnR4dHxrOW8zcDJjOGI3bTN6MG84fGs5bzNwMmM4YjdtM3owbzh8MTAw" - }, - { - "key": "现代", - "name": "现代|APP", - "type": 3, - "api": "csp_Xdai", - "playerType": 1, - "ext": "caHR0cHM6Ly94ZHlzLnZpcC9nZXRhcHAudHh0fHN6ZGp3ZGFwcHdjbm1kaGJ8c3pkandkYXBwd2NubWRoYnwxMTQ=" - }, - { - "key": "玉米", - "name": "玉米|APP", - "type": 3, - "api": "csp_Xdai", - "playerType": 1, - "ext": "jaHR0cHM6Ly93d3cuempjLmFwcC98YWI0ZTlhNDIxNjc1ZjE0YnxhYjRlOWE0MjE2NzVmMTRifDQ0Mg==" - }, - { - "key": "优质", - "name": "优质|APP", - "type": 3, - "api": "csp_Xdai", - "playerType": 1, - "ext": "jaHR0cHM6Ly9keXl6dHZhcHBhcGlnb29kZ3guNjguZ3k6MTI2ODkvY2l3azI4dnUzOGlvOC9hcGl1cmwudHh0fGR5eXp0dmFwaWFwcHl5ZHN8ZHl5enR2YXBpYXBweXlkc3wxMDA=" - }, - { - "key": "木叶", - "name": "木叶|APP", + "key": "格格", + "name": "格格|APP", "type": 3, "api": "csp_Xdai", "playerType": 2, - "ext": "saHR0cDovLzExMy40NS4yNDMuMjMzL211eWUudHh0fFJ1TjlMUnZ3VFJncFFucEt8UnVOOUxSdndUUmdwUW5wS3w1NDc=" + "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": "蝴蝶", @@ -1019,36 +972,6 @@ "changeable": 1, "ext": "http://kkwk123.top/api.php/app/" }, - { - "key": "站长影视", - "name": "站长|APP", - "type": 3, - "api": "csp_AppGetApp", - "searchable": 1, - "quickSearch": 0, - "filterable": 0, - "ext": "w7TClcK8w5rDrcKYwoPCmcKkw57ClcK0wpvCnF9SwoPCmcOtw5jDj8Orw6ZValLCmMOtw6fDqsOswrRiX8KdacOcw57CrMKxw6DCqmbCnmPDpsKow6XCsMKywpRhYMKUwqfDl8Ozw7LDtGVewpPCn8Omwq3Cr8KvwrJsX8KRwqDDosKhw6rDocOqVVxSecOnw5zDrsOQw6nCpcKUUmrCm8KVwqbCm8OuwpzCoFJqwpvDjuWHv+mFoeaQn+WQllzlhpzkvYflkbDCreW/q+iov+i2vua7g+esicKNUsKlwpXCu8Oew61+wpXCqVLCs8KVw57DssOzwq3CpMKmwpHDqcOcw5vDqcOqwqzCqcKUwqPCm8KfwpzCusOfwqZ5wqZSwrPClcOew7LDs8KtwqTCpsKRw6nDnMObw6nDqsKswqnClMKjwpvDsA==" - }, - { - "key": "悠悠影视", - "name": "悠悠|APP", - "type": 3, - "api": "csp_AppGetApp", - "searchable": 1, - "quickSearch": 0, - "filterable": 0, - "ext": "w7TCmsK8w5rDrcKYwoPCmcKkw57CmsK0wpnCoVpcUFfDgsOhw6PDrcORwqLCosKUV8KzwpPCocOiw6jCnMKkwoZhwqrCrMKhwqXCmlrCpMKZwqDCoMKtwprCoMOV5Ya46YSY5o+V5ZCTwqXlh5/kvpHlkbDCtOW+pOintui1tOa7gOetksOQwqHCpcKaWnHClcKjw4TDmMOzwqDCtFNXdMKow7DCvMOtw63DrMKXwofCksKJw6nDlcOmw7DDqFpcUFfCusOYw63DgsOwWmpQV8K9w6vDscOCw63Cp8KiwpTCh8Obw4zDqsObw6bCqsKeV1zCmcKaw43DosOuwpjChcKiwpzCoMKtwprCoMOiwqfCpMKgasKowqLCq8KuwrBhYmJlwqfCpsKqwqfCsGhqZWXCr8KpwqnDmsOqwpxewqDCmMOpwprCpsKZwqHCl8KVwpPCosOyw6PDrsOEw5/CrFdqUMKgw6zDm8Oow7HClMKewpdgwqrCpcKwwqDDtw==" - }, - { - "key": "洽洽影视", - "name": "洽洽|APP", - "type": 3, - "api": "csp_AppGZ", - "searchable": 1, - "quickSearch": 1, - "filterable": 1, - "ext": "KhY021WelCEl+6MsvwnzaPussky6FQJcpCjT9V7/D61ft9vQAhNEPOYSMZVJSODd/JOOSOwUzim+9qfvgpNz7SvUPpAkXAweyrp76WY8s5EBwW7DBMY=" - }, { "key": "移动", "name": "移动|APP", @@ -1058,64 +981,80 @@ "quickSearch": 1 }, { - "key": "小米尘落", - "name": "尘落|APP", - "type": 3, - "api": "csp_Wetv", - "searchable": 1, - "quickSearch": 1 - }, - { - "key": "小米电影", - "name": "电影|APP", + "key": "厂长影视", + "name": "厂长|影视", "type": 3, + "playerType": "2", + "api": "csp_Czsapp", "searchable": 1, "quickSearch": 1, - "api": "csp_MovieApp" + "filterable": 1, + "ext": "https://www.czzymovie.com/" }, { - "key": "西瓜视频", - "name": "西瓜|视频", + "key": "糯米影视", + "name": "糯米┃影视", "type": 3, - "api": "csp_AmuXiguaV2", - "searchable": 1, - "quickSearch": 0, - "filterable": 0, - "changeable": 0, - "style": { - "type": "rect", - "ratio": 1.597 - } + "api": "csp_Wwys", + "ext": "https://www.wwgz.cn" }, { - "key": "采集之王", - "name": "采集|合集", + "key": "私人影视", + "name": "私人|影视", "type": 3, - "api": "./JS/drpy2.min.js", - "ext": "./JS/采集之王.js?type=url¶ms=../JSON/采集静态.json$1$1" + "api": "csp_Siren" }, { - "key": "爱看机器人", - "name": "爱看|影视", + "key": "云播影视", + "name": "云播|影视", "type": 3, - "api": "csp_IkanBot", + "api": "csp_Tvyb" + }, + { + "key": "奇优影视", + "name": "奇优|影视", + "type": 3, + "api": "csp_Qiyou" + }, + { + "key": "苹果影视", + "name": "苹果|影视", + "type": 3, + "api": "csp_LiteApple", "searchable": 1, "quickSearch": 1, "filterable": 1 }, { - "key": "农民影视", - "name": "农民|影视", + "key": "全网影视", + "name": "全看|影视", "type": 3, - "api": "csp_XBPQ", - "ext": "./XBPQ/农民影视.json" + "api": "csp_Quanwk", + "ext": "https://www.91qkw.com" }, { - "key": "秀儿影视", - "name": "秀儿|影视", + "key": "饺子影视", + "name": "饺子|影视", "type": 3, - "api": "csp_XBPQ", - "ext": "./XBPQ/秀儿影视.json" + "api": "csp_Jiaozi", + "playerType": 2 + }, + { + "key": "火火影视", + "name": "火火|影视", + "type": 3, + "api": "csp_SaoHuo", + "playerType": 2, + "ext": "https://shdy5.us" + }, + { + "key": "尘落影视", + "name": "尘落|影视", + "type": 3, + "api": "csp_Wetv", + "searchable": 1, + "quickSearch": 1, + "ext": "https://v.wetv.wang" }, { "key": "低端影视", @@ -1162,6 +1101,50 @@ "quickSearch": 1, "filterable": 1 }, + { + "key": "采集之王", + "name": "采集|合集", + "type": 3, + "api": "./js/drpy2.min.js", + "ext": "./js/采集之王.js?type=url¶ms=../json/采集静态.json$1$1" + }, + { + "key": "爱看机器人", + "name": "爱看|影视", + "type": 3, + "api": "csp_Ikanbot", + "searchable": 1, + "quickSearch": 1, + "filterable": 1 + }, + { + "key": "农民影视", + "name": "农民|影视", + "type": 3, + "api": "csp_XBPQ", + "ext": "./XBPQ/农民影视.json" + }, + { + "key": "秀儿影视", + "name": "秀儿|影视", + "type": 3, + "api": "csp_XBPQ", + "ext": "./XBPQ/秀儿影视.json" + }, + { + "key": "小枫影视", + "name": "小枫|影视", + "type": 3, + "api": "csp_XBPQ", + "ext": "./XBPQ/小枫影视.json" + }, + { + "key": "奇迹影视", + "name": "奇迹|影视", + "type": 3, + "api": "csp_XBPQ", + "ext": "./XBPQ/奇迹影视.json" + }, { "key": "可可影视", "name": "可可|影视", @@ -1205,14 +1188,14 @@ "ext": "./XBPQ/流光影视.json" }, { - "key": "金牌影视", - "name": "金牌|影视", + "key": "一起影视", + "name": "一起|影视", "type": 3, - "api": "csp_WebJP", + "api": "csp_AppFree4K", "searchable": 1, "quickSearch": 1, - "filterable": 1, - "ext": "KhY021WelCEl+6MsvwnzaPusskysEhxc/i3d/FHwReBTtZTeDEVZJbQKKez3K+OxlrjAIMdUpAUxP8fGystYn0Hss098UFVR69Qm2ARgmeZN86q8Ww==" + "filterable": 0, + "ext": "w7TCmsONw6LDrsKYwoXCosKcwqDCrcKawqDDosKnwqTCoMKjwrPCosKpw5rDqsKjwpPCncKjwqfDmcOsw57Dn8KbwpRewqbDosOjwqHCpcKaWnvClcKpwqDCrcKawqDDnMKYZWNkwrHDl8Ogw5vCqsKWY8KTYsKxwqbCocKlwppaecKmV8KzwpPCocKuw6BoZGRpw53Dl8Krwq3CrWRjYmHCsMKawqbCmcKhdcKRwp7Cm8OHw5TDsMKgwrRTV+ecpOaTncKgwp/CmsKgw4rClMKiwqPClcOOw6XDpsKgwrRTV8KYwqTDrcOjw63Cs8KpYsKRwqDCoMOvwqTCqMOfw6zCmMKVwpjClMKnw6nDo8OpwqnCncKjwp/CnsKnw6PDosOpwrnCqMKiwpxtwqDCn8KawqDCvsKUwp59wqXDjsOlw6bCoMK0U1fCmMKkw63Do8OtwrPCqWLClMKdXsOvw5zDnsOzwqjClMKjwpnCkcKow5fDp8Okw69ib8KRwpPCtsOXw6fCn8OuwqLCm8KVwp7CtsOEw4PDhcK8dnh6dsOMwr/DkcOPw4B4e8KCVsOuw6XDpsK2wqFfUFfClMOew5bDrMOyw6rCp3vClcKpwqDCrcKawqDDscKowqnCmWbCr8KpwqHDtg==" }, { "key": "耐看影视", @@ -1237,22 +1220,29 @@ "key": "思古影视", "name": "思古|影视", "type": 3, - "api": "./JS/drpy2.min.js", - "ext": "./JS/思古影视.js" + "api": "./js/drpy2.min.js", + "ext": "./js/思古影视.js" + }, + { + "key": "追剧影视", + "name": "追剧|影视", + "type": 3, + "api": "./js/drpy2.min.js", + "ext": "./js/追剧视频.js" }, { "key": "魔力高清", "name": "魔力|影视", "type": 3, - "api": "./JS/drpy2.min.js", - "ext": "./JS/魔力高清.js" + "api": "./js/drpy2.min.js", + "ext": "./js/魔力高清.js" }, { "key": "碟调影视", "name": "碟调|影视", "type": 3, - "api": "./JS/drpy2.min.js", - "ext": "./JS/碟调影视.js" + "api": "./js/drpy2.min.js", + "ext": "./js/碟调影视.js" }, { "key": "八号影视", @@ -1324,33 +1314,26 @@ "filterable": 1, "ext": "./XYQHiker/电影牛.json" }, - { - "key": "素白白", - "name": "素白白|影视", - "type": 3, - "api": "./JS/drpy2.min.js", - "ext": "./JS/素白白.js" - }, { "key": "剧圈圈", "name": "剧圈圈|影视", "type": 3, - "api": "./JS/drpy2.min.js", - "ext": "./JS/剧圈圈.js" + "api": "./js/drpy2.min.js", + "ext": "./js/剧圈圈.js" }, { "key": "看了么", "name": "看了么|影视", "type": 3, - "api": "./JS/drpy2.min.js", - "ext": "./JS/看了么.js" + "api": "./js/drpy2.min.js", + "ext": "./js/看了么.js" }, { "key": "茶杯狐", "name": "茶杯狐|影视JS", "type": 3, - "api": "./JS/drpy2.min.js", - "ext": "./JS/茶杯狐.js" + "api": "./js/drpy2.min.js", + "ext": "./js/茶杯狐.js" }, { "key": "1905", @@ -1604,52 +1587,42 @@ "key": "56动漫", "name": "56|动漫", "type": 3, - "api": "./JS/drpy2.min.js", - "ext": "./JS/56动漫.js" + "api": "./js/drpy2.min.js", + "ext": "./js/56动漫.js" }, { "key": "NT动漫", "name": "NT|动漫", "type": 3, - "api": "./JS/drpy2.min.js", - "ext": "./JS/NT动漫.js" + "api": "./js/drpy2.min.js", + "ext": "./js/NT动漫.js" }, { "key": "Anime1", "name": "Anime1|动漫", "type": 3, - "api": "./JS/drpy2.min.js", - "ext": "./JS/Anime1.js" - }, - { - "key": "DFun动漫", - "name": "DFun|动漫", - "type": 3, - "api": "csp_AppGetApp", - "searchable": 1, - "quickSearch": 0, - "filterable": 0, - "ext": "w7TClcK8w5rDrcKYwoPCmcKkw57ClcK0wpvDosKnwqTCoMKjwrPCosKpw6PDsmFlZsKlw7HDnMKow5zDqcKgX8Kpwp3Cp8Onw7LDrcKcX1LCg8KZw63DmMOPw6vDplVqUlLCpcKVw67DosOqVWpSwovlh77phZvmkJ/lkZzCpuWGn+S9h+WQp2rlv6roqLnotr7mvInnrZPCkFJcUsK6w5jDrcOEw5/CrFJqUsOsw5TCr8Odwq7CpmXCkWbCrcOXwq/DqsOxaWFSXMKbwrTDn8Osw4PCqVJqUsOsw5TCr8Odwq7CpmXCkWbCrcOXwq/DqsOxaWFSwq0=" + "api": "./js/drpy2.min.js", + "ext": "./js/Anime1.js" }, { "key": "曼波动漫", "name": "曼波|动漫", "type": 3, - "api": "csp_AppGetApp", + "api": "csp_Xdai", "searchable": 1, "quickSearch": 0, "filterable": 0, - "ext": "w7TClcK8w5rDrcKYwoPCmcKkw57ClcK0wpvCnF9SwoPCmcOtw5jDj8Orw6ZValLCmMOtw6fDqsOswrRiX8KRwqDDqcKhw6nDpsOpwpnCpcKeYcKnw6fDqcOpwqnClMKgwplew6nDm8OqwpvCplXCpMKZwqDCm8KtwpzDlOWHv+mEm+aPleWQk1zlh6XkvorlkbHCs+W/q+inuei1tOa7gOesicOWwpXCpsKbwrvCmMKje8KVw7LClcK0wpvCsGnClMKTY8KpwqzDncObw5/CmMKTwpFkwq7Cp8KcwqXCnHTClcKjecOvwpXCtMKbwrBpwpTCk2PCqcKsw53Dm8OfwpjCk8KRZMKuwqfCnMO2" + "ext": "jaHR0cHM6Ly9hcHAub21vZnVuMS50b3AvYXBpLnBocHw2NmRjMzA5Y2JlZWNhNDU0fDY2ZGMzMDljYmVlY2E0NTR8MTAw" }, { "key": "稀饭动漫", "name": "稀饭|动漫", "type": 3, - "api": "csp_AppGetApp", + "api": "csp_Xdai", "searchable": 1, "quickSearch": 0, "filterable": 0, - "ext": "w7TClcK8w5rDrcKYwoPCmcKkw57ClcK0wpvDosKnwqTCoMKjwrPCosKpw7HDoMKUwqDCoF3CqsKmwqrCrsKtbGBgZsKuwqHDncOow61hwpHCoF3DoMOow5vDp8Ohwq3CmMKfwqXCp8Ogw7PDqsOdwp/Cn8KlwpTCp8OWw6nDpsKpwprClcKkwpHDqcOjwqjDrcOywqdSXFLDgsOhw6PDrcORwqLCosKUUsKzwpXCnMKlwpzCp8KZwqBSwrPClcOV5Ye+6YWi5o+Y5ZCTXOWGnOS+kOWRqsK05b+q6KmA6LW35ruA56yJwo3Cm8KfwpzCusOfwqZ7wpXCqcKbwq3CnMKqw7PCjWLCg8Kgw6fCrMOlw6vDqMKtwoZ7wp/CvMKVwqbCm8K7wpjCo3nCpsKbwq3CnMKqw7PCjWLCg8Kgw6fCrMOlw6vDqMKtwoZ7wp/CvMKVwqbCm8ONwpzCpMKVwoXDq8OfwpzCs8KcVcKt" + "ext": "jaHR0cHM6Ly94ZmFwcC0xMzA1MzkwMDY1LmNvcy5hcC1ndWFuZ3pob3UubXlxY2xvdWQuY29tL2dldGFwcC50eHR8MXlaMlNwbjlrcm56VktvQ3wxeVoyU3BuOWtybnpWS29DfDEwMA==" }, { "key": "咕咕动漫", @@ -1663,192 +1636,93 @@ "key": "动画片", "name": "动画片|动漫", "type": 3, - "api": "./JS/drpy2.min.js", - "ext": "./JS/动画片大全.js" + "api": "./js/drpy2.min.js", + "ext": "./js/动画片大全.js" }, { "key": "路漫漫", "name": "路漫漫|动漫", "type": 3, - "api": "./JS/drpy2.min.js", - "ext": "./JS/路漫漫.js" + "api": "./js/drpy2.min.js", + "ext": "./js/路漫漫.js" }, { "key": "动漫岛", "name": "动漫岛|动漫", "type": 3, - "api": "./JS/drpy2.min.js", - "ext": "./JS/动漫岛.js" + "api": "./js/drpy2.min.js", + "ext": "./js/动漫岛.js" }, { "key": "去看吧", "name": "去看吧|动漫", "type": 3, - "api": "./JS/drpy2.min.js", - "ext": "./JS/去看吧.js" + "api": "./js/drpy2.min.js", + "ext": "./js/去看吧.js" }, { "key": "爱弹幕", "name": "爱弹幕|动漫", "type": 3, - "api": "./JS/drpy2.min.js", - "ext": "./JS/爱弹幕.js" + "api": "./js/drpy2.min.js", + "ext": "./js/爱弹幕.js" }, { "key": "异世界", "name": "异世界|动漫", "type": 3, - "api": "./JS/drpy2.min.js", - "ext": "./JS/异世界.js" + "api": "./js/drpy2.min.js", + "ext": "./js/异世界.js" }, { "key": "好看动漫", "name": "好看|动漫", "type": 3, - "api": "./JS/drpy2.min.js", - "ext": "./JS/好看动漫.js" + "api": "./js/drpy2.min.js", + "ext": "./js/好看动漫.js" }, { "key": "奇米动漫", "name": "奇米|动漫", "type": 3, - "api": "./JS/drpy2.min.js", - "ext": "./JS/奇米动漫.js" + "api": "./js/drpy2.min.js", + "ext": "./js/奇米动漫.js" }, { "key": "怡萱动漫", "name": "怡萱|动漫", "type": 3, - "api": "./JS/drpy2.min.js", - "ext": "./JS/怡萱动漫.js" + "api": "./js/drpy2.min.js", + "ext": "./js/怡萱动漫.js" }, { "key": "花子动漫", "name": "花子|动漫", "type": 3, - "api": "./JS/drpy2.min.js", - "ext": "./JS/花子动漫.js" + "api": "./js/drpy2.min.js", + "ext": "./js/花子动漫.js" }, { "key": "动漫巴士", "name": "巴士|动漫", "type": 3, - "api": "./JS/drpy2.min.js", - "ext": "./JS/动漫巴士.js" + "api": "./js/drpy2.min.js", + "ext": "./js/动漫巴士.js" }, { "key": "樱花动漫", "name": "樱花|动漫", "type": 3, - "api": "./JS/drpy2.min.js", - "ext": "./JS/樱花动漫.js" - }, - { - "key": "搜索弹幕", - "name": "搜索|弹幕", - "type": 3, - "api": "csp_PanSearch", - "searchable": 1, - "filterable": 0, - "changeable": 1, - "ext": { - "token": "http://127.0.0.1:9978/file/TVBox/token.txt", - "danmu": true - } - }, - { - "key": "易搜弹幕", - "name": "易搜|弹幕", - "type": 3, - "api": "csp_YiSo", - "searchable": 1, - "filterable": 0, - "changeable": 1, - "ext": { - "token": "http://127.0.0.1:9978/file/TVBox/token.txt", - "danmu": true, - "cookie": "satoken=0eedba28-be8a-4f01-81af-2d8d44808ecf" - } - }, - { - "key": "云盘弹幕", - "name": "云盘|弹幕", - "type": 3, - "api": "csp_Yunpan4k", - "searchable": 1, - "filterable": 0, - "changeable": 1, - "ext": { - "token": "http://127.0.0.1:9978/file/TVBox/token.txt", - "cookie": "http://127.0.0.1:9978/file/TVBox/quark.txt", - "danmu": true - } - }, - { - "key": "夸搜弹幕", - "name": "夸搜|弹幕", - "type": 3, - "api": "csp_Qkso", - "searchable": 1, - "filterable": 1, - "changeable": 0, - "ext": { - "cookie": "http://127.0.0.1:9978/file/TVBox/quark.txt", - "danmu": true - } - }, - { - "key": "小纸条弹幕", - "name": "小纸条|弹幕", - "type": 3, - "api": "csp_XiaoZhiTiao", - "searchable": 1, - "filterable": 1, - "changeable": 0, - "ext": { - "token": "http://127.0.0.1:9978/file/TVBox/token.txt", - "danmu": true - } - }, - { - "key": "夸克趣盘搜弹幕", - "name": "趣盘搜|弹幕", - "type": 3, - "api": "csp_QuPanSou", - "searchable": 1, - "quickSearch": 1, - "filterable": 1, - "changeable": 1, - "ext": { - "cookie": "http://127.0.0.1:9978/file/TVBox/quark.txt", - "danmu": true - } - }, - { - "key": "夸克短剧弹幕", - "name": "夸克短剧|弹幕", - "type": 3, - "api": "csp_Qkdj", - "searchable": 1, - "filterable": 1, - "changeable": 0, - "ext": { - "cookie": "http://127.0.0.1:9978/file/TVBox/quark.txt", - "danmu": true - } + "api": "./js/drpy2.min.js", + "ext": "./js/樱花动漫.js" }, { "key": "荐片", "name": "荐片|磁力", - "type": 3, "api": "csp_Jianpian", - "searchable": 1, - "quickSearch": 1, - "filterable": 1, + "type": 3, "playerType": 1, - "ext": { - "danmu": true - } + "ext": "http://api2.rinhome.com" }, { "key": "修罗影视", @@ -2042,7 +1916,7 @@ "quickSearch": 1, "filterable": 1, "ext": "./XBPQ/18R/好好J.json" - }, + }, { "key": "花丛视频", "name": "花丛|成人", @@ -2052,7 +1926,7 @@ "quickSearch": 1, "filterable": 1, "ext": "./XBPQ/18R/花丛视频.json" - }, + }, { "key": "PornHub", "name": "Phb|成人", @@ -2117,76 +1991,66 @@ "filterable": 1 }, { - "key": "我的阿里", - "name": "我的|阿里", + "key": "阿里云盘", + "name": "阿里|云盘", "type": 3, - "api": "csp_MyAli", + "api": "csp_PanAli", "searchable": 0, - "quickSearch": 0, "filterable": 0, - "indexs": 0, - "ext": { - "token": "http://127.0.0.1:9978/file/TVBox/token.txt" - }, - "style": { - "type": "list" - } - }, - { - "key": "我的夸克", - "name": "我的|夸克", - "type": 3, - "api": "csp_MyQuark", - "searchable": 0, - "quickSearch": 0, - "filterable": 0, - "indexs": 0, - "ext": { - "cookie": "http://127.0.0.1:9978/file/TVBox/quark.txt" - }, - "style": { - "type": "list" - } - }, - { - "key": "我的UC", - "name": "我的|UC", - "type": 3, - "api": "csp_MyUc", - "searchable": 0, - "quickSearch": 0, - "filterable": 0, - "indexs": 0, - "ext": { - "uc_cookie": "http://127.0.0.1:9978/file/TVBox/uc.txt" - }, - "style": { - "type": "list" - } - }, - { - "key": "阿里合集", - "name": "阿里|合集", - "type": 3, - "api": "csp_AliShare", - "searchable": 1, "changeable": 0, - "filterable": 0, - "indexs": 0, - "ext": { - "token": "http://127.0.0.1:9978/file/TVBox/token.txt", - "share": "./JS/alishare.txt" - }, "style": { - "type": "list" + "type": "list", + "ratio": 1.433 + }, + "ext": "./json/aliShare.json" + }, + { + "key": "夸克云盘", + "name": "夸克|云盘", + "type": 3, + "api": "csp_PanQuark", + "searchable": 0, + "filterable": 0, + "changeable": 0, + "style": { + "type": "list", + "ratio": 1.433 + }, + "ext": "./json/quarkShare.json" + }, + { + "key": "UC", + "name": "UC|云盘", + "type": 3, + "api": "csp_PanUc", + "searchable": 0, + "filterable": 0, + "changeable": 0, + "style": { + "type": "list", + "ratio": 1.433 + }, + "ext": "./json/ucShare.json" + }, + { + "key": "百度云盘", + "name": "百度|云盘", + "type": 3, + "api": "csp_PanBaiDu", + "searchable": 0, + "filterable": 0, + "changeable": 0, + "style": { + "type": "list", + "ratio": 1.433 } }, { "key": "短剧合集", "name": "短剧|合集", "type": 3, - "api": "./JS/quark.min.js", - "ext": "./JS/短剧合集.js", + "api": "./js/quark.min.js", + "ext": "./js/短剧合集.js", "style": { "type": "list" } @@ -2195,21 +2059,30 @@ "key": "AList", "name": "AList|合集", "type": 3, - "api": "csp_AList", + "api": "csp_Alist", "searchable": 1, "filterable": 1, "changeable": 0, "style": { "type": "list" }, - "ext": "./JSON/alist.json" + "ext": "./json/alist.json" }, { "key": "网络直播", "name": "网络|直播", "type": 3, - "api": "csp_Living", - "searchable": 1 + "api": "./py/网络直播.py" + }, + { + "key": "88看球", + "name": "88|看球", + "type": 3, + "api": "./js/drpy2.min.js", + "style": { + "type": "list" + }, + "ext": "./js/88看球.js" }, { "key": "急救教学", @@ -2222,7 +2095,8 @@ "style": { "type": "rect", "ratio": 3.8 - } + }, + "gridview": "0-0-4.1" }, { "key": "push_agent", @@ -2231,13 +2105,7 @@ "api": "csp_Push", "searchable": 0, "filterable": 0, - "changeable": 0, - "ext": { - "token": "http://127.0.0.1:9978/file/TVBox/token.txt", - "cookie": "http://127.0.0.1:9978/file/TVBox/quark.txt", - "uc_cookie": "http://127.0.0.1:9978/file/TVBox/uc.txt", - "danmu": true - } + "changeable": 0 } ], "parses": [ @@ -2573,27 +2441,6 @@ } ], "lives": [ - { - "name": "ITV", - "type": 0, - "url": "https://9877.kstore.space/Live/ITV.txt", - "epg": "http://epg.51zmt.top:8000/e.xml", - "ua": "okhttp/3.15,AptvPlayer/1.4.0", - "timeout": 5, - "playerType": 2 - }, - { - "name": "肥羊直播", - "type": 3, - "api": "csp_Feiyang", - "url": "https://9877.kstore.space/Live/live.m3u", - "timeout": 10, - "ua": "okhttp/3.15", - "catchup": { - "type": "append", - "source": "?livemode=4&starttime=${(b)yyyyMMdd'T'HHmm}00.00Z&endtime=${(e)yyyyMMdd'T'HHmm}00.00Z" - } - }, { "name": "AI直播", "type": 0, @@ -2626,17 +2473,25 @@ "timeout": 10, "ua": "okhttp/3.15" }, + { + "name": "B站直播", + "type": 3, + "api": "csp_Feiyang", + "url": "https://9877.kstore.space/Live/bilibili.m3u", + "timeout": 10, + "ua": "okhttp/3.15" + }, { "name": "电视Live", "type": 0, - "url": "http://127.0.0.1:9978/proxy?do=live&u=Gather", + "url": "https://tv.iill.top/m3u/Gather", "playerType": 2, "timeout": 10 }, { "name": "网络Live", "type": 0, - "url": "http://127.0.0.1:9978/proxy?do=live&url=https://tv.iill.top/m3u/Live", + "url": "https://tv.iill.top/m3u/Live", "playerType": 2, "timeout": 10 }, diff --git a/spider.jar b/spider.jar index 8018cbd..2696c4a 100644 Binary files a/spider.jar and b/spider.jar differ diff --git a/wex.jar b/wex.jar deleted file mode 100644 index f2cb313..0000000 Binary files a/wex.jar and /dev/null differ