├── README.md ├── lib ├── 0408.jar ├── svip.jar ├── spider.jar ├── custom_spider.jar ├── 骚火影视.json ├── 素白白.json ├── 可可影视.json ├── keke影视.json ├── nmys.json ├── 河马短剧.json ├── 红果短剧.py ├── 金牌影视.js ├── 金牌影视2.js ├── 甜圈短剧.py ├── jinpai.js ├── 金牌影视.py ├── TVB云播.js ├── 河马短剧.py └── drpy2.min.js ├── shenghanku.json ├── back ├── hanXC.json └── zyhan.json /README.md: -------------------------------------------------------------------------------- 1 | # TVBox 2 | -------------------------------------------------------------------------------- /lib/0408.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hanhan8127/TVBox/HEAD/lib/0408.jar -------------------------------------------------------------------------------- /lib/svip.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hanhan8127/TVBox/HEAD/lib/svip.jar -------------------------------------------------------------------------------- /lib/spider.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hanhan8127/TVBox/HEAD/lib/spider.jar -------------------------------------------------------------------------------- /lib/custom_spider.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hanhan8127/TVBox/HEAD/lib/custom_spider.jar -------------------------------------------------------------------------------- /shenghanku.json: -------------------------------------------------------------------------------- 1 | { 2 | "urls": [ 3 | 4 | {"url": "https://raw.bgithub.xyz/hanhan8127/TVBox/main/hanXC.json","name": "胜寒1"}, 5 | {"url": "https://raw.gitmirror.com/hanhan8127/TVBox/main/hanXC.json","name": "胜寒2"}, 6 | // https://d.kstore.dev/download/12020/ck.json 7 | 8 | {"url": "https://gitee.com/pulling-sister/xiaoya/raw/master/xiaoya.json","name": "小雅影视"}, 9 | {"url": "https://raw.liucn.cc/box/m.json","name": "肥猫"}, 10 | {"url": "https://6492.kstore.space/xnf/xnf.json","name": "环 宇 轩"}, 11 | 12 | {"url": "https://tv.nxog.top/m/111.php?ou=公众号欧歌app&mz=index&jar=index&123&b=tv","name": "欧歌线路"}, 13 | {"name": "小米仓库","url": "http://www.mpanso.com/小米/DEMO.json"}, 14 | {"name": "瞄影视","url": "http://meowtv.cn/tv"}, 15 | 16 | {"url": "https://raw.bgithub.xyz/PizazzGY/TVBox/refs/heads/main/api.json","name": "API"}, 17 | 18 | {"url": "http://我不是.摸鱼儿.top","name": "摸鱼"}, 19 | {"url": "http://47.99.102.252/xc.json","name": "XC星辰"} 20 | 21 | 22 | 23 | 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /lib/骚火影视.json: -------------------------------------------------------------------------------- 1 | { 2 | 3 | "作者":"天天开心", 4 | 5 | "站名":"骚火影视", 6 | 7 | "主页url":"https://saohuo.vip/", 8 | 9 | "简介":"+

", 10 | 11 | "导演":"

* / 导演:&& /", 12 | 13 | "主演":"主演:&&

", 14 | 15 | "影片地区":"

&& / ", 16 | 17 | "影片年代":"

* / && /", 18 | 19 | "影片状态":"v_note\">&&", 20 | 21 | "搜索url":"/search.php?searchword={wd}", 22 | 23 | "线路二次截取":"

", 24 | 25 | "线路数组":"", 26 | 27 | "线路标题":"+>&&<[替换:1号线路>>骚火专线#2线路>>骚火备用]", 28 | 29 | "跳转播放链接":"&&
", 10 | "数组": "
  • &&[替换:data-original=\">>图https://images.weserv.nl/?url=#https://www.subaibaiys.com>>https://www.subaibai.com]", 11 | "图片": "图&&\"", 12 | "副标题": "class=\"jidi\">&&", 13 | "搜索模式": "1", 14 | "搜索url": "https://www.subaibai.com/?s={wd}", 15 | "影片年代": "年份:&&
  • ", 16 | "影片地区": "地区:&&", 17 | "影片类型": "类型:&&", 18 | "导演": "导演:&&", 19 | "主演": "主演:&&", 20 | "简介": "yp_context\">&&

    ", 21 | "线路数组": "mi_paly_box\">&&
    ", 22 | "线路标题": "ypxingq_t\">&&[替换:在线播放>>]", 23 | "播放数组": "
    &&
    [替换:https://www.subaibaiys.com>>https://www.subaibai.com]", 24 | "播放列表": "", 25 | "播放标题": ">&&<", 26 | "播放链接": "href=\"&&\"", 27 | "嗅探词": "wangchuanxin.top#.mp4?#.m3u8#.mp4#.flv#.mp3#.m4a", 28 | "过滤词": "data.m3u8.in#51.la#cnzz.com#baidu.com#bilibili.com", 29 | "播放请求头": "User-Agent$Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36#authority$wangchuanxin.top#Origin$https://www.subaibai.com/" 30 | } -------------------------------------------------------------------------------- /lib/可可影视.json: -------------------------------------------------------------------------------- 1 | { 2 | "站名": "可可影视", 3 | "请求头": "User-Agent$MOBILE_UA", 4 | "编码": "UTF-8", 5 | "图片代理": "0", 6 | "主页url": "https://www.kkys04.com/", 7 | //https://www.kkys02.com/ https://www.kkys03.com/ https://www.kkys01.com/ https://dl.keke1.app/ https://www.keke1.app/ 8 | "首页": "120", 9 | "起始页": "1", 10 | "分类url": "/show/{cateId}-{class}-{area}-{lang}-{year}-{by}-{catePg}.html;;mrcd0", 11 | "分类": "电影&剧集&综艺&动漫&短剧", 12 | "分类值": "1&2&4&3&6", 13 | "数组": "默认--
    ||搜索--/detail&&", 14 | "标题": "title\">&&&&&&&&&&&&&&&&&&&&&&[不包含:4K(高峰不卡)]", 26 | "线路标题": "label\">&&<", 27 | "播放数组": "episode-list&&", 29 | "播放标题": ">&&<", 30 | "播放链接": "href=\"&&\"", 31 | "嗅探词": ".mp4#.m3u8", 32 | "搜索请求头": "User-Agent$MOBILE_UA", 33 | "搜索url": "/search?k={wd}&page={pg}", 34 | "搜索模式": "1", 35 | "筛选": "1", 36 | "剧情": "Netflix&剧情&喜剧&动作&爱情&恐怖&惊悚&犯罪&科幻&悬疑&奇幻&冒险&战争&历史&古装&家庭&传记&武侠&歌舞&短片&动画&儿童&职场||Netflix&剧情&爱情&喜剧&犯罪&悬疑&古装&动作&家庭&惊悚&奇幻&美剧&科幻&历史&战争&韩剧&武侠&言情&恐怖&冒险&都市&职场||纪录&真人秀&记录&脱口秀&剧情&历史&喜剧&传记&相声&节目&歌舞&冒险&运动&Season&犯罪&短片&搞笑&晚会||Netflix&动态漫画&剧情&动画&喜剧&冒险&动作&奇幻&科幻&儿童&搞笑&爱情&家庭&短片&热血&益智&悬疑&经典&校园&Anime&运动&亲子&青春&恋爱&武侠&惊悚||逆袭&甜宠&虐恋&穿越&重生&剧情&科幻&武侠&爱情&动作&战争&冒险&其它", 37 | "剧情值": "*", 38 | "地区": "中国大陆&中国香港&中国台湾&美国&日本&韩国&英国&法国&德国&印度&泰国&丹麦&瑞典&巴西&加拿大&俄罗斯&意大利&比利时&爱尔兰&西班牙&澳大利亚&其他||中国大陆&中国香港&韩国&美国&日本&法国&英国&德国&中国台湾&泰国&印度&其他||中国大陆&中国香港&中国台湾&美国&日本&韩国&其他||日本&中国大陆&中国台湾&美国&中国香港&韩国&英国&法国&德国&印度&泰国&丹麦&瑞典&巴西&加拿大&俄罗斯&意大利&比利时&爱尔兰&西班牙&澳大利亚&其他||空", 39 | "地区值": "*", 40 | "语言": "国语&粤语&英语&日语&韩语&法语||国语&粤语&英语&日语&韩语&法语||国语&粤语&英语&日语&韩语&法语||国语&粤语&英语&日语&韩语&法语||空", 41 | "语言值": "*", 42 | "排序": "综合&最新&最热&评分", 43 | "排序值": "1&2&3&4" 44 | } 45 | -------------------------------------------------------------------------------- /lib/keke影视.json: -------------------------------------------------------------------------------- 1 | { 2 | "规则名": "可可影视", 3 | //"DEBUG":"1", 4 | "规则作者": "香雅情", 5 | "请求头参数": "MOBILE_UA", 6 | "网页编码格式": "UTF-8", 7 | "图片是否需要代理": "否", 8 | "是否开启获取首页数据": "是", 9 | "首页推荐链接": "https://www.keke1.app", 10 | "首页列表数组规则": "body&&.module-v-box", 11 | "首页片单列表数组规则": ".module-item", 12 | "首页片单是否Jsoup写法": "1", 13 | "分类起始页码": "1", 14 | "分类链接": "https://www.keke1.app/show/{cateId}-----{by}-{catePg}.html", 15 | "分类名称": "电影&电视剧&综艺&动漫&短剧", 16 | "分类名称替换词": "1&2&4&3&6", 17 | //"筛选数据": {}, 18 | "筛选数据": "ext", 19 | //{cateId} 20 | "筛选子分类名称": "", 21 | "筛选子分类替换词": "", 22 | //{class} 23 | "筛选类型名称": "", 24 | "筛选类型替换词": "*", 25 | //{area} 26 | "筛选地区名称": "", 27 | "筛选地区替换词": "*", 28 | //{year} 29 | "筛选年份名称": "", 30 | "筛选年份替换词": "*", 31 | //{lang} 32 | "筛选语言名称": "", 33 | "筛选语言替换词": "*", 34 | //{by} 35 | "筛选排序名称": "综合&最新&最热&评分", 36 | "筛选排序替换词": "1&2&3&4", 37 | "分类截取模式": "1", 38 | "分类列表数组规则": ".module-v-box&&.module-item", 39 | "分类片单是否Jsoup写法": "是", 40 | "分类片单标题": ".v-item-title,-1&&Text", 41 | "分类片单链接": "a&&href", 42 | "分类片单图片": "'https://vres.miximixi.me'+.lazyload&&data-original", 43 | "分类片单副标题": ".v-item-bottom&&Text", 44 | "分类片单链接加前缀": "https://www.keke1.app", 45 | "分类片单链接加后缀": "", 46 | "搜索请求头参数": "User-Agent$MOBILE_UA", 47 | "搜索链接": "https://www.keke1.app/search?k={wd}&page=1", 48 | "POST请求数据": "", 49 | "搜索截取模式": "1", 50 | "搜索列表数组规则": ".search-result-list&&.search-result-item", 51 | "搜索片单是否Jsoup写法": "是", 52 | "搜索片单图片": "'https://vres.miximixi.me'+.lazyload&&data-original", 53 | "搜索片单标题": ".title&&Text", 54 | "搜索片单链接": "a&&href", 55 | "搜索片单副标题": "", 56 | "搜索片单链接加前缀": "https://www.keke1.app", 57 | "搜索片单链接加后缀": "", 58 | "链接是否直接播放": "否", 59 | "直接播放链接加前缀": "", 60 | "直接播放链接加后缀": "", 61 | "直接播放直链视频请求头": "", 62 | "详情是否Jsoup写法": "是", 63 | "类型详情": "", 64 | "年代详情": "", 65 | "地区详情": "", 66 | "演员详情": "body&&.detail-info-row:contains(演员:)&&Text!演员:", 67 | "简介详情": ".detail-desc&&Text", 68 | "线路列表数组规则": ".source-box&&.swiper-slide", 69 | "线路标题": "span&&Text[不包含:高峰不卡]", 70 | "播放列表数组规则": ".episode-box-main&&.episode-list", 71 | "选集列表数组规则": "a", 72 | "选集标题链接是否Jsoup写法": "是", 73 | "选集标题": "a&&Text", 74 | "选集链接": "a&&href", 75 | "是否反转选集序列": "否", 76 | "选集链接加前缀": "https://www.keke1.app", 77 | "选集链接加后缀": "", 78 | "分析MacPlayer": "", 79 | "是否开启手动嗅探": "否", 80 | "手动嗅探视频链接关键词": ".mp4#.m3u8#.flv#video/tos", 81 | "手动嗅探视频链接过滤词": ".html#=http" 82 | } 83 | -------------------------------------------------------------------------------- /lib/nmys.json: -------------------------------------------------------------------------------- 1 | { 2 | "规则名": "农民影视", 3 | "规则作者": "香雅情", 4 | "请求头参数": "User-Agent$手机#Referer$https://www.wwgz.cn", 5 | "网页编码格式": "UTF-8", 6 | "图片是否需要代理": "0", 7 | "是否开启获取首页数据": "1", 8 | "首页推荐链接": "https://www.wwgz.cn", 9 | "首页列表数组规则": "body&&.globalPicList", 10 | "首页片单列表数组规则": "li:has(img)", 11 | "首页片单是否Jsoup写法": "1", 12 | "首页片单标题": ".sTit&&Text", 13 | "首页片单链接": "a&&href", 14 | "首页片单图片": "img&&data-echo||data-src||src", 15 | "首页片单副标题": ".sBottom&&Text", 16 | "首页片单链接加前缀": "https://www.wwgz.cn", 17 | "首页片单链接加后缀": "", 18 | "分类起始页码": "1", 19 | "分类链接": "https://www.wwgz.cn/vod-list-id-{cateId}-pg-{catePg}-order--by-{by}-class--year-{year}-letter--area-{area}-lang-.html", 20 | "分类名称": "电影&电视剧&综艺&动漫&短剧", 21 | "分类名称替换词": "1&2&3&4&26", 22 | "筛选数据": "ext", 23 | "筛选子分类名称": "动作片&喜剧片&爱情片&科幻片&恐怖片&剧情片&战争片&惊悚片&奇幻片||国产剧&港台泰&日韩剧&欧美剧||空||动漫剧&动漫片", 24 | "筛选子分类替换词": "5&6&7&8&9&10&11&16&17||12&13&14&15||空||18&19", 25 | "筛选地区名称": "大陆&香港&台湾&美国&韩国&日本&泰国&新加坡&马来西亚&印度&英国&法国&加拿大&西班牙&俄罗斯&其它", 26 | "筛选地区替换词": "*", 27 | "分类截取模式": "1", 28 | "分类列表数组规则": ".globalPicList&&li", 29 | "分类片单是否Jsoup写法": "1", 30 | "分类片单标题": ".sTit&&Text", 31 | "分类片单链接": "a&&href", 32 | "分类片单图片": "img&&data-echo||data-src||src", 33 | "分类片单副标题": ".sBottom&&Text", 34 | "分类片单链接加前缀": "https://www.wwgz.cn", 35 | "分类片单链接加后缀": "", 36 | "搜索请求头参数": "User-Agent$手机#Referer$https://www.wwgz.cn", 37 | "search_url": "https://v.nmvod.cn/index.php?m=vod-search;post", 38 | "sea_PtBody": "wd={wd}", 39 | "search_mode": "1", 40 | "sea_arr_rule": "#data_list&&li", 41 | "sea_is_jsoup": "1", 42 | "sea_pic": ".lazyload&&data-src", 43 | "sea_title": ".sTit&&Text", 44 | "sea_url": "a&&href", 45 | "搜索片单副标题": ".sDes,-1&&Text", 46 | "搜索片单链接加前缀": "https://www.wwgz.cn", 47 | "搜索片单链接加后缀": "", 48 | "链接是否直接播放": "0", 49 | "直接播放链接加前缀": "https://live.52sf.ga/huya/", 50 | "直接播放链接加后缀": "#isVideo=true#", 51 | "直接播放直链视频请求头": "authority$ku.peizq.online#Referer$https://play.peizq.online", 52 | "详情是否Jsoup写法": "1", 53 | "类型详情": ".type-title&&Text", 54 | "年代详情": "body&&span:contains(年代:)&&Text!年代:", 55 | "地区详情": "", 56 | "演员详情": "body&&.sDes:contains(主演:)&&Text!主演:", 57 | "简介详情": ".detail-con&&p&&Text!简介:", 58 | "线路列表数组规则": "#leftTabBox&&ul&&li", 59 | "线路标题": "Text[替换:默认=>农民专线]", 60 | "播放列表数组规则": "#leftTabBox&&.numList", 61 | "选集列表数组规则": "li", 62 | "选集标题链接是否Jsoup写法": "1", 63 | "选集标题": "a&&Text", 64 | "选集链接": "a&&href", 65 | "是否反转选集序列": "1", 66 | "选集链接加前缀": "https://www.wwgz.cn", 67 | "选集链接加后缀": "", 68 | "分析MacPlayer": "0", 69 | "是否开启手动嗅探": "1", 70 | "手动嗅探视频链接关键词": ".mp4#.m3u8#item/video#video_mp4#video/tos", 71 | "手动嗅探视频链接过滤词": ".html#=http" 72 | } -------------------------------------------------------------------------------- /lib/河马短剧.json: -------------------------------------------------------------------------------- 1 | { 2 | "规则名": "河马短剧", 3 | "规则作者": "香雅情", 4 | "请求头参数": "MOBILE_UA", 5 | "网页编码格式": "UTF-8", 6 | "图片是否需要代理": "否", 7 | "是否开启获取首页数据": "否", 8 | "首页推荐链接": "https://www.kuaikaw.cn", 9 | "首页列表数组规则": "body&&.module-items", 10 | "首页片单列表数组规则": ".module-item:lt(12)", 11 | "首页片单是否Jsoup写法": "1", 12 | "分类起始页码": "1", 13 | "分类链接": "https://www.kuaikaw.cn/browse/{cateId}/{catePg}[firstPage=https://www.kuaikaw.cn/browse/{cateId}]", 14 | "分类名称": "短剧全部", 15 | "分类名称替换词": "0", 16 | //"筛选数据": {}, 17 | "筛选数据": "ext", 18 | //{cateId} 19 | "筛选子分类名称": "全部&民国&萌宝&超能&甜宠&豪门恩怨&长生&神医&寻亲&抗战谍战&奇幻&闪婚&职场商战&权谋&高手下山&时空之旅&欢喜冤家&都市&体育&家庭&喜剧&都市修仙&神豪&科幻&致富&奇幻脑洞&强者回归&励志&复仇&马甲&亲情&小人物&无敌&现实&重生&穿越&年代&悬疑&婚姻&家国情仇&虐恋&古装&仙侠&玄幻仙侠&传承觉醒&功夫武打&戏曲歌舞&情感&逆袭&战争", 20 | "筛选子分类替换词": "0&590-839&589&1115&442&462&585&1073&438&1125&1093&1092-1097&715&713&943&840-1101&474&1094&718&717&1129&1128&714-1126&917&1124&475&1130&918&721&476&1076-1100&416-463&1091-1096&719&835-837&472&1074&441-469&439-465&916&716-722&445-470&1127&915&466&444-468&1102&720&473&1095&1098&838&417-464&1099", 21 | //{class} 22 | "筛选类型名称": "", 23 | "筛选类型替换词": "*", 24 | //{area} 25 | "筛选地区名称": "", 26 | "筛选地区替换词": "*", 27 | //{year} 28 | "筛选年份名称": "", 29 | "筛选年份替换词": "*", 30 | //{lang} 31 | "筛选语言名称": "", 32 | "筛选语言替换词": "*", 33 | //{by} 34 | "筛选排序名称": "时间&人气&评分", 35 | "筛选排序替换词": "time&hits&score", 36 | "分类截取模式": "1", 37 | "分类列表数组规则": ".BrowseList_listBox__MyeBa&&.BrowseList_listItem__h7lD4", 38 | "分类片单是否Jsoup写法": "是", 39 | "分类片单标题": "img&&alt", 40 | "分类片单链接": "a&&href", 41 | "分类片单图片": "img&&src", 42 | "分类片单副标题": ".BrowseList_lastChapter__dkL54&&Text", 43 | "分类片单链接加前缀": "https://www.kuaikaw.cn", 44 | "分类片单链接加后缀": "", 45 | "搜索请求头参数": "User-Agent$MOBILE_UA", 46 | "搜索链接": "https://www.kuaikaw.cn/search/{SearchPg}?searchValue={wd}", 47 | "POST请求数据": "", 48 | "搜索截取模式": "1", 49 | "搜索列表数组规则": ".search_searchList__AvbeR&&.MTagBookList_tagBookItem__C_038", 50 | "搜索片单是否Jsoup写法": "是", 51 | "搜索片单图片": "img&&src", 52 | "搜索片单标题": "img&&alt", 53 | "搜索片单链接": "a&&href", 54 | "搜索片单副标题": "", 55 | "搜索片单链接加前缀": "https://www.kuaikaw.cn", 56 | "搜索片单链接加后缀": "", 57 | "链接是否直接播放": "否", 58 | "直接播放链接加前缀": "", 59 | "直接播放链接加后缀": "", 60 | "直接播放直链视频请求头": "", 61 | "详情是否Jsoup写法": "是", 62 | "类型详情": "", 63 | "年代详情": "", 64 | "地区详情": "", 65 | "演员详情": "", 66 | "简介详情": ".introduction_introBox__t4Bbz&&Text", 67 | "线路列表数组规则": "", 68 | "线路标题": "Text", 69 | "播放列表数组规则": "body&&.CatalogList_swiperBox__5kdPs", 70 | "选集列表数组规则": "a:not(:has(img))", 71 | "选集标题链接是否Jsoup写法": "是", 72 | "选集标题": "a&&Text", 73 | "选集链接": "a&&href", 74 | "是否反转选集序列": "否", 75 | "选集链接加前缀": "https://www.kuaikaw.cn", 76 | "选集链接加后缀": "", 77 | "分析MacPlayer": "否", 78 | "是否开启手动嗅探": "否", 79 | "手动嗅探视频链接关键词": ".mp4#.m3u8#.flv#video/tos", 80 | "手动嗅探视频链接过滤词": ".html#=http" 81 | } 82 | -------------------------------------------------------------------------------- /lib/红果短剧.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # by @嗷呜 3 | import re 4 | import sys 5 | from pyquery import PyQuery as pq 6 | sys.path.append('..') 7 | from base.spider import Spider 8 | 9 | class Spider(Spider): 10 | 11 | def init(self, extend=""): 12 | pass 13 | 14 | def getName(self): 15 | pass 16 | 17 | def isVideoFormat(self, url): 18 | pass 19 | 20 | def manualVideoCheck(self): 21 | pass 22 | 23 | def destroy(self): 24 | pass 25 | 26 | host='https://www.hongguodj.cc' 27 | 28 | headers = { 29 | 'Accept': '*/*', 30 | 'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8', 31 | 'Cache-Control': 'no-cache', 32 | 'Connection': 'keep-alive', 33 | 'DNT': '1', 34 | 'Origin': host, 35 | 'Pragma': 'no-cache', 36 | 'Sec-Fetch-Dest': 'empty', 37 | 'Sec-Fetch-Mode': 'cors', 38 | 'Sec-Fetch-Site': 'cross-site', 39 | 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36', 40 | 'sec-ch-ua': '"Not/A)Brand";v="8", "Chromium";v="134", "Google Chrome";v="134"', 41 | 'sec-ch-ua-mobile': '?0', 42 | 'sec-ch-ua-platform': '"macOS"', 43 | } 44 | 45 | def homeContent(self, filter): 46 | result = {} 47 | classes = [] 48 | vlist = [] 49 | data = pq(self.fetch(self.host, headers=self.headers).text) 50 | for i in list(data('.slip li').items())[1:]: 51 | classes.append({ 52 | 'type_name': i.text(), 53 | 'type_id': re.findall(r'\d+', i('a').attr('href'))[0] 54 | }) 55 | for i in data('.wrap .rows').items(): 56 | vlist.extend(self.getlist(i('li'))) 57 | result['class'] = classes 58 | result['list'] = vlist 59 | return result 60 | 61 | def homeVideoContent(self): 62 | pass 63 | 64 | def categoryContent(self, tid, pg, filter, extend): 65 | data=pq(self.fetch(f'{self.host}/type/{tid}-{pg}.html', headers=self.headers).text) 66 | result = {} 67 | result['list'] = self.getlist(data('.list ul li')) 68 | result['page'] = pg 69 | result['pagecount'] = 9999 70 | result['limit'] = 90 71 | result['total'] = 999999 72 | return result 73 | 74 | def detailContent(self, ids): 75 | data=pq(self.fetch(f'{self.host}{ids[0]}', headers=self.headers).text) 76 | v=data('.info') 77 | p=v('p') 78 | vod = { 79 | 'vod_name': v('h1').text(), 80 | 'type_name': p.eq(2).text(), 81 | 'vod_year': p.eq(3).text(), 82 | 'vod_area': p.eq(4).text(), 83 | 'vod_remarks': v('em').text(), 84 | 'vod_actor': p.eq(0).text(), 85 | 'vod_director': p.eq(1).text(), 86 | 'vod_content': data('#desc .text').text(), 87 | 'vod_play_from': '', 88 | 'vod_play_url': '' 89 | } 90 | names = [i.text() for i in data('.title.slip a').items()] 91 | plist=[] 92 | for i in data('.play-list ul').items(): 93 | plist.append('#'.join([f'{j("a").text()}${j("a").attr("href")}' for j in i('li').items()])) 94 | vod['vod_play_from'] = '$$$'.join(names) 95 | vod['vod_play_url'] = '$$$'.join(plist) 96 | return {'list': [vod]} 97 | 98 | def searchContent(self, key, quick, pg="1"): 99 | data=pq(self.fetch(f'{self.host}/search/{key}----------{pg}---.html', headers=self.headers).text) 100 | return {'list': self.getlist(data('.show.rows li')),'page':pg} 101 | 102 | def playerContent(self, flag, id, vipFlags): 103 | p=0 104 | uid=f'{self.host}{id}' 105 | data=pq(self.fetch(uid, headers=self.headers).text) 106 | url=data('.video.ratio').attr('data-play') 107 | if not url: 108 | url = uid 109 | p = 1 110 | return {'parse': p, 'url': url, 'header': self.headers} 111 | 112 | def localProxy(self, param): 113 | pass 114 | 115 | def getlist(self,data): 116 | vlist = [] 117 | for j in data.items(): 118 | vlist.append({ 119 | 'vod_id': j('a').attr('href'), 120 | 'vod_name': j('img').attr('alt'), 121 | 'vod_pic': self.host + j('img').attr('data-src'), 122 | 'vod_year': j('.bg').text(), 123 | 'vod_remarks': j('p').text() 124 | }) 125 | return vlist 126 | 127 | 128 | -------------------------------------------------------------------------------- /lib/金牌影视.js: -------------------------------------------------------------------------------- 1 | var rule = { 2 | title: '金牌影院', 3 | host: 'https://m.sunnafh.com', 4 | url: '/api/mw-movie/anonymous/video/list?pageNum=fypage&pageSize=30&sort=1&sortBy=1&type1=fyclass', 5 | searchUrl: '/api/mw-movie/anonymous/video/searchByWordPageable?keyword=**&pageNum=fypage&pageSize=12&type=false', 6 | headers: { 7 | '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' 8 | }, 9 | searchable: 2, 10 | quickSearch: 0, 11 | filterable: 0, 12 | class_name: '电影&电视剧&综艺&动漫', 13 | class_url: '1&2&3&4', 14 | limit: 6, 15 | double: false, 16 | play_parse:true, 17 | lazy:`js: 18 | let pid = input.split('/')[5]; 19 | let nid = input.split('/')[7]; 20 | const t = new Date().getTime(); 21 | eval(getCryptoJS); 22 | let signkey = 'clientType=1&id='+pid+'&nid='+nid+'&key=cb808529bae6b6be45ecfab29a4889bc&t='+t; 23 | const key = CryptoJS.SHA1(CryptoJS.MD5(signkey).toString()).toString(); 24 | let json_data = JSON.parse(request('https://m.sunnafh.com/api/mw-movie/anonymous/v2/video/episode/url?clientType=1&id='+pid+'&nid='+nid,{headers: { 25 | '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', 26 | 'deviceid': '63ffad23-a598-4f96-85d7-7bf5f3e4a0a2', 27 | 'sign': key, 28 | 't': t 29 | }})); 30 | let link = json_data.data.list[0].url; 31 | if(/\\.(m3u8|mp4)/.test(link)){input={jx:0,parse:0,url:link}}else{input={jx:0,parse:1,url:link}} 32 | `, 33 | 一级: `js: 34 | let d = []; 35 | let url = ''; 36 | let t = new Date().getTime(); 37 | eval(getCryptoJS); 38 | let signkey = 'pageNum='+MY_PAGE+'&pageSize=30&sort=1&sortBy=1&type1='+MY_CATE+'&key=cb808529bae6b6be45ecfab29a4889bc&t='+t; 39 | let key = CryptoJS.SHA1(CryptoJS.MD5(signkey).toString()).toString(); 40 | let list = JSON.parse(request(input,{headers:{ 41 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36', 42 | 'Accept': 'application/json, text/plain, */*', 43 | 'deviceId': '63ffad23-a598-4f96-85d7-7bf5f3e4a0a2', 44 | 'sign': key, 45 | 't': t 46 | }})).data.list; 47 | list.forEach((it)=>{ 48 | d.push({ 49 | title: it.vodName, 50 | desc:it.vodRemarks, 51 | img:it.vodPic, 52 | url:'http'+it.vodId 53 | }) 54 | }); 55 | setResult(d); 56 | `, 57 | 二级: `js: 58 | let kid=input.split('http')[1]; 59 | let t = new Date().getTime(); 60 | eval(getCryptoJS); 61 | let signkey = 'id='+kid+'&key=cb808529bae6b6be45ecfab29a4889bc&t='+t; 62 | let key = CryptoJS.SHA1(CryptoJS.MD5(signkey).toString()).toString(); 63 | let kjson = JSON.parse(request('https://m.sunnafh.com/api/mw-movie/anonymous/video/detail?id='+kid,{headers:{ 64 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36', 65 | 'Accept': 'application/json, text/plain, */*', 66 | 'deviceId': '63ffad23-a598-4f96-85d7-7bf5f3e4a0a2', 67 | 'sign': key, 68 | 't': t 69 | }})).data; 70 | let kurls = kjson.episodeList.map(function(it) => { 71 | return it.name + "$" + "https://m.sunnafh.com/vod/play/"+kid+"/sid/"+it.nid 72 | }).join('#'); 73 | VOD = { 74 | vod_id: kid, 75 | vod_name: kjson.vodName, 76 | vod_pic: kjson.vodPic, 77 | type_name: kjson.vodClass, 78 | vod_remarks: kjson.vodRemarks, 79 | vod_year: kjson.vodYear, 80 | vod_area: kjson.vodArea, 81 | vod_lang: kjson.vodLang, 82 | vod_director: kjson.vodDirector, 83 | vod_actor: kjson.vodActor, 84 | vod_content: kjson.vodContent, 85 | vod_play_from: '金牌线路', 86 | vod_play_url: kurls 87 | }`, 88 | 搜索: `js: 89 | let t = new Date().getTime(); 90 | eval(getCryptoJS); 91 | let pg = MY_PAGE; 92 | let signkey = 'keyword='+KEY+'&pageNum='+pg+'&pageSize=12&type=false&key=cb808529bae6b6be45ecfab29a4889bc&t='+t; 93 | let key = CryptoJS.SHA1(CryptoJS.MD5(signkey).toString()).toString(); 94 | let html = JSON.parse(request(input,{headers: { 95 | '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', 96 | 'deviceid': '63ffad23-a598-4f96-85d7-7bf5f3e4a0a2', 97 | 'sign': key, 98 | 't': t 99 | }})); 100 | let data = html.data.list; 101 | let d = []; 102 | data.forEach(it=>{ 103 | d.push({ 104 | title: it.vodName, 105 | desc:it.vodVersion, 106 | img:it.vodPic, 107 | url:'http'+it.vodId 108 | }) 109 | }); 110 | setResult(d) 111 | `, 112 | } -------------------------------------------------------------------------------- /lib/金牌影视2.js: -------------------------------------------------------------------------------- 1 | var rule = { 2 | title: '金牌影院', 3 | host: 'https://www.gs4x7nq4.com/ ', 4 | url: '/api/mw-movie/anonymous/video/list?pageNum=fypage&pageSize=30&sort=1&sortBy=1&type1=fyclass', 5 | searchUrl: '/api/mw-movie/anonymous/video/searchByWordPageable?keyword=**&pageNum=fypage&pageSize=12&type=false', 6 | headers: { 7 | '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' 8 | }, 9 | searchable: 2, 10 | quickSearch: 0, 11 | filterable: 0, 12 | class_name: '电影&电视剧&综艺&动漫', 13 | class_url: '1&2&3&4', 14 | limit: 6, 15 | double: false, 16 | play_parse:true, 17 | lazy:`js: 18 | let pid = input.split('/')[5]; 19 | let nid = input.split('/')[7]; 20 | const t = new Date().getTime(); 21 | eval(getCryptoJS); 22 | let signkey = 'clientType=1&id='+pid+'&nid='+nid+'&key=cb808529bae6b6be45ecfab29a4889bc&t='+t; 23 | const key = CryptoJS.SHA1(CryptoJS.MD5(signkey).toString()).toString(); 24 | let json_data = JSON.parse(request('https://www.gs4x7nq4.com/api/mw-movie/anonymous/v2/video/episode/url?clientType=1&id='+pid+'&nid='+nid,{headers: { 25 | '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', 26 | 'deviceid': '63ffad23-a598-4f96-85d7-7bf5f3e4a0a2', 27 | 'sign': key, 28 | 't': t 29 | }})); 30 | let link = json_data.data.list[0].url; 31 | if(/\\.(m3u8|mp4)/.test(link)){input={jx:0,parse:0,url:link}}else{input={jx:0,parse:1,url:link}} 32 | `, 33 | 一级: `js: 34 | let d = []; 35 | let url = ''; 36 | let t = new Date().getTime(); 37 | eval(getCryptoJS); 38 | let signkey = 'pageNum='+MY_PAGE+'&pageSize=30&sort=1&sortBy=1&type1='+MY_CATE+'&key=cb808529bae6b6be45ecfab29a4889bc&t='+t; 39 | let key = CryptoJS.SHA1(CryptoJS.MD5(signkey).toString()).toString(); 40 | let list = JSON.parse(request(input,{headers:{ 41 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36', 42 | 'Accept': 'application/json, text/plain, */*', 43 | 'deviceId': '63ffad23-a598-4f96-85d7-7bf5f3e4a0a2', 44 | 'sign': key, 45 | 't': t 46 | }})).data.list; 47 | list.forEach((it)=>{ 48 | d.push({ 49 | title: it.vodName, 50 | desc:it.vodRemarks, 51 | img:it.vodPic, 52 | url:'http'+it.vodId 53 | }) 54 | }); 55 | setResult(d); 56 | `, 57 | 二级: `js: 58 | let kid=input.split('http')[1]; 59 | let t = new Date().getTime(); 60 | eval(getCryptoJS); 61 | let signkey = 'id='+kid+'&key=cb808529bae6b6be45ecfab29a4889bc&t='+t; 62 | let key = CryptoJS.SHA1(CryptoJS.MD5(signkey).toString()).toString(); 63 | let kjson = JSON.parse(request('https://www.gs4x7nq4.com/api/mw-movie/anonymous/video/detail?id='+kid,{headers:{ 64 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36', 65 | 'Accept': 'application/json, text/plain, */*', 66 | 'deviceId': '63ffad23-a598-4f96-85d7-7bf5f3e4a0a2', 67 | 'sign': key, 68 | 't': t 69 | }})).data; 70 | let kurls = kjson.episodeList.map(function(it) => { 71 | return it.name + "$" + "https://www.gs4x7nq4.com/vod/play/"+kid+"/sid/"+it.nid 72 | }).join('#'); 73 | VOD = { 74 | vod_id: kid, 75 | vod_name: kjson.vodName, 76 | vod_pic: kjson.vodPic, 77 | type_name: kjson.vodClass, 78 | vod_remarks: kjson.vodRemarks, 79 | vod_year: kjson.vodYear, 80 | vod_area: kjson.vodArea, 81 | vod_lang: kjson.vodLang, 82 | vod_director: kjson.vodDirector, 83 | vod_actor: kjson.vodActor, 84 | vod_content: kjson.vodContent, 85 | vod_play_from: '金牌线路', 86 | vod_play_url: kurls 87 | }`, 88 | 搜索: `js: 89 | let t = new Date().getTime(); 90 | eval(getCryptoJS); 91 | let pg = MY_PAGE; 92 | let signkey = 'keyword='+KEY+'&pageNum='+pg+'&pageSize=12&type=false&key=cb808529bae6b6be45ecfab29a4889bc&t='+t; 93 | let key = CryptoJS.SHA1(CryptoJS.MD5(signkey).toString()).toString(); 94 | let html = JSON.parse(request(input,{headers: { 95 | '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', 96 | 'deviceid': '63ffad23-a598-4f96-85d7-7bf5f3e4a0a2', 97 | 'sign': key, 98 | 't': t 99 | }})); 100 | let data = html.data.list; 101 | let d = []; 102 | data.forEach(it=>{ 103 | d.push({ 104 | title: it.vodName, 105 | desc:it.vodVersion, 106 | img:it.vodPic, 107 | url:'http'+it.vodId 108 | }) 109 | }); 110 | setResult(d) 111 | `, 112 | } -------------------------------------------------------------------------------- /lib/甜圈短剧.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # by @嗷呜 3 | import sys 4 | sys.path.append('..') 5 | from base.spider import Spider 6 | 7 | 8 | class Spider(Spider): 9 | 10 | def init(self, extend=""): 11 | pass 12 | 13 | def getName(self): 14 | pass 15 | 16 | def isVideoFormat(self, url): 17 | pass 18 | 19 | def manualVideoCheck(self): 20 | pass 21 | 22 | def destroy(self): 23 | pass 24 | 25 | ahost='https://api.cenguigui.cn' 26 | 27 | headers = { 28 | 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36', 29 | 'sec-ch-ua-platform': '"macOS"', 30 | 'sec-ch-ua': '"Not/A)Brand";v="8", "Chromium";v="134", "Google Chrome";v="134"', 31 | 'DNT': '1', 32 | 'sec-ch-ua-mobile': '?0', 33 | 'Sec-Fetch-Site': 'cross-site', 34 | 'Sec-Fetch-Mode': 'no-cors', 35 | 'Sec-Fetch-Dest': 'video', 36 | 'Sec-Fetch-Storage-Access': 'active', 37 | 'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8', 38 | } 39 | 40 | def homeContent(self, filter): 41 | result = {'class': [{'type_id': '推荐榜', 'type_name': '推荐榜'}, 42 | {'type_id': '新剧', 'type_name': '新剧'}, 43 | {'type_id': '逆袭', 'type_name': '逆袭'}, 44 | {'type_id': '霸总', 'type_name': '霸总'}, 45 | {'type_id': '现代言情', 'type_name': '现代言情'}, 46 | {'type_id': '打脸虐渣', 'type_name': '打脸虐渣'}, 47 | {'type_id': '豪门恩怨', 'type_name': '豪门恩怨'}, 48 | {'type_id': '神豪', 'type_name': '神豪'}, 49 | {'type_id': '马甲', 'type_name': '马甲'}, 50 | {'type_id': '都市日常', 'type_name': '都市日常'}, 51 | {'type_id': '战神归来', 'type_name': '战神归来'}, 52 | {'type_id': '小人物', 'type_name': '小人物'}, 53 | {'type_id': '女性成长', 'type_name': '女性成长'}, 54 | {'type_id': '大女主', 'type_name': '大女主'}, 55 | {'type_id': '穿越', 'type_name': '穿越'}, 56 | {'type_id': '都市修仙', 'type_name': '都市修仙'}, 57 | {'type_id': '强者回归', 'type_name': '强者回归'}, 58 | {'type_id': '亲情', 'type_name': '亲情'}, 59 | {'type_id': '古装', 'type_name': '古装'}, 60 | {'type_id': '重生', 'type_name': '重生'}, 61 | {'type_id': '闪婚', 'type_name': '闪婚'}, 62 | {'type_id': '赘婿逆袭', 'type_name': '赘婿逆袭'}, 63 | {'type_id': '虐恋', 'type_name': '虐恋'}, 64 | {'type_id': '追妻', 'type_name': '追妻'}, 65 | {'type_id': '天下无敌', 'type_name': '天下无敌'}, 66 | {'type_id': '家庭伦理', 'type_name': '家庭伦理'}, 67 | {'type_id': '萌宝', 'type_name': '萌宝'}, 68 | {'type_id': '古风权谋', 'type_name': '古风权谋'}, 69 | {'type_id': '职场', 'type_name': '职场'}, 70 | {'type_id': '奇幻脑洞', 'type_name': '奇幻脑洞'}, 71 | {'type_id': '异能', 'type_name': '异能'}, 72 | {'type_id': '无敌神医', 'type_name': '无敌神医'}, 73 | {'type_id': '古风言情', 'type_name': '古风言情'}, 74 | {'type_id': '传承觉醒', 'type_name': '传承觉醒'}, 75 | {'type_id': '现言甜宠', 'type_name': '现言甜宠'}, 76 | {'type_id': '奇幻爱情', 'type_name': '奇幻爱情'}, 77 | {'type_id': '乡村', 'type_name': '乡村'}, 78 | {'type_id': '历史古代', 'type_name': '历史古代'}, 79 | {'type_id': '王妃', 'type_name': '王妃'}, 80 | {'type_id': '高手下山', 'type_name': '高手下山'}, 81 | {'type_id': '娱乐圈', 'type_name': '娱乐圈'}, 82 | {'type_id': '强强联合', 'type_name': '强强联合'}, 83 | {'type_id': '破镜重圆', 'type_name': '破镜重圆'}, 84 | {'type_id': '暗恋成真', 'type_name': '暗恋成真'}, 85 | {'type_id': '民国', 'type_name': '民国'}, 86 | {'type_id': '欢喜冤家', 'type_name': '欢喜冤家'}, 87 | {'type_id': '系统', 'type_name': '系统'}, 88 | {'type_id': '真假千金', 'type_name': '真假千金'}, 89 | {'type_id': '龙王', 'type_name': '龙王'}, 90 | {'type_id': '校园', 'type_name': '校园'}, 91 | {'type_id': '穿书', 'type_name': '穿书'}, 92 | {'type_id': '女帝', 'type_name': '女帝'}, 93 | {'type_id': '团宠', 'type_name': '团宠'}, 94 | {'type_id': '年代爱情', 'type_name': '年代爱情'}, 95 | {'type_id': '玄幻仙侠', 'type_name': '玄幻仙侠'}, 96 | {'type_id': '青梅竹马', 'type_name': '青梅竹马'}, 97 | {'type_id': '悬疑推理', 'type_name': '悬疑推理'}, 98 | {'type_id': '皇后', 'type_name': '皇后'}, 99 | {'type_id': '替身', 'type_name': '替身'}, 100 | {'type_id': '大叔', 'type_name': '大叔'}, 101 | {'type_id': '喜剧', 'type_name': '喜剧'}, 102 | {'type_id': '剧情', 'type_name': '剧情'}]} 103 | return result 104 | 105 | def homeVideoContent(self): 106 | pass 107 | 108 | def categoryContent(self, tid, pg, filter, extend): 109 | params = { 110 | 'classname': tid, 111 | 'offset': str((int(pg) - 1)), 112 | } 113 | data = self.fetch(f'{self.ahost}/api/duanju/api.php', params=params, headers=self.headers).json() 114 | videos = [] 115 | for k in data['data']: 116 | videos.append({ 117 | 'vod_id': k.get('book_id'), 118 | 'vod_name': k.get('title'), 119 | 'vod_pic': k.get('cover'), 120 | 'vod_year': k.get('score'), 121 | 'vod_remarks': f"{k.get('sub_title')}|{k.get('episode_cnt')}" 122 | }) 123 | result = {} 124 | result['list'] = videos 125 | result['page'] = pg 126 | result['pagecount'] = 9999 127 | result['limit'] = 90 128 | result['total'] = 999999 129 | return result 130 | 131 | def detailContent(self, ids): 132 | v=self.fetch(f'{self.ahost}/api/duanju/api.php', params={'book_id': ids[0]}, headers=self.headers).json() 133 | vod = { 134 | 'type_name': v.get('category'), 135 | 'vod_year': v.get('time'), 136 | 'vod_remarks': v.get('duration'), 137 | 'vod_content': v.get('desc'), 138 | 'vod_play_from': '嗷呜爱看短剧', 139 | 'vod_play_url': '#'.join([f"{i['title']}${i['video_id']}" for i in v['data']]) 140 | } 141 | return {'list':[vod]} 142 | 143 | def searchContent(self, key, quick, pg="1"): 144 | return self.categoryContent(key, pg, True, {}) 145 | 146 | def playerContent(self, flag, id, vipFlags): 147 | data=self.fetch(f'{self.ahost}/api/duanju/api.php', params={'video_id': id}, headers=self.headers).json() 148 | return {'parse': 0, 'url': data['data']['url'], 'header': self.headers} 149 | 150 | def localProxy(self, param): 151 | pass 152 | -------------------------------------------------------------------------------- /lib/jinpai.js: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # by @嗷呜 3 | import json 4 | import sys 5 | import threading 6 | import uuid 7 | import requests 8 | sys.path.append('..') 9 | from base.spider import Spider 10 | import time 11 | from Crypto.Hash import MD5, SHA1 12 | 13 | class Spider(Spider): 14 | ''' 15 | 配置示例: 16 | { 17 | "key": "xxxx", 18 | "name": "xxxx", 19 | "type": 3, 20 | "api": ".所在路径/金牌.py", 21 | "searchable": 1, 22 | "quickSearch": 1, 23 | "filterable": 1, 24 | "changeable": 1, 25 | "ext": { 26 | "site": "https://www.jiabaide.cn,域名2,域名3" 27 | } 28 | }, 29 | ''' 30 | def init(self, extend=""): 31 | if extend: 32 | hosts=json.loads(extend)['site'] 33 | self.host = self.host_late(hosts) 34 | pass 35 | 36 | def getName(self): 37 | pass 38 | 39 | def isVideoFormat(self, url): 40 | pass 41 | 42 | def manualVideoCheck(self): 43 | pass 44 | 45 | def destroy(self): 46 | pass 47 | 48 | def homeContent(self, filter): 49 | cdata = self.fetch(f"{self.host}/api/mw-movie/anonymous/get/filer/type", headers=self.getheaders()).json() 50 | fdata = self.fetch(f"{self.host}/api/mw-movie/anonymous/v1/get/filer/list", headers=self.getheaders()).json() 51 | result = {} 52 | classes = [] 53 | filters={} 54 | for k in cdata['data']: 55 | classes.append({ 56 | 'type_name': k['typeName'], 57 | 'type_id': str(k['typeId']), 58 | }) 59 | sort_values = [{"n": "最近更新", "v": "2"},{"n": "人气高低", "v": "3"}, {"n": "评分高低", "v": "4"}] 60 | for tid, d in fdata['data'].items(): 61 | current_sort_values = sort_values.copy() 62 | if tid == '1': 63 | del current_sort_values[0] 64 | filters[tid] = [ 65 | {"key": "type", "name": "类型", 66 | "value": [{"n": i["itemText"], "v": i["itemValue"]} for i in d["typeList"]]}, 67 | 68 | *([] if not d["plotList"] else [{"key": "v_class", "name": "剧情", 69 | "value": [{"n": i["itemText"], "v": i["itemText"]} 70 | for i in d["plotList"]]}]), 71 | 72 | {"key": "area", "name": "地区", 73 | "value": [{"n": i["itemText"], "v": i["itemText"]} for i in d["districtList"]]}, 74 | 75 | {"key": "year", "name": "年份", 76 | "value": [{"n": i["itemText"], "v": i["itemText"]} for i in d["yearList"]]}, 77 | 78 | {"key": "lang", "name": "语言", 79 | "value": [{"n": i["itemText"], "v": i["itemText"]} for i in d["languageList"]]}, 80 | 81 | {"key": "sort", "name": "排序", "value": current_sort_values} 82 | ] 83 | result['class'] = classes 84 | result['filters'] = filters 85 | return result 86 | 87 | def homeVideoContent(self): 88 | data1 = self.fetch(f"{self.host}/api/mw-movie/anonymous/v1/home/all/list", headers=self.getheaders()).json() 89 | data2=self.fetch(f"{self.host}/api/mw-movie/anonymous/home/hotSearch",headers=self.getheaders()).json() 90 | data=[] 91 | for i in data1['data'].values(): 92 | data.extend(i['list']) 93 | data.extend(data2['data']) 94 | vods=self.getvod(data) 95 | return {'list':vods} 96 | 97 | def categoryContent(self, tid, pg, filter, extend): 98 | 99 | params = { 100 | "area": extend.get('area', ''), 101 | "filterStatus": "1", 102 | "lang": extend.get('lang', ''), 103 | "pageNum": pg, 104 | "pageSize": "30", 105 | "sort": extend.get('sort', '1'), 106 | "sortBy": "1", 107 | "type": extend.get('type', ''), 108 | "type1": tid, 109 | "v_class": extend.get('v_class', ''), 110 | "year": extend.get('year', '') 111 | } 112 | data = self.fetch(f"{self.host}/api/mw-movie/anonymous/video/list?{self.js(params)}", headers=self.getheaders(params)).json() 113 | result = {} 114 | result['list'] = self.getvod(data['data']['list']) 115 | result['page'] = pg 116 | result['pagecount'] = 9999 117 | result['limit'] = 90 118 | result['total'] = 999999 119 | return result 120 | 121 | def detailContent(self, ids): 122 | data=self.fetch(f"{self.host}/api/mw-movie/anonymous/video/detail?id={ids[0]}",headers=self.getheaders({'id':ids[0]})).json() 123 | vod=self.getvod([data['data']])[0] 124 | vod['vod_play_from']='金牌' 125 | vod['vod_play_url'] = '#'.join( 126 | f"{i['name'] if len(vod['episodelist']) > 1 else vod['vod_name']}${ids[0]}@@{i['nid']}" for i in 127 | vod['episodelist']) 128 | vod.pop('episodelist', None) 129 | return {'list':[vod]} 130 | 131 | def searchContent(self, key, quick, pg="1"): 132 | params = { 133 | "keyword": key, 134 | "pageNum": pg, 135 | "pageSize": "8", 136 | "sourceCode": "1" 137 | } 138 | data=self.fetch(f"{self.host}/api/mw-movie/anonymous/video/searchByWord?{self.js(params)}",headers=self.getheaders(params)).json() 139 | vods=self.getvod(data['data']['result']['list']) 140 | return {'list':vods,'page':pg} 141 | 142 | def playerContent(self, flag, id, vipFlags): 143 | self.header = { 144 | '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', 145 | 'sec-ch-ua-platform': '"Windows"', 146 | 'DNT': '1', 147 | 'sec-ch-ua': '"Not/A)Brand";v="8", "Chromium";v="126", "Google Chrome";v="126"', 148 | 'sec-ch-ua-mobile': '?0', 149 | 'Origin': self.host, 150 | 'Referer': f'{self.host}/' 151 | } 152 | ids=id.split('@@') 153 | 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() 154 | vlist=[] 155 | for i in pdata['data']['list']:vlist.extend([i['resolutionName'],i['url']]) 156 | return {'parse':0,'url':vlist,'header':self.header} 157 | 158 | def localProxy(self, param): 159 | pass 160 | 161 | def host_late(self, url_list): 162 | if isinstance(url_list, str): 163 | urls = [u.strip() for u in url_list.split(',')] 164 | else: 165 | urls = url_list 166 | if len(urls) <= 1: 167 | return urls[0] if urls else '' 168 | 169 | results = {} 170 | threads = [] 171 | 172 | def test_host(url): 173 | try: 174 | start_time = time.time() 175 | response = requests.head(url, timeout=1.0, allow_redirects=False) 176 | delay = (time.time() - start_time) * 1000 177 | results[url] = delay 178 | except Exception as e: 179 | results[url] = float('inf') 180 | for url in urls: 181 | t = threading.Thread(target=test_host, args=(url,)) 182 | threads.append(t) 183 | t.start() 184 | for t in threads: 185 | t.join() 186 | return min(results.items(), key=lambda x: x[1])[0] 187 | 188 | def md5(self, sign_key): 189 | md5_hash = MD5.new() 190 | md5_hash.update(sign_key.encode('utf-8')) 191 | md5_result = md5_hash.hexdigest() 192 | return md5_result 193 | 194 | def js(self, param): 195 | return '&'.join(f"{k}={v}" for k, v in param.items()) 196 | 197 | def getheaders(self, param=None): 198 | if param is None:param = {} 199 | t=str(int(time.time()*1000)) 200 | param['key']='cb808529bae6b6be45ecfab29a4889bc' 201 | param['t']=t 202 | sha1_hash = SHA1.new() 203 | sha1_hash.update(self.md5(self.js(param)).encode('utf-8')) 204 | sign = sha1_hash.hexdigest() 205 | deviceid = str(uuid.uuid4()) 206 | headers = { 207 | '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', 208 | 'Accept': 'application/json, text/plain, */*', 209 | 'sign': sign, 210 | 't': t, 211 | 'deviceid':deviceid 212 | } 213 | return headers 214 | 215 | def convert_field_name(self, field): 216 | field = field.lower() 217 | if field.startswith('vod') and len(field) > 3: 218 | field = field.replace('vod', 'vod_') 219 | if field.startswith('type') and len(field) > 4: 220 | field = field.replace('type', 'type_') 221 | return field 222 | 223 | def getvod(self, array): 224 | return [{self.convert_field_name(k): v for k, v in item.items()} for item in array] 225 | 226 | -------------------------------------------------------------------------------- /lib/金牌影视.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # by @嗷呜 3 | import json 4 | import sys 5 | import threading 6 | import uuid 7 | import requests 8 | sys.path.append('..') 9 | from base.spider import Spider 10 | import time 11 | from Crypto.Hash import MD5, SHA1 12 | 13 | class Spider(Spider): 14 | ''' 15 | 配置示例: 16 | { 17 | "key": "xxxx", 18 | "name": "xxxx", 19 | "type": 3, 20 | "api": ".所在路径/金牌.py", 21 | "searchable": 1, 22 | "quickSearch": 1, 23 | "filterable": 1, 24 | "changeable": 1, 25 | "ext": { 26 | "site": "https://www.jiabaide.cn,域名2,域名3" 27 | } 28 | }, 29 | ''' 30 | def init(self, extend=""): 31 | if extend: 32 | hosts=json.loads(extend)['site'] 33 | self.host = self.host_late(hosts) 34 | pass 35 | 36 | def getName(self): 37 | pass 38 | 39 | def isVideoFormat(self, url): 40 | pass 41 | 42 | def manualVideoCheck(self): 43 | pass 44 | 45 | def destroy(self): 46 | pass 47 | 48 | def homeContent(self, filter): 49 | cdata = self.fetch(f"{self.host}/api/mw-movie/anonymous/get/filer/type", headers=self.getheaders()).json() 50 | fdata = self.fetch(f"{self.host}/api/mw-movie/anonymous/v1/get/filer/list", headers=self.getheaders()).json() 51 | result = {} 52 | classes = [] 53 | filters={} 54 | for k in cdata['data']: 55 | classes.append({ 56 | 'type_name': k['typeName'], 57 | 'type_id': str(k['typeId']), 58 | }) 59 | sort_values = [{"n": "最近更新", "v": "2"},{"n": "人气高低", "v": "3"}, {"n": "评分高低", "v": "4"}] 60 | for tid, d in fdata['data'].items(): 61 | current_sort_values = sort_values.copy() 62 | if tid == '1': 63 | del current_sort_values[0] 64 | filters[tid] = [ 65 | {"key": "type", "name": "类型", 66 | "value": [{"n": i["itemText"], "v": i["itemValue"]} for i in d["typeList"]]}, 67 | 68 | *([] if not d["plotList"] else [{"key": "v_class", "name": "剧情", 69 | "value": [{"n": i["itemText"], "v": i["itemText"]} 70 | for i in d["plotList"]]}]), 71 | 72 | {"key": "area", "name": "地区", 73 | "value": [{"n": i["itemText"], "v": i["itemText"]} for i in d["districtList"]]}, 74 | 75 | {"key": "year", "name": "年份", 76 | "value": [{"n": i["itemText"], "v": i["itemText"]} for i in d["yearList"]]}, 77 | 78 | {"key": "lang", "name": "语言", 79 | "value": [{"n": i["itemText"], "v": i["itemText"]} for i in d["languageList"]]}, 80 | 81 | {"key": "sort", "name": "排序", "value": current_sort_values} 82 | ] 83 | result['class'] = classes 84 | result['filters'] = filters 85 | return result 86 | 87 | def homeVideoContent(self): 88 | data1 = self.fetch(f"{self.host}/api/mw-movie/anonymous/v1/home/all/list", headers=self.getheaders()).json() 89 | data2=self.fetch(f"{self.host}/api/mw-movie/anonymous/home/hotSearch",headers=self.getheaders()).json() 90 | data=[] 91 | for i in data1['data'].values(): 92 | data.extend(i['list']) 93 | data.extend(data2['data']) 94 | vods=self.getvod(data) 95 | return {'list':vods} 96 | 97 | def categoryContent(self, tid, pg, filter, extend): 98 | 99 | params = { 100 | "area": extend.get('area', ''), 101 | "filterStatus": "1", 102 | "lang": extend.get('lang', ''), 103 | "pageNum": pg, 104 | "pageSize": "30", 105 | "sort": extend.get('sort', '1'), 106 | "sortBy": "1", 107 | "type": extend.get('type', ''), 108 | "type1": tid, 109 | "v_class": extend.get('v_class', ''), 110 | "year": extend.get('year', '') 111 | } 112 | data = self.fetch(f"{self.host}/api/mw-movie/anonymous/video/list?{self.js(params)}", headers=self.getheaders(params)).json() 113 | result = {} 114 | result['list'] = self.getvod(data['data']['list']) 115 | result['page'] = pg 116 | result['pagecount'] = 9999 117 | result['limit'] = 90 118 | result['total'] = 999999 119 | return result 120 | 121 | def detailContent(self, ids): 122 | data=self.fetch(f"{self.host}/api/mw-movie/anonymous/video/detail?id={ids[0]}",headers=self.getheaders({'id':ids[0]})).json() 123 | vod=self.getvod([data['data']])[0] 124 | vod['vod_play_from']='金牌' 125 | vod['vod_play_url'] = '#'.join( 126 | f"{i['name'] if len(vod['episodelist']) > 1 else vod['vod_name']}${ids[0]}@@{i['nid']}" for i in 127 | vod['episodelist']) 128 | vod.pop('episodelist', None) 129 | return {'list':[vod]} 130 | 131 | def searchContent(self, key, quick, pg="1"): 132 | params = { 133 | "keyword": key, 134 | "pageNum": pg, 135 | "pageSize": "8", 136 | "sourceCode": "1" 137 | } 138 | data=self.fetch(f"{self.host}/api/mw-movie/anonymous/video/searchByWord?{self.js(params)}",headers=self.getheaders(params)).json() 139 | vods=self.getvod(data['data']['result']['list']) 140 | return {'list':vods,'page':pg} 141 | 142 | def playerContent(self, flag, id, vipFlags): 143 | self.header = { 144 | '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', 145 | 'sec-ch-ua-platform': '"Windows"', 146 | 'DNT': '1', 147 | 'sec-ch-ua': '"Not/A)Brand";v="8", "Chromium";v="126", "Google Chrome";v="126"', 148 | 'sec-ch-ua-mobile': '?0', 149 | 'Origin': self.host, 150 | 'Referer': f'{self.host}/' 151 | } 152 | ids=id.split('@@') 153 | 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() 154 | vlist=[] 155 | for i in pdata['data']['list']:vlist.extend([i['resolutionName'],i['url']]) 156 | return {'parse':0,'url':vlist,'header':self.header} 157 | 158 | def localProxy(self, param): 159 | pass 160 | 161 | def host_late(self, url_list): 162 | if isinstance(url_list, str): 163 | urls = [u.strip() for u in url_list.split(',')] 164 | else: 165 | urls = url_list 166 | if len(urls) <= 1: 167 | return urls[0] if urls else '' 168 | 169 | results = {} 170 | threads = [] 171 | 172 | def test_host(url): 173 | try: 174 | start_time = time.time() 175 | response = requests.head(url, timeout=1.0, allow_redirects=False) 176 | delay = (time.time() - start_time) * 1000 177 | results[url] = delay 178 | except Exception as e: 179 | results[url] = float('inf') 180 | for url in urls: 181 | t = threading.Thread(target=test_host, args=(url,)) 182 | threads.append(t) 183 | t.start() 184 | for t in threads: 185 | t.join() 186 | return min(results.items(), key=lambda x: x[1])[0] 187 | 188 | def md5(self, sign_key): 189 | md5_hash = MD5.new() 190 | md5_hash.update(sign_key.encode('utf-8')) 191 | md5_result = md5_hash.hexdigest() 192 | return md5_result 193 | 194 | def js(self, param): 195 | return '&'.join(f"{k}={v}" for k, v in param.items()) 196 | 197 | def getheaders(self, param=None): 198 | if param is None:param = {} 199 | t=str(int(time.time()*1000)) 200 | param['key']='cb808529bae6b6be45ecfab29a4889bc' 201 | param['t']=t 202 | sha1_hash = SHA1.new() 203 | sha1_hash.update(self.md5(self.js(param)).encode('utf-8')) 204 | sign = sha1_hash.hexdigest() 205 | deviceid = str(uuid.uuid4()) 206 | headers = { 207 | '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', 208 | 'Accept': 'application/json, text/plain, */*', 209 | 'sign': sign, 210 | 't': t, 211 | 'deviceid':deviceid 212 | } 213 | return headers 214 | 215 | def convert_field_name(self, field): 216 | field = field.lower() 217 | if field.startswith('vod') and len(field) > 3: 218 | field = field.replace('vod', 'vod_') 219 | if field.startswith('type') and len(field) > 4: 220 | field = field.replace('type', 'type_') 221 | return field 222 | 223 | def getvod(self, array): 224 | return [{self.convert_field_name(k): v for k, v in item.items()} for item in array] 225 | 226 | -------------------------------------------------------------------------------- /lib/TVB云播.js: -------------------------------------------------------------------------------- 1 | var rule = { 2 | title: 'TVB云播', 3 | //模板:'mxpro', 4 | host: 'http://www.tvyun07.com', 5 | url: 'vod/show/id/fyfilter.html', 6 | filterable: 1,//是否启用分类筛选, 7 | filter_url: '{{fl.cateId}}{{fl.area}}{{fl.by}}{{fl.class}}{{fl.lang}}{{fl.letter}}/page/fypage{{fl.year}}', 8 | class_name: '电影&电视剧&综艺&动漫&日韩剧&国产剧&欧美剧&港台剧', 9 | class_url: '1&2&3&4&16&13&15&14', 10 | filter: { 11 | "1": [{ "key": "cateId", "name": "类型", "value": [{ "n": "全部", "v": "1" }, { "n": "动作片", "v": "6" }, { "n": "喜剧片", "v": "7" }, { "n": "爱情片", "v": "8" }, { "n": "科幻片", "v": "9" }, { "n": "恐怖片", "v": "10" }, { "n": "剧情片", "v": "11" }, { "n": "战争片", "v": "12" }] }, { "key": "class", "name": "剧情", "value": [{ "n": "全部", "v": "" }, { "n": "喜剧", "v": "/class/喜剧" }, { "n": "爱情", "v": "/class/爱情" }, { "n": "恐怖", "v": "/class/恐怖" }, { "n": "动作", "v": "/class/动作" }, { "n": "科幻", "v": "/class/科幻" }, { "n": "剧情", "v": "/class/剧情" }, { "n": "战争", "v": "/class/战争" }, { "n": "警匪", "v": "/class/警匪" }, { "n": "犯罪", "v": "/class/犯罪" }, { "n": "动画", "v": "/class/动画" }, { "n": "奇幻", "v": "/class/奇幻" }, { "n": "武侠", "v": "/class/武侠" }, { "n": "冒险", "v": "/class/冒险" }, { "n": "枪战", "v": "/class/枪战" }, { "n": "悬疑", "v": "/class/悬疑" }, { "n": "惊悚", "v": "/class/惊悚" }, { "n": "经典", "v": "/class/经典" }, { "n": "青春", "v": "/class/青春" }, { "n": "文艺", "v": "/class/文艺" }, { "n": "微电影", "v": "/class/微电影" }, { "n": "古装", "v": "/class/古装" }, { "n": "历史", "v": "/class/历史" }, { "n": "运动", "v": "/class/运动" }, { "n": "农村", "v": "/class/农村" }, { "n": "儿童", "v": "/class/儿童" }, { "n": "网络电影", "v": "/class/网络电影" }] }, { "key": "area", "name": "地区", "value": [{ "n": "全部", "v": "" }, { "n": "大陆", "v": "/area/大陆" }, { "n": "香港", "v": "/area/香港" }, { "n": "台湾", "v": "/area/台湾" }, { "n": "美国", "v": "/area/美国" }, { "n": "法国", "v": "/area/法国" }, { "n": "英国", "v": "/area/英国" }, { "n": "日本", "v": "/area/日本" }, { "n": "韩国", "v": "/area/韩国" }, { "n": "德国", "v": "/area/德国" }, { "n": "泰国", "v": "/area/泰国" }, { "n": "印度", "v": "/area/印度" }, { "n": "意大利", "v": "/area/意大利" }, { "n": "西班牙", "v": "/area/西班牙" }, { "n": "加拿大", "v": "/area/加拿大" }, { "n": "其他", "v": "/area/其他" }] }, { "key": "lang", "name": "语言", "value": [{ "n": "全部", "v": "" }, { "n": "国语", "v": "/lang/国语" }, { "n": "英语", "v": "/lang/英语" }, { "n": "粤语", "v": "/lang/粤语" }, { "n": "韩语", "v": "/lang/韩语" }, { "n": "日语", "v": "/lang/日语" }, { "n": "法语", "v": "/lang/法语" }, { "n": "德语", "v": "/lang/德语" }, { "n": "其它", "v": "/lang/其它" }] }, { "key": "year", "name": "年份", "value": [{ "n": "全部", "v": "" }, { "n": "2025", "v": "/year/2025" },{ "n": "2024", "v": "/year/2024" }, { "n": "2023", "v": "/year/2023" }, { "n": "2022", "v": "/year/2022" }, { "n": "2021", "v": "/year/2021" }, { "n": "2020", "v": "/year/2020" }, { "n": "2019", "v": "/year/2019" }, { "n": "2018", "v": "/year/2018" }, { "n": "2017", "v": "/year/2017" }, { "n": "2016", "v": "/year/2016" }, { "n": "2015", "v": "/year/2015" }, { "n": "2014", "v": "/year/2014" }, { "n": "2013", "v": "/year/2013" }, { "n": "2012", "v": "/year/2012" }, { "n": "2011", "v": "/year/2011" }, { "n": "2010", "v": "/year/2010" }, { "n": "2009", "v": "/year/2009" }, { "n": "2008", "v": "/year/2008" }, { "n": "2007", "v": "/year/2007" }, { "n": "2006", "v": "/year/2006" }, { "n": "2005", "v": "/year/2005" }, { "n": "2004", "v": "/year/2004" }] }, { "key": "by", "name": "排序", "value": [{ "n": "全部", "v": "" }, { "n": "时间", "v": "/by/time" }, { "n": "人气", "v": "/by/hits" }, { "n": "评分", "v": "/by/score" }] }], 12 | "2": [{ "key": "cateId", "name": "类型", "value": [{ "n": "全部", "v": "2" }, { "n": "国产剧", "v": "13" }, { "n": "港台剧", "v": "14" }, { "n": "日韩剧", "v": "15" }, { "n": "欧美剧", "v": "16" }] }, { "key": "class", "name": "剧情", "value": [{ "n": "全部", "v": "" }, { "n": "古装", "v": "/class/古装" }, { "n": "青春", "v": "/class/青春" }, { "n": "偶像", "v": "/class/偶像" }, { "n": "喜剧", "v": "/class/喜剧" }, { "n": "家庭", "v": "/class/家庭" }, { "n": "犯罪", "v": "/class/犯罪" }, { "n": "动作", "v": "/class/动作" }, { "n": "奇幻", "v": "/class/奇幻" }, { "n": "剧情", "v": "/class/剧情" }, { "n": "历史", "v": "/class/历史" }, { "n": "经典", "v": "/class/经典" }, { "n": "乡村", "v": "/class/乡村" }, { "n": "情景", "v": "/class/情景" }, { "n": "商战", "v": "/class/商战" }, { "n": "网剧", "v": "/class/网剧" }, { "n": "其他", "v": "/class/其他" }] }, { "key": "area", "name": "地区", "value": [{ "n": "全部", "v": "" }, { "n": "内地", "v": "/area/内地" }, { "n": "韩国", "v": "/area/韩国" }, { "n": "香港", "v": "/area/香港" }, { "n": "台湾", "v": "/area/台湾" }, { "n": "日本", "v": "/area/日本" }, { "n": "美国", "v": "/area/美国" }, { "n": "泰国", "v": "/area/泰国" }, { "n": "英国", "v": "/area/英国" }, { "n": "新加坡", "v": "/area/新加坡" }, { "n": "其他", "v": "/area/其他" }] }, { "key": "year", "name": "年份", "value": [{ "n": "全部", "v": "" }, { "n": "2025", "v": "/year/2025" },{ "n": "2024", "v": "/year/2024" }, { "n": "2023", "v": "/year/2023" }, { "n": "2022", "v": "/year/2022" }, { "n": "2021", "v": "/year/2021" }, { "n": "2020", "v": "/year/2020" }, { "n": "2019", "v": "/year/2019" }, { "n": "2018", "v": "/year/2018" }, { "n": "2017", "v": "/year/2017" }, { "n": "2016", "v": "/year/2016" }, { "n": "2015", "v": "/year/2015" }, { "n": "2014", "v": "/year/2014" }, { "n": "2013", "v": "/year/2013" }, { "n": "2012", "v": "/year/2012" }, { "n": "2011", "v": "/year/2011" }, { "n": "2010", "v": "/year/2010" }, { "n": "2009", "v": "/year/2009" }, { "n": "2008", "v": "/year/2008" }, { "n": "2007", "v": "/year/2007" }, { "n": "2006", "v": "/year/2006" }, { "n": "2005", "v": "/year/2005" }, { "n": "2004", "v": "/year/2004" }] }, { "key": "lang", "name": "语言", "value": [{ "n": "全部", "v": "" }, { "n": "国语", "v": "/lang/国语" }, { "n": "英语", "v": "/lang/英语" }, { "n": "粤语", "v": "/lang/粤语" }, { "n": "韩语", "v": "/lang/韩语" }, { "n": "日语", "v": "/lang/日语" }, { "n": "其它", "v": "/lang/其它" }] }, { "key": "by", "name": "排序", "value": [{ "n": "全部", "v": "" }, { "n": "时间", "v": "/by/time" }, { "n": "人气", "v": "/by/hits" }, { "n": "评分", "v": "/by/score" }] }], 13 | "3": [{ "key": "class", "name": "剧情", "value": [{ "n": "全部", "v": "" }, { "n": "选秀", "v": "/class/选秀" }, { "n": "情感", "v": "/class/情感" }, { "n": "访谈", "v": "/class/访谈" }, { "n": "播报", "v": "/class/播报" }, { "n": "旅游", "v": "/class/旅游" }, { "n": "音乐", "v": "/class/音乐" }, { "n": "美食", "v": "/class/美食" }, { "n": "纪实", "v": "/class/纪实" }, { "n": "曲艺", "v": "/class/曲艺" }, { "n": "生活", "v": "/class/生活" }, { "n": "游戏互动", "v": "/class/游戏互动" }, { "n": "财经", "v": "/class/财经" }, { "n": "求职", "v": "/class/求职" }] }, { "key": "area", "name": "地区", "value": [{ "n": "全部", "v": "" }, { "n": "内地", "v": "/area/内地" }, { "n": "港台", "v": "/area/港台" }, { "n": "日韩", "v": "/area/日韩" }, { "n": "欧美", "v": "/area/欧美" }] }, { "key": "lang", "name": "语言", "value": [{ "n": "全部", "v": "" }, { "n": "国语", "v": "/lang/国语" }, { "n": "英语", "v": "/lang/英语" }, { "n": "粤语", "v": "/lang/粤语" }, { "n": "韩语", "v": "/lang/韩语" }, { "n": "日语", "v": "/lang/日语" }, { "n": "其它", "v": "/lang/其它" }] }, { "key": "year", "name": "年份", "value": [{ "n": "全部", "v": "" }, { "n": "2025", "v": "/year/2025" },{ "n": "2024", "v": "/year/2024" }, { "n": "2023", "v": "/year/2023" }, { "n": "2022", "v": "/year/2022" }, { "n": "2021", "v": "/year/2021" }, { "n": "2020", "v": "/year/2020" }, { "n": "2019", "v": "/year/2019" }, { "n": "2018", "v": "/year/2018" }, { "n": "2017", "v": "/year/2017" }, { "n": "2016", "v": "/year/2016" }, { "n": "2015", "v": "/year/2015" }, { "n": "2014", "v": "/year/2014" }, { "n": "2013", "v": "/year/2013" }, { "n": "2012", "v": "/year/2012" }, { "n": "2011", "v": "/year/2011" }, { "n": "2010", "v": "/year/2010" }, { "n": "2009", "v": "/year/2009" }, { "n": "2008", "v": "/year/2008" }, { "n": "2007", "v": "/year/2007" }, { "n": "2006", "v": "/year/2006" }, { "n": "2005", "v": "/year/2005" }, { "n": "2004", "v": "/year/2004" }] }, { "key": "by", "name": "排序", "value": [{ "n": "全部", "v": "" }, { "n": "时间", "v": "/by/time" }, { "n": "人气", "v": "/by/hits" }, { "n": "评分", "v": "/by/score" }] }], 14 | "4": [{ "key": "class", "name": "剧情", "value": [{ "n": "全部", "v": "" }, { "n": "情感", "v": "/class/情感" }, { "n": "科幻", "v": "/class/科幻" }, { "n": "热血", "v": "/class/热血" }, { "n": "推理", "v": "/class/推理" }, { "n": "搞笑", "v": "/class/搞笑" }, { "n": "冒险", "v": "/class/冒险" }, { "n": "萝莉", "v": "/class/萝莉" }, { "n": "校园", "v": "/class/校园" }, { "n": "动作", "v": "/class/动作" }, { "n": "机战", "v": "/class/机战" }, { "n": "运动", "v": "/class/运动" }, { "n": "战争", "v": "/class/战争" }, { "n": "少年", "v": "/class/少年" }, { "n": "少女", "v": "/class/少女" }, { "n": "社会", "v": "/class/社会" }, { "n": "原创", "v": "/class/原创" }, { "n": "亲子", "v": "/class/亲子" }, { "n": "益智", "v": "/class/益智" }, { "n": "励志", "v": "/class/励志" }, { "n": "其它", "v": "/class/其他" }] }, { "key": "area", "name": "地区", "value": [{ "n": "全部", "v": "" }, { "n": "国产", "v": "/area/国产" }, { "n": "日本", "v": "/area/日本" }, { "n": "欧美", "v": "/area/欧美" }, { "n": "其他", "v": "/area/其他" }] }, { "key": "lang", "name": "语言", "value": [{ "n": "全部", "v": "" }, { "n": "国语", "v": "/lang/国语" }, { "n": "英语", "v": "/lang/英语" }, { "n": "粤语", "v": "/lang/粤语" }, { "n": "韩语", "v": "/lang/韩语" }, { "n": "日语", "v": "/lang/日语" }, { "n": "其它", "v": "/lang/其它" }] }, { "key": "year", "name": "年份", "value": [{ "n": "全部", "v": "" }, { "n": "2025", "v": "/year/2025" },{ "n": "2024", "v": "/year/2024" }, { "n": "2023", "v": "/year/2023" }, { "n": "2022", "v": "/year/2022" }, { "n": "2021", "v": "/year/2021" }, { "n": "2020", "v": "/year/2020" }, { "n": "2019", "v": "/year/2019" }, { "n": "2018", "v": "/year/2018" }, { "n": "2017", "v": "/year/2017" }, { "n": "2016", "v": "/year/2016" }, { "n": "2015", "v": "/year/2015" }, { "n": "2014", "v": "/year/2014" }, { "n": "2013", "v": "/year/2013" }, { "n": "2012", "v": "/year/2012" }, { "n": "2011", "v": "/year/2011" }, { "n": "2010", "v": "/year/2010" }, { "n": "2009", "v": "/year/2009" }, { "n": "2008", "v": "/year/2008" }, { "n": "2007", "v": "/year/2007" }, { "n": "2006", "v": "/year/2006" }, { "n": "2005", "v": "/year/2005" }, { "n": "2004", "v": "/year/2004" }] }, { "key": "by", "name": "排序", "value": [{ "n": "全部", "v": "" }, { "n": "时间", "v": "/by/time" }, { "n": "人气", "v": "/by/hits" }, { "n": "评分", "v": "/by/score" }] }] 15 | }, 16 | filter_def: { 17 | 1: { cateId: '1' }, 18 | 2: { cateId: '2' }, 19 | 3: { cateId: '3' }, 20 | 4: { cateId: '4' }, 21 | 13: { cateId: '13' }, 22 | 14: { cateId: '14' }, 23 | 15: { cateId: '15' }, 24 | 16: { cateId: '16' } 25 | }, 26 | searchUrl: '/vod/search.html?wd=**&submit=', 27 | searchable: 2,//是否启用全局搜索, 28 | quickSearch: 0,//是否启用快速搜索, 29 | filterable: 0,//是否启用分类筛选, 30 | play_parse: true, 31 | lazy: '', 32 | limit: 6, 33 | // 推荐:'ul.myui-vodlist;ul li;*;*;*;*', 34 | 推荐: 'ul.myui-vodlist;li;*;*;*;*', 35 | // 推荐:'ul.myui-vodlist;ul&&li;*;*;*;*', // 此写法本地js无效 36 | double: true, // 推荐内容是否双层定位 37 | 一级: '.myui-vodlist__box;a&&title;.lazyload&&data-original;.tag&&Text;a&&href', 38 | 二级: { 39 | "title": "h1&&Text;.data:eq(0) a:eq(0)&&Text", 40 | "img": ".lazyload&&data-original", 41 | "desc": ";.data:eq(0) a:eq(2)&&Text;.data:eq(0) a:eq(1)&&Text;.data:eq(2)&&Text;.data:eq(3)&&Text", 42 | "content": ".text-collapse span&&Text", 43 | "tabs": ".myui-panel__head h3", 44 | "lists": ".myui-content__list:eq(#id) li" 45 | }, 46 | 搜索: 'ul.myui-vodlist__media li;*;*;*;*', 47 | } 48 | -------------------------------------------------------------------------------- /back: -------------------------------------------------------------------------------- 1 | //{"key":"天翼资源","name":"天翼资源","type":1,"api":"https://www.911ysw.top/tianyi.php/provide/vod/","playUrl":"","searchable":1,"quickSearch":1 , "categories": ["国产剧", "综艺","动漫","动作片", "喜剧片", "爱情片", "科幻片", "恐怖片", "剧情片", "战争片","惊悚片","犯罪片","悬疑片","惊悚片", "港台剧", "日韩剧","泰国剧", "欧美剧" ] }, 2 | //{"key":"星辰","name":"星辰影院","type": 3,"api": "csp_XBPQ","ext": {"作者": "心动","站名": "星辰","主页url": "https://yyrj.site","搜索模式": "1","搜索url":"/index.php/vod/search/wd/{wd}.html","线路数组":"
    ","线路标题":"&&[不包含:飞刀资源]","分类url": "/index.php/vod/show/area/{area}/id/{cateId}/page/{catePg}/year/{year}.html","分类": "电影&电视剧&综艺&动漫&短剧","分类值": "1&2&3&4&5"}}, 3 | {"key": "hipy_js_8号影院","name": "8号影院","type": 3,"api": "https://yubox.xyz/drpy_libs/drpy2.min.js","searchable": 1,"quickSearch": 1,"filterable": 1,"order_num": 9,"ext": "https://yubox.xyz/drpy_js/8号影院.js"}, 4 | 5 | //{"key": "花姐影院","name": "花姐影院","type": 3,"api": "csp_XBPQ","searchable": 1,"quickSearch": 1,"filterable": 1,"ext": {"数组": "
  • ","搜索url": "https://www.huajie2.com/search.php?searchword={wd}", 6 | "分类url":"https://www.huajie2.com/search.php?searchtype=5&area={area}&class={class}&by={by}&year={year}&tid={cateId}&yuyan={lang}&page={catePg}","分类": "国产剧&电视剧&电影&综艺&动漫","分类值": "13&2&1&3&4&40"},"jar":"https://gitlab.com/xmbjm/omg/-/raw/main/jar/xyqxbpq.jar"}, 7 | 8 | //{"key":"cj_非凡量子","name":"非凡量子","type":1,"api":"https://xysjtv.yy365.vip/api.php/provide/vod/?ac=list","playurl": "https://tvmvip.com/lz2.php?url=","searchable":1,"quickSearch":1,"filterable":1,"changeable":1}, 9 | 10 | 11 | //{"key":"csp_U酷","name":"U酷资源","type":1,"api":"https://api.ukuapi.com/api.php/provide/vod/","playUrl":"","searchable":1,"quickSearch":1, "categories":["国产剧","短剧", "综艺", "动漫","动作片", "喜剧片", "爱情片", "科幻片", "恐怖片", "剧情片", "战争片","韩剧","港澳剧", "台湾剧", "日剧","泰剧","欧美剧", "日韩综艺", "港台综艺", "欧美综艺", "日韩动漫", "欧美动漫"] }, 12 | //{"key":"zy_云解析","name":"步步资源", "type":1, "api":"https://api.yparse.com/api/json","playurl":"https://yparse.ik9.cc/index.php?url=", "searchable": 1, "quickSearch": 1, "filterable": 1, "categories": ["短剧","国产剧","微电影","韩国剧","日本剧","泰国剧", "喜剧片", "爱情片", "科幻片", "恐怖片", "剧情片", "战争片", "纪录片","动画片", "香港剧", "台湾剧","欧美剧", "海外剧" ] }, 13 | //https://www.yparse.com/help 14 | //{"key":"zy_天空影视", "name": "天空资源", "type": 1, "api": "https://m3u8.tiankongapi.com/api.php/provide/vod/", "searchable": 1, "quickSearch": 1, "categories":["短剧","国产剧", "综艺", "大陆综艺", "国产动漫","动作片", "喜剧片", "爱情片", "科幻片", "恐怖片", "剧情片", "战争片", "动画片","奇幻片","灾难片","韩国剧", "台湾剧", "泰国剧", "日韩综艺", "港台综艺", "欧美综艺", "日本动漫", "欧美动漫" ,"其他片" ] }, 15 | //{"key":"zy_天空资源1", "name": "天空资源", "type": 1, "api": "http://api.tiankongapi.com/api.php/provide/vod/", "searchable": 1, "quickSearch": 1, "categories": ["短剧", "国产剧", "大陆综艺","国产动漫","动作片", "喜剧片", "爱情片", "科幻片", "恐怖片", "剧情片", "战争片", "纪录片", "悬疑片", "犯罪片", "动画片", "奇幻片", "香港剧", "台湾剧", "美国剧", "韩国剧", "日本剧","日韩综艺", "港台综艺", "欧美综艺", "国产动漫", "日韩动漫", "欧美动漫", "其他剧" ] }, 16 | 17 | //{"key":"zy_无尽", "name": "无尽资源","type": 1, "api": "https://api.wujinapi.com/api.php/provide/vod/", "searchable": 1, "quickSearch": 1, "categories":["国产剧", "综艺", "大陆综艺", "动漫","国产动漫","动作片", "喜剧片", "爱情片", "科幻片", "恐怖片", "剧情片", "战争片", "动画片","奇幻片","灾难片","韩国剧","香港剧", "台湾剧", "日本剧","泰国剧","美国剧", "日韩综艺", "港台综艺", "欧美综艺", "日韩动漫", "欧美动漫" ]}, 18 | //{"key":"zy_樱花资源", "name": "樱花资源", "type": 1, "api": "https://m3u8.apiyhzy.com/api.php/provide/vod/?ac=list", "searchable": 1, "quickSearch": 1,"categories": [ "国产剧","大陆综艺","动作片","喜剧片","爱情片", "科幻片", "恐怖片", "剧情片", "战争片", "纪录片", "悬疑片", "犯罪片", "动画片", "奇幻片", "香港剧", "台湾剧", "美国剧", "韩国剧", "日本剧","日韩综艺", "港台综艺", "欧美综艺", "国产动漫", "日韩动漫", "欧美动漫" ]}, 19 | ////樱花影视https://www.yhh888.cn/zxtype/23.html 20 | 21 | //{"key":"速播资源","name":"速播资源","type":1,"api":"https://subocaiji.com/api.php/provide/vod/","playUrl":"","searchable":1,"quickSearch":1 , "categories": ["大陆剧", "综艺","动漫","中国动漫","动作片", "喜剧片", "爱情片", "科幻片", "恐怖片", "剧情片", "战争片","动漫电影","港澳剧","台湾剧","韩剧", "日剧", "美剧","泰剧", "伦理片","日本动漫"] }, 22 | 23 | //{"key":"zy_飞速1","name":"飞速资源", "type": 1, "api": "https://www.feisuzy.com/api.php/provide/vod/", "searchable": 1, "quickSearch": 1, "categories": ["国产剧", "短剧", "大陆综艺","国产动漫","动作片", "喜剧片", "爱情片", "科幻片", "恐怖片", "剧情片", "战争片", "纪录片", "动画片","香港剧", "台湾剧", "欧美剧", "韩国剧", "日本剧","泰国剧","日韩综艺", "港台综艺", "欧美综艺", "日韩动漫", "欧美动漫", "其他片" ] }, 24 | //{"key":"zy_飞速2", "name": "飞速资源", "type": 1, "api": "https://www.feisuzyapi.com/api.php/provide/vod/", "searchable": 1, "quickSearch": 1, "categories": [ "国产剧","短剧", "大陆综艺","国产动漫","动作片", "喜剧片", "爱情片", "科幻片", "恐怖片", "剧情片", "战争片", "纪录片", "动画片","香港剧", "台湾剧", "欧美剧", "韩国剧", "日本剧","泰国剧","日韩综艺", "港台综艺", "欧美综艺", "日韩动漫", "欧美动漫", "其他片" ] }, 25 | //飞速资源:http://feisuzy.cc/,飞速 feisuzy.com、(fszy1-10).com、feisuzy.cc(总有一条可以打开) 26 | 27 | //{"key":"zy_金鹰","name": "金鹰资源", "type": 1, "api":"https://jyzyapi.com/provide/vod/from/jinyingyun/at/json","playurl": "https://hd.iapijy.com/play?url=", "searchable": 1, "quickSearch": 1, "categories": ["内地剧","短剧", "综艺","动作片", "喜剧片", "爱情片", "科幻片", "恐怖片", "剧情片", "战争片", "纪录片", "香港剧", "台湾剧", "美国剧", "韩剧", "日剧"] }, 28 | //域名: jinyingzy.com jinyingzy.net 备用域名: jyzy1.com jyzy2.com jyzy3.com m3u8 解析接口: https://hd.iapijy.com/play?url= 29 | 30 | //{"key":"zy_淘片","name":"淘片资源","type": 1,"api": "https://taopianapi.com/cjapi/mc/vod/json.html","searchable": 1,"quickSearch": 1,"filterable": 1,"categories":["电视剧/国产剧","综艺/大陆综艺","动漫/国产动漫","电视剧/韩国剧","综艺/日韩综艺","动漫/日本动漫","电影/动作片","电影/科幻片", "电影/奇幻片", "电影/喜剧片", "电影/爱情片", "电影/惊悚片", "电影/恐怖片","电影/纪录片","剧情片","电影/动画片","电影/冒险片","电影/战争片"]}, 31 | //https://taopianapi.com/cjapi/sda/vod/json/iframe.html,https://taopianapi.com/ 32 | 33 | //{"key":"虎牙资源","name":"虎牙资源","type":1,"api":"https://www.huyaapi.com/api.php/provide/vod/","playUrl":"","searchable":1,"quickSearch":1, "categories": ["短剧","内地剧","综艺","中国动漫","动画片","动作片", "喜剧片", "爱情片", "科幻片", "恐怖片", "剧情片", "战争片","记录片", "香港剧","韩剧","日剧","马泰剧","台湾剧", "日本动漫","欧美剧" ] }, 34 | 35 | //{"key":"csp_xBPQ_爱看影院","name":"️爱看影院","type":3,"api":"csp_XBPQ","searchable":1,"quickSearch":1,"filterable":1,"ext":{"分类url":"https://www.3wyy.com/vodshow/{cateId}-{area}-time-{class}-{lang}----{catePg}---{year}.html;;lr","分类":"电影$1#连续剧$2#综艺$3#动漫$4"}}, 36 | //{"key": "索尼资源","name": "索尼资源","type": 1,"api": "https://suoniapi.com/api.php/provide/vod/from/snm3u8/","categories": ["爽文短剧","国产剧","大陆综艺","国产动漫","动画片","动作片","喜剧片","爱情片","科幻片","恐怖片","剧情片","战争片","欧美剧","韩剧","日剧","港剧","台剧","泰剧","海外剧","纪录片","日韩综艺","港台综艺","欧美综艺","日韩动漫","欧美动漫","港台动漫","海外动漫","演唱会","体育赛事","篮球","足球","预告片","斯诺克","影视解说"],"searchable": 1,"quickSearch": 1}, 37 | //{"key":"爱坤资源","name":"爱坤影视","type":1,"api":"https://ikunzyapi.com/api.php/provide/vod/","playUrl":"","searchable":1,"quickSearch":1, "categories": ["爽文短剧","国产剧","大陆综艺","国产动漫","日韩综艺","动作片", "喜剧片", "爱情片", "科幻片", "恐怖片", "剧情片", "战争片","惊悚片","家庭片","古装片","犯罪片","悬疑片", "香港剧","韩国剧","日本剧","泰剧","欧美剧" ] }, 38 | //https://ikunzyapi.com/ 39 | //{"key":"zy_红牛","name":"红牛资源","type":1,"api": "https://www.hongniuzy2.com/api.php/provide/vod/","searchable": 1, "quickSearch": 1, "filterable": 1, "categories": [ "国产剧", "综艺","大陆综艺", "动漫","动作片", "喜剧片", "爱情片", "科幻片", "恐怖片", "剧情片", "战争片", "纪录片", "港澳剧", "台湾剧","日剧", "韩剧", "泰剧", "欧美剧", "欧美电影"]}, 40 | //{"key": "csp_非凡资源","name": "非凡资源","type": 1,"api": "http://cj.ffzyapi.com/api.php/provide/vod/","playurl": "https://tvmvip.com/lz2.php?url=","searchable": 1,"quickSearch": 1,"filterable": 1,"categories": ["国产剧","大陆综艺", "国产动漫","动作片","喜剧片","科幻片","恐怖片","爱情片","剧情片","战争片","记录片","欧美剧","香港剧","韩国剧","台湾剧","日本剧","海外剧","泰国剧","日韩动漫","欧美动漫","港台动漫","海外动漫","港台综艺","日韩综艺","欧美综艺"]}, 41 | //非凡资源备用网址:ffzy1.tv ffzy2.tv ffzy3.tv ffzy4.tv ffzy5.tv 42 | //{"key":"zy_百度","name":"百度资源","type": 1,"api": "https://api.apibdzy.com/api.php/provide/vod/?ac=list","searchable": 1,"quickSearch": 1,"filterable": 1,"playerType": 2,"categories": ["大陆剧","大陆综艺","国产动漫","动作片","喜剧片","科幻片","恐怖片","爱情片","剧情片","战争片","纪录片","动画电影","欧美剧","犯罪片","港澳剧","韩剧","泰剧","台湾剧","日剧","海外剧","其他片","悬疑片","奇幻片","动画片","体育赛事","日韩动漫","欧美动漫","港台动漫","海外动漫","港台综艺","日韩综艺","欧美综艺"]}, 43 | 44 | //{"key":"csp_AppYsV2_555","name":"555影视","type":3,"api":"csp_AppYsV2","searchable":1,"quickSearch":1,"filterable":1,"ext":"https://5flixs.net/api.php/app/"}, 45 | //555电影发布页:https://www.555dyy.top/ 笔盒18:https://beabox.xyz/;最新地址发布页beabox.tv,https://bihek.vip/,无法访问可发送邮件至beabox@email.com 46 | 47 | //{"key":"csp_Kuaikan","name":"快看影视","type":3,"api":"csp_Kuaikan","searchable":1,"quickSearch":1,"filterable":1",playerType":2,"changeable":1,"jar":"https://mirror.ghproxy.com/raw.githubusercontent.com/hanhan8127/TVBox/main/shenghan.jar"}, 48 | 49 | //{"key":"zy_光速", "name":"光速资源", "type": 1, "api": "https://api.guangsuapi.com/api.php/provide/vod/", "searchable": 1, "quickSearch": 1, "categories": ["短剧", "大陆剧", "综艺","动漫","动作片", "喜剧片", "爱情片", "科幻片", "恐怖片", "剧情片", "战争片", "纪录片","港澳剧", "台湾剧", "欧美剧", "韩剧", "日剧","泰剧" ] }, 50 | 51 | //{"key":"影图资源","name":"影图资源","type":1,"api":"https://cj.vodimg.top/api.php/provide/vod/","searchable":1,"quickSearch":1, "categories": ["电影","连续剧","国产剧", "综艺","动漫","动作片", "喜剧片", "爱情片", "科幻片", "恐怖片", "剧情片", "战争片", "港台剧", "日韩剧", "欧美剧" ]}, 52 | //{"key":"csp_暴风","name":"暴风资源","type": 1,"api": "https://bfzyapi.com/api.php/provide/vod/","searchable": 1,"quickSearch": 1,"filterable": 1,"playerType": 2,"categories":["国产剧","大陆综艺","国产动漫","日韩动漫","动作片","喜剧片","科幻片","恐怖片","爱情片","剧情片","战争片","纪录片","欧美剧","犯罪片","香港剧","韩国剧","台湾剧","日本剧","海外剧","其他片","悬疑片","奇幻片","动画片","日韩动漫","欧美动漫","港台动漫","海外动漫","港台综艺","日韩综艺","欧美综艺"]}, 53 | 54 | //{"key":"奇虎资源", "name":"奇虎资源", "type": 1, "api": "https://caiji.qhzyapi.com/api.php/provide/vod/?ac=list", "searchable": 1, "quickSearch": 1,"categories": ["短剧","国产剧","大陆综艺","国产动漫","韩国剧","动画片","剧情片","战争片","动作片","科幻片","记录片","爱情片","喜剧片","灾难片","日本动漫","欧美动漫","日本剧","泰国剧","台湾剧","香港剧","欧美剧","日韩综艺","港台综艺","欧美综艺"]}, 55 | //虎资源站:qihuzy.com,备用网址:qihuzy1.com至qihuzy9.com 56 | 57 | //{"key":"快云资源","name":"快云资源","type": 1,"api": "https://kuaiyun-api.com/api.php/provide/vod","searchable": 1,"quickSearch": 1,"filterable": 1,"changeable": 1,"categories": ["国产剧","国产综艺","国产动漫","日本动漫","动作片","爱情片","科幻片","恐怖片","奇幻片","战争片","喜剧片","动画电影","犯罪片","纪录片","欧美剧","港台剧","泰剧","港台综艺","日韩综艺","欧美综艺","韩国综艺","欧美动漫","日本剧","电影解说","奇幻片","灾难片","悬疑片","海外剧"]}, 58 | 59 | //{"key":"zy_八戒", "name":"八戒资源", "type": 1, "api": "http://cj.bajiecaiji.com/inc/apijson_vod.php","searchable": 1, "quickSearch": 1, "categories": ["国产剧", "大陆综艺","国产动漫","动作片", "喜剧片", "爱情片", "科幻片", "恐怖片", "剧情片", "战争片", "纪录片", "香港剧", "台湾剧", "韩国剧", "日本剧","泰国剧", "欧美剧", "日韩综艺", "港台综艺", "欧美综艺", "日韩动漫", "欧美动漫", "港台动漫" ] }, 60 | //http://cj.bajiecaiji.com/inc/api.php 61 | 62 | //{"key":"zy_快车资源","name":"快车资源", "type": 1, "api": "https://caiji.kczyapi.com/api.php/provide/vod/", "searchable": 1, "quickSearch": 1, "categories": [ "国产剧", "大陆综艺","动作片", "喜剧片", "爱情片", "科幻片", "恐怖片", "剧情片", "战争片", "香港剧", "台湾剧", "欧美剧", "韩国剧", "日本剧","日韩综艺", "港台综艺", "欧美综艺", "国产动漫", "日韩动漫", "欧美动漫" ] }, 63 | 64 | //{"key":"csp_SP360","name":"360影视","type":3,"playerType":2,"api":"csp_SP360","searchable":1,"quickSearch":1,"filterable":1,"changeable":0}, 65 | //{"key": "hipy_js_360影视[官]","name": "360影视","type": 3,"api": "https://yubox.xyz/drpy_libs/drpy2.min.js","searchable": 1,"quickSearch": 1,"filterable": 1,"order_num": 0,"ext": "https://yubox.xyz/drpy_js/360影视[官].js"}, 66 | //{"key": "苹果","name":"小苹果","type":3,"api":"csp_LiteApple","searchable":1,"quickSearch":1,"filterable":1,"changeable":1,"playerType":1}, 67 | 68 | //{"key":"vidhub","name":"影视视库","type":3,"api":"csp_WebVidHub","searchable":1,"quickSearch":0,"filterable":0,"ext":"https://vidhub1.cc"}, 69 | 70 | //{"key":"小镇","name":"电影小镇","type":3,"api":"csp_XBPQ","searchable":1,"quickSearch":1,"filterable":1,"ext":{"主页url":"http://dyxz.tv","数组":"
    &&
    ","图片":"data-original=\"&&\"","标题":"title=\"&&\"","链接":"href=\"&&\"","副标题":"&&","搜索url":"http://dyxz.tv/search.php;post;searchword={wd}","搜索模式":"1","搜索数组":"","搜索图片":"data-original=\"&&\"","搜索标题":"title=\"&&\"","搜索链接":"href=\"&&\"","搜索副标题":"&&","搜索后缀":"/view/","线路数组":"","线路标题":">&&<","播放数组":"
  • ","分类url":"http://yjsp.mxys8.com/index.php/vod/show/id/{cateId}/page/{catePg}.html","分类": "国产剧$13#电影$1#连续剧$2#动漫$4#综艺$3#纪录片$27"}}, 40 | //米 http://yj.appss.cc ////https://try.gogs.io/NB666/api/raw/main/config.bin http://yjsp.mxys8.com/index.php/vod/show/area/{area}/by/{by}/class/{class}/id/{cateId}/page/{catePg}/year/{year}.html 41 | 42 | {"key":"可可影视","name":"可可影视","type":3,"api":"csp_XBPQ","searchable":1,"quickSearch":1,"filterable":1, 43 | "ext":{"主页url":"https://www.keke1.app/","分类url":"/show/{cateId}-----3-{catePg}.html","分类":"电影$1#剧集$2#综艺$3#动漫$4#短剧$6", 44 | "数组": "默认--
    ||搜索--/detail&&","标题": "title\">&&&&&&&&&&&&&&&&&&[不包含:4K(高峰不卡)]","线路标题": "label\">&&<", 49 | "播放数组": "episode-list&&","播放标题": ">&&<","播放链接": "href=\"&&\"", 50 | "嗅探词": ".mp4#.m3u8","搜索请求头": "User-Agent$MOBILE_UA","搜索url": "/search?k={wd}&page={pg}","搜索模式": "1"}}, 51 | 52 | {"key":"毒舌影视","name":"毒舌影视","type":3,"api":"csp_XBPQ","searchable":1,"quickSearch":1,"filterable":1, 53 | "ext":{"主页url":"https://www.dushe6.app/","分类url":"/show/{cateId}-----3-{catePg}.html","分类":"电影$1#剧集$2#综艺$3#动漫$4#短剧$6", 54 | "数组": "默认--
    ||搜索--/detail&&","标题": "title\">&&&&&&&&&&&&&&&&&&[不包含:4K(高峰不卡)]","线路标题": "label\">&&<", 59 | "播放数组": "episode-list&&","播放标题": ">&&<","播放链接": "href=\"&&\"", 60 | "嗅探词": ".mp4#.m3u8","搜索请求头": "User-Agent$MOBILE_UA","搜索url": "/search?k={wd}&page={pg}","搜索模式": "1"}}, 61 | 62 | //https://dl.keke1.app/ https://www.keke1.app/ https://dl.dushe7.app/ https://www.dushe7.app dushe02.com dushe03.com dushe04.com 63 | 64 | {"key":"pianba","name":"片吧影视","type":3,"api":"csp_XBPQ","searchable":1,"quickSearch":1,"filterable":1, 65 | "ext":{"分类url": "https://www.ipianba.com/class/{cateId}-{area}-{by}--{lang}----{catePg}---{year}.html","分类": "电影$1#剧集$2#动漫$3#综艺$4"}}, 66 | {"key":"drpy_js_金牌1","name":"金牌影视","type":3,"api":"./lib/drpy2.min.js","ext":"./lib/金牌影视.js"}, 67 | {"key":"drpy_js_金牌","name":"金牌秒播","type":3,"api":"./lib/drpy2.min.js","ext":"./lib/金牌影视2.js"}, 68 | //https://www.cfkj86.com/ http://www.yuhelover.com/ https://www.ghw9zwp5.com https://chuang999.com/ https://helloux9w23vc.com/ www.y5yy.com https://www.hkybqufgh.com/ http://www.guanyugekj.com/ 69 | //https://gitee.com/senno/tvbox/raw/master/api.json; https://m.sunnafh.com/ https://www.gs4x7nq4.com/ https://ndhfiohk.com/ https://jieys.com/ https://www.vv3nwjk.com/ https://www.jpyy2.com/ 70 | //https://www.sizhengxt.com,https://www.sizhengxt.com,https://www.tjrongze.com,https://www.jiabaide.cn 71 | //https://fmbox.cc 电影先生:https://dyxs39.com/ DianYing.indyxs.medyxs.dedyxs32.comdyxs33.comdyxs34.comdyxs37.comdyxs38.comdyxs39.com 72 | //https://m66.yanjiusuo1137.top/ https://shujiazuoye.org/ ①yyyyy.tv ② yyyyy.at ③yyyyy.in ④ yyyyy.la ⑤ yyyyy.sbs https://aogv.tgcoohh7y7m.com/国色天香/ 73 | 74 | {"key":"Wwys","name":"旺旺影视","type":3,"quickSearch":1,"api":"csp_Wwys","ext":"https://www.wwgz.cn"}, 75 | 76 | //{"key":"baibai","name":"素白影视","type":3,"quickSearch":1,"api":"csp_SuBaiBai","ext":"https://www.subaibai.com"}, 77 | //{"key":"素白白","name":"素白白","type": 3,"api": "csp_XBPQ","searchable":1,"quickSearch":1,"filterable":1, 78 | // "ext":{"简介": "剧情介绍:+yp_context\">&&
    ","线路数组": "javascript:void(0);\">&&","播放数组": "paly_list_btn\">&&
    ","分类url": "https://www.subaibai.com/{cateId}/page/{catePg}[https://www.subaibai.com/{cateId}]","分类": "电视剧$tv-drama#国产剧$domestic-drama#电影$new-movie#热门电影$hot-month#高分电影$high-movie#欧美剧$american-drama#日韩剧$korean-drama#动漫电影$cartoon-movie#香港电影$cartoon-movie#动漫剧$anime-drama"}}, 79 | //https://subaibai.vip/ 80 | 81 | {"key": "jieys","name": "界影视","type": 3,"api": "https://raw.bgithub.xyz/MingHoChen/tvbox_cluntop/refs/heads/main/py/py_jieyingshi.py","searchable": 1,"quickSearch": 0,"filterable": 0,"changeable": 0}, 82 | 83 | {"key": "猫咪资源","name":"猫咪影院","type": 1,"api":"http://zy.xmm.hk/api.php/provide/vod/?ac=list","searchable": 1,"quickSearch": 1,"filterable": 1,"categories": ["电影","连续剧","综艺","动漫"]}, 84 | //主域名 :http://zy.xiaomaomi.cc/# zy.xmm.hk 85 | 86 | {"key": "狐狸君","name": "狐君4K","type": 3,"api": "csp_XBPQ","changeable": 1,"searchable": 1,"quickSearch": 1,"filterable": 1, 87 | "ext": {"搜索模式": "1","搜索url": "https://www.foxjun.com/s/?q={wd}","搜索数组": "class=\"media\">&&/div>", "搜索图片": "src=\"&&\"","搜索标题": "《&&》", 88 | "搜索副标题": "》&&\"","搜索链接": "href=\"&&\"","标题": "《&&》","副标题": "》&&\"","影片年代": "上映日期:&&

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

    ","主演": "主演:&&

    ","简介": "简介:&&

    ", 89 | "播放数组": "&&","播放列表": "[包含:magnet]","播放标题": ">&&<","播放链接": "href=\"&&\"","分类url": "https://www.foxjun.com/channel/{cateId}.html?apage1={catepg}", 90 | "分类": "国产剧$guochanju#电影$dianying#动画$donghua#美欧剧$meiouju#日韩剧$rihanju"}}, 91 | 92 | //{"key": "优质影视","name": "优质影视","type": 3,"api": "csp_XBPQ","ext": {"分类url":"https://www.myripon.com/index.php/vod/show/id/{cateId}/page/{catePg}.html","分类": "国产剧$13#电影$1#电视剧$2#综艺$3#动漫$4"}}, 93 | {"key": "永乐影视","name": "永乐影视","type": 3,"api": "csp_XBPQ","ext": {"分类url":"https://www.ylys.tv/vodshow/{cateId}--------{catePg}---/","分类": "国产剧$13#电视剧$2#电影$1#综艺$3#动漫$4"}}, 94 | {"key":"csp_红狐狸","name":"狐狸影视","type":3,"api":"csp_XBPQ","ext":{"分类url":"https://honghuli.com/show/{cateId}-{area}-------{catePg}---{year}.html","分类":"电影$1#电视剧$2#综艺$3#动漫$4"}}, 95 | 96 | {"key":"nkvod","name":"耐看观影","type":3,"api":"csp_XBPQ","ext":{"分类url":"https://www.nkvod.com/show/{cateId}--------{catePg}---.html","分类":"电视剧$2#电影$1#动漫$4#综艺$3"}}, 97 | {"key":"lkvod","name":"爱看影视","type":3,"api":"csp_XBPQ","ext":{"分类url":"https://www.lkvod.com/show/{cateId}--------{catePg}---.html","分类":"电视剧$2#电影$1#动漫$4#综艺$3"}}, 98 | // https://www.lkvod.me https://www.nkvod.me/ 99 | 100 | {"key":"热播影视","name":"热播影视","type": 3,"api": "csp_AppRJ","searchable": 1,"quickSearch": 1,"filterable": 0,"ext": {"url": "http://v.rbotv.cn"}}, 101 | 102 | //{"key":"bestpipe","name":"百思影视","type":3,"api":"csp_XBPQ","ext":{"分类url":"https://www.bestpipe.cn/vodshow/{cateId}-{area}-------{catePg}---.html","分类":"电影$20#剧集$21#短剧$24#综艺$23#动漫$22"}}, 103 | //{"key": "茶壶","name": "茶壶影视","type": 3,"api": "csp_XBPQ","ext": {"分类url":"https://www.htuys.com/search.php?page={catePg}&searchtype=5&tid={cateId}","分类": "国产剧$13#电视剧$2#电影$1#综艺$3#动漫$4"}}, 104 | //{"key": "枝枝影视","name": "枝枝影视","type": 3,"api": "csp_XBPQ","ext": {"分类url":"https://zzoc.cc/vodshow/{cateId}--time------{catePg}---.html","分类":"国产剧$13#电视剧$2#电影$1#综艺$3#短剧$20#动漫$4"}}, 105 | //{"key": "81影视","name": "八一影视","type": 3,"api": "csp_XBPQ","ext": {"分类url":"https://8scsi.com/by/{cateId}-{catePg}.html","分类": "国产剧$5#电视剧$1#电影$2#大陆综艺$22#综艺$3#动漫$4"}}, 106 | //http://www.88tvs.org/ 107 | //{"key":"蜜桃","name": "桃子影视","type": 3,"api": "csp_XBPQ","ext": {"分类url":"https://www.mtvod.cc/vodshow/id/{cateId}/page/{catePg}.html","分类": "国产剧$guochanju#电影$dianying#电视剧$juji#综艺$zongyi#动漫$dongman"}}, 108 | //{"key":"悟空","name": "悟空影视","type": 3,"api": "csp_XBPQ","ext": {"分类url":"https://www.wkvod.cc/vodshow/area/{cateId}/id/juji/page/{catePg}.html","分类":"国产剧$中国大陆#台湾剧$中国台湾#韩剧$韩国#美剧$美国#香港剧$中国香港"}}, 109 | //https://www.ffys.app https://www.mtvod.cc/ www.wkvod.cc https://www.wkvod.vip/ www.wkvod.top 110 | //{"key": "zhengsheng","name": "80影视","type": 3,"api": "csp_XBPQ","ext": {"分类url":"http://www.zhengshenggs.com/s/{cateId}/page/{catePg}.html","分类": "短剧$duanju#国产剧$guochanju#电影$dianying#日韩剧$rihanju#欧美剧$oumeiju#港台剧$gangtaiju"}}, 111 | //{"key":"厂长","name":"厂长影视","type":3,"playerType":"2","api":"csp_Czsapp","searchable":1,"quickSearch":1,"filterable":1,"ext": "https://www.czzymovie.com/"}, 112 | //易记域名CZ01.TV https://cz01.vip/ 推荐访问:www.czzymovie.com WWW.CZZY77.COM 113 | 114 | //{"key":"红果短剧","name":"红果短剧","type": 3,"api": "./lib/红果短剧.py","searchable": 1,"changeable": 1,"quickSearch": 1,"filterable": 1,"playerType": 2}, 115 | {"key":"甜圈短剧","name":"甜圈短剧","type": 3,"api": "./lib/甜圈短剧.py","searchable": 1,"changeable": 1,"quickSearch": 1,"filterable": 1,"playerType": 2}, 116 | {"key":"河马短剧","name":"河马短剧","type": 3,"api": "./lib/河马短剧.py","searchable": 1,"changeable": 1,"quickSearch": 1,"filterable": 1,"playerType": 2}, 117 | {"key":"星芽短剧2","name":"星芽短剧","type":3,"api":"https://weixine.net/js/lib/drpy2.min.js","ext": "https://weixine.net/js/xingya.js"}, 118 | 119 | {"key": "旺旺","name": "旺旺短剧","type": 1,"api": "https://api.wwzy.tv/api.php/provide/vod/?ac=list","playerType": 1,"searchable": 1,"changeable": 1}, 120 | 121 | {"key": "魔都资源","name": "魔都影院","type": 1,"api": "https://www.mdzyapi.com/api.php/provide/vod/?ac=list","searchable": 1,"quickSearch": 1,"filterable": 1, 122 | "categories": ["短剧","国产剧","大陆综艺", "国产动漫","动作","喜剧","网络电影","恐怖","惊悚","爱情","剧情","战争","冒险","韩国剧","台湾剧剧","日本剧","欧美剧","泰国剧","日本动漫","欧美动漫","港台综艺","日韩综艺","欧美综艺"]}, 123 | //魔都导航: https://www.moduzy.vip 魔都资源: https://www.moduzy.com 备用地址: moduzy1.com 至 moduzy10.com 124 | 125 | {"key": "电影天堂","name": "电影天堂","type": 1,"api": "https://caiji.dyttzyapi.com/api.php/provide/vod/?ac=list","searchable": 1,"quickSearch": 1,"filterable": 1, 126 | "categories": ["短剧","国产剧","大陆综艺", "国产动漫","韩国剧","动作片","喜剧片","动画片","恐怖片","爱情片","剧情片","战争片","记录片","欧美剧","香港剧","台湾剧","日本剧","海外剧","泰国剧","日韩动漫","欧美动漫","港台动漫","海外动漫","港台综艺","日韩综艺","欧美综艺"]}, 127 | // https://caiji.dyttzyapi.com/ dyttzy1.tv dyttzy2.tv dyttzy3.tv dyttzy4.tv dyttzy5.tv 128 | 129 | {"key": "天涯资源","name": "天涯影院","type": 1,"api": "https://ty.tyyszy5.com/api.php/provide/vod/?ac=list","searchable": 1,"quickSearch": 1,"filterable": 1, 130 | "categories": ["短剧","国产剧","大陆综艺", "国产动漫","动作","喜剧","网络电影","恐怖","惊悚","爱情","剧情","战争","冒险","欧美剧","港台剧","日韩剧","欧美剧","其他剧","日本动漫","欧美动漫","港台综艺","日韩综艺","欧美综艺"]}, 131 | //https://tyyszy.com/ https://tyyszyapi.com/api.php/provide/vod/?ac=list 132 | 133 | {"key": "非凡资源","name": "非凡影院","type": 1,"api": "http://ffzy.tv/api.php/provide/vod/","searchable": 1,"quickSearch": 1,"filterable": 1, 134 | "categories": ["短剧","国产剧","大陆综艺", "国产动漫","韩国剧","动作片","喜剧片","科幻片","恐怖片","爱情片","剧情片","战争片","记录片","欧美剧","香港剧","台湾剧","日本剧","海外剧","泰国剧","日韩动漫","欧美动漫","港台动漫","海外动漫","港台综艺","日韩综艺","欧美综艺"]}, 135 | //非凡资源备用网址:ffzy1.tv ffzy2.tv ffzy3.tv ffzy4.tv ffzy5.tv http://ffzy.tv/api.php/provide/vod/ 136 | 137 | {"key": "1080资源","name": "1080影院","type": 1,"api": "https://api.yzzy-api.com/inc/apijson.php","searchable": 1,"quickSearch": 1,"filterable": 1, 138 | "categories": ["短剧大全","国产剧","大陆综艺", "国产动漫","动作片","喜剧片","科幻片","恐怖片","爱情片","剧情片","战争片","记录片","韩国剧","欧美剧","香港剧","台湾剧","泰国剧","日韩动漫","欧美动漫","港台综艺","日韩综艺"]}, 139 | //优质 高清资源主域名:yzzy.tv hdzyk.com(备用网址): 1080zyk1.com 至 1080zyk20.com http://www.zhengshenggs.com/dplayeryes/index.php?url= 140 | {"key": "360资源","name": "360影院","type": 1,"api": "https://360zy.com/api.php/provide/vod","searchable": 1,"quickSearch": 1,"filterable": 1, 141 | "categories": ["爽文短剧","国产剧","大陆综艺", "国产动漫","韩国剧","动作片","喜剧片","科幻片","恐怖片","爱情片","剧情片","战争片","记录片","欧美剧","香港剧","台湾剧","泰国剧","日韩动漫","欧美动漫","港台综艺","日韩综艺"]}, 142 | //主域名 : 360zy.com 360zy.net 360zy.vip 360zy.top 360zy.tv 备用域名 :360zy1.com-360zy10.com 143 | {"key":"极速资源","name":"极速影院","type": 1,"api": "https://jszyapi.com/api.php/provide/vod/at/json","searchable": 1,"quickSearch": 1,"filterable": 1, 144 | "categories": ["短剧","内地剧","大陆综艺","中国动漫","动作片","喜剧片","爱情片","科幻片","恐怖片","剧情片","战争片","动画片","记录片","台湾剧","日剧","韩剧","马泰剧","港台综艺","日韩综艺","欧美综艺","日韩动漫","欧美动漫","港台动漫","海外动漫"]}, 145 | //https://jszyapi.com/ www.jisuzy.com www.jisuzy.tv www.jisuziyuan.com www.jszy666.com https://jisjiexi.com/play/?url= 146 | 147 | {"key":"360影视","name":"360影视","type":3,"api":"csp_SP360","searchable":1,"quickSearch":1,"filterable":1}, 148 | {"key":"bili","name":"哔哩哔哩","type":3,"playerType":"2","api":"https://tvbox.catvod.com/js/drpy2.min.js","ext":"https://tvbox.catvod.com/js/bili.js"}, 149 | {"key":"爱奇艺","name":"爱奇艺","type":3,"playerType":"2","api":"https://tvbox.catvod.com/js/drpy2.min.js","ext":"https://tvbox.catvod.com/js/aqy.js"}, 150 | {"key":"优酷","name":"优酷","type":3,"playerType":"2","api":"https://tvbox.catvod.com/js/drpy2.min.js","ext":"https://tvbox.catvod.com/js/yk.js"}, 151 | {"key":"腾讯","name":"腾讯","type":3,"playerType":"2","api":"https://tvbox.catvod.com/js/drpy2.min.js","ext":"https://tvbox.catvod.com/js/tx.js"}, 152 | {"key":"搜狗","name":"搜狗","type":3,"playerType":"2","api":"https://tvbox.catvod.com/js/drpy2.min.js","ext":"https://tvbox.catvod.com/js/sg.js"}, 153 | {"key":"MGTV","name":"芒果","type":3,"playerType":"2","api":"https://tvbox.catvod.com/js/drpy2.min.js","ext":"https://tvbox.catvod.com/js/mgtv.js"}, 154 | 155 | {"key":"zhuijuwu","name":"追剧影视","type":3,"api":"csp_XBPQ","searchable":1,"quickSearch":1,"filterable":1, 156 | "ext":{"线路数组":"","线路标题":">&&<","分类url":"https://zhuijuwu.com/frim/index{cateId}-{catePg}.html","分类":"大陆剧$13#电影$1#电视剧$2#综艺$3#动漫$4"}}, 157 | 158 | {"key": "csp_hanhan","name": "请勿相信影片广告!","type": 1,"playerType": 2,"api": "","searchable": 1,"quickSearch": 1,"filterable": 1} 159 | 160 | ], 161 | 162 | "parses":[ 163 | 164 | {"name":"Json聚合","type":3,"url":"Demo"}, 165 | {"name": "00","type":0,"url": "https://jx.nnxv.cn/tv.php?url="}, 166 | {"name":"线0","type":0,"url":"https://bd.jx.cn/?url="}, 167 | {"name":"线1","type":0,"url":"https://jx.hls.one/?url="}, 168 | {"name":"线2","type":0,"url":"https://jiexi.789jiexi.com/?url="}, 169 | {"name":"线3","type":0,"url": "https://www.pangujiexi.com/pangu/?url="}, 170 | {"name":"线4","type":0,"url": "https://jx.xmflv.cc/?url="}, 171 | {"name":"线5","type":0,"url":"https://www.playm3u8.cn/jiexi.php?url="}, 172 | {"name":"线6","type":0,"url":"https://www.8090g.cn/?url="}, 173 | {"name":"线7","type":0,"url":"https://www.pouyun.com/?url="}, 174 | {"name":"线8","type":0,"url":"https://jx.m3u8.tv/jiexi/?url="}, 175 | {"name":"线9","type":0,"url":"https://jx.2s0.cn/player/?url="}, 176 | {"name":"线10","type":0,"url":"https://www.yemu.xyz/?url="}, 177 | {"name":"线11","type":0,"url":"https://www.ckplayer.vip/jiexi/?url="}, 178 | {"name":"线12","type":0,"url":"https://jx.yparse.com/index.php?url="}, 179 | 180 | {"name":"胜寒欢迎您","type":0,"url":""} 181 | ], 182 | 183 | 184 | "flags":["youku","优酷","优 酷","优酷视频", "qq","腾讯","腾 讯","腾讯视频", "iqiyi", "qiyi","奇艺","爱奇艺","爱 奇 艺", "m1905", "xigua", "letv","leshi","乐视","乐 视", "sohu","搜狐","搜 狐","搜狐视频", "tudou","mgtv","芒果","imgo","芒果TV","芒 果 T V", "bilibili","哔 哩","哔 哩 哔 哩","SPA","YuMi-vip","pptv","PPTV","ltnb","rx","SLYS4k","tucheng","BYGA","luanzi","dxzy","QEYSS","aliyun","AliS","122","chuangying","CL4K","xfyun","wuduzy","wasu","renrenmi","ppayun","haiwaikan","cool","dbm3u8","xmm","funshion","ruyi1080","ruyib1080"], 185 | "doh":[{"name":"Google","url":"https://dns.google/dns-query","ips":["8.8.4.4","8.8.8.8"]}, 186 | {"name":"Cloudflare","url":"https://cloudflare-dns.com/dns-query","ips":["1.1.1.1","1.0.0.1","2606:4700:4700::1111","2606:4700:4700::1001"]}, 187 | {"name":"AdGuard","url":"https://dns.adguard.com/dns-query","ips":["94.140.14.140","94.140.14.141"]}, 188 | {"name":"DNSWatch","url":"https://resolver2.dns.watch/dns-query","ips":["84.200.69.80","84.200.70.40"]}, 189 | {"name":"Quad9","url":"https://dns.quad9.net/dns-quer","ips":["9.9.9.9","149.112.112.112"]}], 190 | 191 | "rules":[ 192 | {"name":"kk","hosts":["kuaikan"],"regex":["5","20.123","20.167","#EXT-X-DISCONTINUITY\\r*\\n*((?!#EXT-X-DISCONTINUITY)[\\s\\S])*?#EXT-X-KEY:METHOD((?!#EXT-X-DISCONTINUITY)[\\s\\S])*?#EXT-X-DISCONTINUITY"]}, 193 | {"name":"yqk","hosts":["yqk"],"regex":["18.4","15.1666","#EXT-X-DISCONTINUITY\\r*\\n*((?!#EXT-X-DISCONTINUITY)[\\s\\S])*?#EXT-X-CUE-OUT((?!#EXT-X-DISCONTINUITY)[\\s\\S])*?#EXT-X-CUE-IN"]}, 194 | {"name":"sn","hosts":["suonizy"],"regex":["#EXTINF.*?\\s+.*?original.*?\\.ts\\s+","15.1666","15.2666","16.3333","15.266667"]}, 195 | {"name":"bf","hosts":["bfzy"],"regex":["#EXT-X-DISCONTINUITY\\r*\\n*#EXTINF:3,[\\s\\S]*?#EXT-X-DISCONTINUITY"]}, 196 | {"name":"xx","hosts":["aws.ulivetv.net"],"regex":["#EXT-X-DISCONTINUITY\\r*\\n*#EXTINF:8,[\\s\\S]*?#EXT-X-DISCONTINUITY"]}, 197 | {"name":"lz","hosts":["vip.lz","hd.lz","v.cdnlz","yzzy1.play"],"regex":["18.5333","19.52","18.6666"]}, 198 | {"name":"ff","hosts":["vip.ffzy","hd.ffzy","ffzy"],"regex":["25.0666","25.08","20.52","25.1","25.1999"]}, 199 | {"name":"hs","hosts":["huoshan.com"],"regex":["item_id="]}, 200 | {"name":"dy","hosts":["douyin.com"],"regex":["is_play_url="]}, 201 | {"name":"nm","hosts":["toutiaovod.com"],"regex":["video/tos/cn"]}, 202 | {"name": "磁力","hosts": ["magnet"],"regex": ["更多","社 區","x u u","最 新","直 播","更 新","社 区","有 趣","英皇体育","全中文AV在线","澳门皇冠赌场","哥哥快来","美女荷官","裸聊","新片首发","UUE29"]} 203 | ] 204 | } 205 | -------------------------------------------------------------------------------- /lib/河马短剧.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import requests 3 | import re 4 | import json 5 | import traceback 6 | import sys 7 | 8 | sys.path.append('../../') 9 | try: 10 | from base.spider import Spider 11 | except ImportError: 12 | # 定义一个基础接口类,用于本地测试 13 | class Spider: 14 | def init(self, extend=""): 15 | pass 16 | 17 | class Spider(Spider): 18 | def __init__(self): 19 | self.siteUrl = "https://www.kuaikaw.cn" 20 | self.nextData = None # 缓存NEXT_DATA数据 21 | self.cateManual = { 22 | "甜宠": "462", 23 | "古装仙侠": "1102", 24 | "现代言情": "1145", 25 | "青春": "1170", 26 | "豪门恩怨": "585", 27 | "逆袭": "417-464", 28 | "重生": "439-465", 29 | "系统": "1159", 30 | "总裁": "1147", 31 | "职场商战": "943" 32 | } 33 | 34 | def getName(self): 35 | # 返回爬虫名称 36 | return "河马短剧" 37 | 38 | def init(self, extend=""): 39 | return 40 | 41 | def fetch(self, url, headers=None): 42 | """统一的网络请求接口""" 43 | if headers is None: 44 | headers = { 45 | "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 Edg/120.0.0.0", 46 | "Referer": self.siteUrl, 47 | "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8", 48 | "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8" 49 | } 50 | 51 | try: 52 | response = requests.get(url, headers=headers, timeout=10, allow_redirects=True) 53 | response.raise_for_status() 54 | return response 55 | except Exception as e: 56 | print(f"请求异常: {url}, 错误: {str(e)}") 57 | return None 58 | 59 | def isVideoFormat(self, url): 60 | # 检查是否为视频格式 61 | video_formats = ['.mp4', '.mkv', '.avi', '.wmv', '.m3u8', '.flv', '.rmvb'] 62 | for format in video_formats: 63 | if format in url.lower(): 64 | return True 65 | return False 66 | 67 | def manualVideoCheck(self): 68 | # 不需要手动检查 69 | return False 70 | 71 | def homeContent(self, filter): 72 | """获取首页分类及筛选""" 73 | result = {} 74 | # 分类列表,使用已初始化的cateManual 75 | classes = [] 76 | for k in self.cateManual: 77 | classes.append({ 78 | 'type_name': k, 79 | 'type_id': self.cateManual[k] 80 | }) 81 | result['class'] = classes 82 | # 获取首页推荐视频 83 | try: 84 | result['list'] = self.homeVideoContent()['list'] 85 | except: 86 | result['list'] = [] 87 | 88 | return result 89 | 90 | def homeVideoContent(self): 91 | """获取首页推荐视频内容""" 92 | videos = [] 93 | try: 94 | response = self.fetch(self.siteUrl) 95 | html_content = response.text 96 | # 提取NEXT_DATA JSON数据 97 | next_data_pattern = r'' 98 | next_data_match = re.search(next_data_pattern, html_content, re.DOTALL) 99 | if next_data_match: 100 | next_data_json = json.loads(next_data_match.group(1)) 101 | page_props = next_data_json.get("props", {}).get("pageProps", {}) 102 | # 获取轮播图数据 - 这些通常是推荐内容 103 | if "bannerList" in page_props and isinstance(page_props["bannerList"], list): 104 | banner_list = page_props["bannerList"] 105 | for banner in banner_list: 106 | book_id = banner.get("bookId", "") 107 | book_name = banner.get("bookName", "") 108 | cover_url = banner.get("coverWap", banner.get("wapUrl", "")) 109 | # 获取状态和章节数 110 | status = banner.get("statusDesc", "") 111 | total_chapters = banner.get("totalChapterNum", "") 112 | if book_id and book_name: 113 | videos.append({ 114 | "vod_id": f"/drama/{book_id}", 115 | "vod_name": book_name, 116 | "vod_pic": cover_url, 117 | "vod_remarks": f"{status} {total_chapters}集" if total_chapters else status 118 | }) 119 | 120 | # SEO分类下的推荐 121 | if "seoColumnVos" in page_props and isinstance(page_props["seoColumnVos"], list): 122 | for column in page_props["seoColumnVos"]: 123 | book_infos = column.get("bookInfos", []) 124 | for book in book_infos: 125 | book_id = book.get("bookId", "") 126 | book_name = book.get("bookName", "") 127 | cover_url = book.get("coverWap", "") 128 | status = book.get("statusDesc", "") 129 | total_chapters = book.get("totalChapterNum", "") 130 | 131 | if book_id and book_name: 132 | videos.append({ 133 | "vod_id": f"/drama/{book_id}", 134 | "vod_name": book_name, 135 | "vod_pic": cover_url, 136 | "vod_remarks": f"{status} {total_chapters}集" if total_chapters else status 137 | }) 138 | 139 | # # 去重 140 | # seen = set() 141 | # unique_videos = [] 142 | # for video in videos: 143 | # if video["vod_id"] not in seen: 144 | # seen.add(video["vod_id"]) 145 | # unique_videos.append(video) 146 | # videos = unique_videos 147 | 148 | except Exception as e: 149 | print(f"获取首页推荐内容出错: {e}") 150 | 151 | result = { 152 | "list": videos 153 | } 154 | return result 155 | 156 | def categoryContent(self, tid, pg, filter, extend): 157 | """获取分类内容""" 158 | result = {} 159 | videos = [] 160 | url = f"{self.siteUrl}/browse/{tid}/{pg}" 161 | response = self.fetch(url) 162 | html_content = response.text 163 | # 提取NEXT_DATA JSON数据 164 | next_data_pattern = r'' 165 | next_data_match = re.search(next_data_pattern, html_content, re.DOTALL) 166 | if next_data_match: 167 | next_data_json = json.loads(next_data_match.group(1)) 168 | page_props = next_data_json.get("props", {}).get("pageProps", {}) 169 | # 获取总页数和当前页 170 | current_page = page_props.get("page", 1) 171 | total_pages = page_props.get("pages", 1) 172 | # 获取书籍列表 173 | book_list = page_props.get("bookList", []) 174 | # 转换为通用格式 175 | for book in book_list: 176 | book_id = book.get("bookId", "") 177 | book_name = book.get("bookName", "") 178 | cover_url = book.get("coverWap", "") 179 | status_desc = book.get("statusDesc", "") 180 | total_chapters = book.get("totalChapterNum", "") 181 | if book_id and book_name: 182 | videos.append({ 183 | "vod_id": f"/drama/{book_id}", 184 | "vod_name": book_name, 185 | "vod_pic": cover_url, 186 | "vod_remarks": f"{status_desc} {total_chapters}集" if total_chapters else status_desc 187 | }) 188 | # 构建返回结果 189 | result = { 190 | "list": videos, 191 | "page": int(current_page), 192 | "pagecount": total_pages, 193 | "limit": len(videos), 194 | "total": total_pages * len(videos) if videos else 0 195 | } 196 | return result 197 | 198 | def switch(self, key, pg): 199 | # 搜索功能 200 | search_results = [] 201 | # 获取第一页结果,并检查总页数 202 | url = f"{self.siteUrl}/search?searchValue={key}&page={pg}" 203 | response = self.fetch(url) 204 | html_content = response.text 205 | # 提取NEXT_DATA JSON数据 206 | next_data_pattern = r'' 207 | next_data_match = re.search(next_data_pattern, html_content, re.DOTALL) 208 | if next_data_match: 209 | next_data_json = json.loads(next_data_match.group(1)) 210 | page_props = next_data_json.get("props", {}).get("pageProps", {}) 211 | # 获取总页数 212 | total_pages = page_props.get("pages", 1) 213 | # 处理所有页的数据 214 | all_book_list = [] 215 | # 添加第一页的书籍列表 216 | book_list = page_props.get("bookList", []) 217 | all_book_list.extend(book_list) 218 | # 如果有多页,获取其他页的数据 219 | if total_pages > 1 : # quick模式只获取第一页 220 | for page in range(2, total_pages + 1): 221 | next_page_url = f"{self.siteUrl}/search?searchValue={key}&page={page}" 222 | next_page_response = self.fetch(next_page_url) 223 | next_page_html = next_page_response.text 224 | next_page_match = re.search(next_data_pattern, next_page_html, re.DOTALL) 225 | if next_page_match: 226 | next_page_json = json.loads(next_page_match.group(1)) 227 | next_page_props = next_page_json.get("props", {}).get("pageProps", {}) 228 | next_page_books = next_page_props.get("bookList", []) 229 | all_book_list.extend(next_page_books) 230 | # 转换为统一的搜索结果格式 231 | for book in all_book_list: 232 | book_id = book.get("bookId", "") 233 | book_name = book.get("bookName", "") 234 | cover_url = book.get("coverWap", "") 235 | total_chapters = book.get("totalChapterNum", "0") 236 | status_desc = book.get("statusDesc", "") 237 | # 构建视频项 238 | vod = { 239 | "vod_id": f"/drama/{book_id}", 240 | "vod_name": book_name, 241 | "vod_pic": cover_url, 242 | "vod_remarks": f"{status_desc} {total_chapters}集" 243 | } 244 | search_results.append(vod) 245 | result = { 246 | "list": search_results, 247 | "page": pg 248 | } 249 | return result 250 | 251 | def searchContent(self, key, quick, pg=1): 252 | result = self.switch(key, pg=pg) 253 | result['page'] = pg 254 | return result 255 | 256 | def searchContentPage(self, key, quick, pg=1): 257 | return self.searchContent(key, quick, pg) 258 | 259 | def detailContent(self, ids): 260 | # 获取剧集信息 261 | vod_id = ids[0] 262 | episode_id = None 263 | chapter_id = None 264 | 265 | if not vod_id.startswith('/drama/'): 266 | if vod_id.startswith('/episode/'): 267 | episode_info = vod_id.replace('/episode/', '').split('/') 268 | if len(episode_info) >= 2: 269 | episode_id = episode_info[0] 270 | chapter_id = episode_info[1] 271 | vod_id = f'/drama/{episode_id}' 272 | else: 273 | vod_id = '/drama/' + vod_id 274 | 275 | drama_url = self.siteUrl + vod_id 276 | print(f"请求URL: {drama_url}") 277 | 278 | headers = { 279 | "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 Edg/120.0.0.0", 280 | "Referer": self.siteUrl, 281 | "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8", 282 | "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8" 283 | } 284 | 285 | rsp = self.fetch(drama_url, headers=headers) 286 | if not rsp or rsp.status_code != 200: 287 | print(f"请求失败,状态码: {getattr(rsp, 'status_code', 'N/A')}") 288 | return {} 289 | 290 | html = rsp.text 291 | next_data_match = re.search(r'', html, re.DOTALL) 292 | 293 | if not next_data_match: 294 | print("未找到NEXT_DATA内容") 295 | return {} 296 | 297 | try: 298 | next_data = json.loads(next_data_match.group(1)) 299 | page_props = next_data.get("props", {}).get("pageProps", {}) 300 | print(f"找到页面属性,包含 {len(page_props.keys())} 个键") 301 | 302 | book_info = page_props.get("bookInfoVo", {}) 303 | chapter_list = page_props.get("chapterList", []) 304 | 305 | title = book_info.get("title", "") 306 | sub_title = f"{book_info.get('totalChapterNum', '')}集" 307 | 308 | categories = [] 309 | for category in book_info.get("categoryList", []): 310 | categories.append(category.get("name", "")) 311 | 312 | vod_content = book_info.get("introduction", "") 313 | 314 | vod = { 315 | "vod_id": vod_id, 316 | "vod_name": title, 317 | "vod_pic": book_info.get("coverWap", ""), 318 | "type_name": ",".join(categories), 319 | "vod_year": "", 320 | "vod_area": book_info.get("countryName", ""), 321 | "vod_remarks": sub_title, 322 | "vod_actor": ", ".join([p.get("name", "") for p in book_info.get("performerList", [])]), 323 | "vod_director": "", 324 | "vod_content": vod_content 325 | } 326 | 327 | # 处理播放列表 328 | play_url_list = [] 329 | episodes = [] 330 | 331 | if chapter_list: 332 | print(f"找到 {len(chapter_list)} 个章节") 333 | 334 | # 先检查是否有可以直接使用的MP4链接作为模板 335 | mp4_template = None 336 | first_mp4_chapter_id = None 337 | 338 | # 先搜索第一个章节的MP4链接 339 | # 为提高成功率,尝试直接请求第一个章节的播放页 340 | if chapter_list and len(chapter_list) > 0: 341 | first_chapter = chapter_list[0] 342 | first_chapter_id = first_chapter.get("chapterId", "") 343 | drama_id_clean = vod_id.replace('/drama/', '') 344 | 345 | if first_chapter_id and drama_id_clean: 346 | first_episode_url = f"{self.siteUrl}/episode/{drama_id_clean}/{first_chapter_id}" 347 | print(f"请求第一集播放页: {first_episode_url}") 348 | 349 | first_rsp = self.fetch(first_episode_url, headers=headers) 350 | if first_rsp and first_rsp.status_code == 200: 351 | first_html = first_rsp.text 352 | # 直接从HTML提取MP4链接 353 | mp4_pattern = r'(https?://[^"\']+\.mp4)' 354 | mp4_matches = re.findall(mp4_pattern, first_html) 355 | if mp4_matches: 356 | mp4_template = mp4_matches[0] 357 | first_mp4_chapter_id = first_chapter_id 358 | print(f"找到MP4链接模板: {mp4_template}") 359 | print(f"模板对应的章节ID: {first_mp4_chapter_id}") 360 | 361 | # 如果未找到模板,再检查章节对象中是否有MP4链接 362 | if not mp4_template: 363 | for chapter in chapter_list[:5]: # 只检查前5个章节以提高效率 364 | if "chapterVideoVo" in chapter and chapter["chapterVideoVo"]: 365 | chapter_video = chapter["chapterVideoVo"] 366 | mp4_url = chapter_video.get("mp4", "") or chapter_video.get("mp4720p", "") or chapter_video.get("vodMp4Url", "") 367 | if mp4_url and ".mp4" in mp4_url: 368 | mp4_template = mp4_url 369 | first_mp4_chapter_id = chapter.get("chapterId", "") 370 | print(f"从chapterVideoVo找到MP4链接模板: {mp4_template}") 371 | print(f"模板对应的章节ID: {first_mp4_chapter_id}") 372 | break 373 | 374 | # 遍历所有章节处理播放信息 375 | for chapter in chapter_list: 376 | chapter_id = chapter.get("chapterId", "") 377 | chapter_name = chapter.get("chapterName", "") 378 | 379 | # 1. 如果章节自身有MP4链接,直接使用 380 | if "chapterVideoVo" in chapter and chapter["chapterVideoVo"]: 381 | chapter_video = chapter["chapterVideoVo"] 382 | mp4_url = chapter_video.get("mp4", "") or chapter_video.get("mp4720p", "") or chapter_video.get("vodMp4Url", "") 383 | if mp4_url and ".mp4" in mp4_url: 384 | episodes.append(f"{chapter_name}${mp4_url}") 385 | continue 386 | 387 | # 2. 如果有MP4模板,尝试替换章节ID构建MP4链接 388 | if mp4_template and first_mp4_chapter_id and chapter_id: 389 | # 替换模板中的章节ID部分 390 | if first_mp4_chapter_id in mp4_template: 391 | new_mp4_url = mp4_template.replace(first_mp4_chapter_id, chapter_id) 392 | episodes.append(f"{chapter_name}${new_mp4_url}") 393 | continue 394 | 395 | # 3. 如果上述方法都不可行,回退到使用chapter_id构建中间URL 396 | if chapter_id and chapter_name: 397 | url = f"{vod_id}${chapter_id}${chapter_name}" 398 | episodes.append(f"{chapter_name}${url}") 399 | 400 | if not episodes and vod_id: 401 | # 尝试构造默认的集数 402 | total_chapters = int(book_info.get("totalChapterNum", "0")) 403 | if total_chapters > 0: 404 | print(f"尝试构造 {total_chapters} 个默认集数") 405 | 406 | # 如果知道章节ID的模式,可以构造 407 | if chapter_id and episode_id: 408 | for i in range(1, total_chapters + 1): 409 | chapter_name = f"第{i}集" 410 | url = f"{vod_id}${chapter_id}${chapter_name}" 411 | episodes.append(f"{chapter_name}${url}") 412 | else: 413 | # 使用普通的构造方式 414 | for i in range(1, total_chapters + 1): 415 | chapter_name = f"第{i}集" 416 | url = f"{vod_id}${chapter_name}" 417 | episodes.append(f"{chapter_name}${url}") 418 | 419 | if episodes: 420 | play_url_list.append("#".join(episodes)) 421 | vod['vod_play_from'] = '河马剧场' 422 | vod['vod_play_url'] = '$$$'.join(play_url_list) 423 | 424 | result = { 425 | 'list': [vod] 426 | } 427 | return result 428 | except Exception as e: 429 | print(f"解析详情页失败: {str(e)}") 430 | print(traceback.format_exc()) 431 | return {} 432 | 433 | def playerContent(self, flag, id, vipFlags): 434 | result = {} 435 | print(f"调用playerContent: flag={flag}, id={id}") 436 | 437 | headers = { 438 | "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 Edg/120.0.0.0", 439 | "Referer": self.siteUrl, 440 | "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8", 441 | "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8" 442 | } 443 | 444 | # 解析id参数 445 | parts = id.split('$') 446 | drama_id = None 447 | chapter_id = None 448 | 449 | if len(parts) >= 2: 450 | drama_id = parts[0] 451 | chapter_id = parts[1] 452 | chapter_name = parts[2] if len(parts) > 2 else "第一集" 453 | print(f"解析参数: drama_id={drama_id}, chapter_id={chapter_id}") 454 | else: 455 | # 处理旧数据格式 456 | print(f"使用原始URL格式: {id}") 457 | result["parse"] = 0 458 | result["url"] = id 459 | result["header"] = json.dumps(headers) 460 | return result 461 | 462 | # 直接检查chapter_id是否包含http(可能已经是视频链接) 463 | if 'http' in chapter_id and '.mp4' in chapter_id: 464 | print(f"已经是MP4链接: {chapter_id}") 465 | result["parse"] = 0 466 | result["url"] = chapter_id 467 | result["header"] = json.dumps(headers) 468 | return result 469 | 470 | # 构建episode页面URL 471 | drama_id_clean = drama_id.replace('/drama/', '') 472 | episode_url = f"{self.siteUrl}/episode/{drama_id_clean}/{chapter_id}" 473 | print(f"请求episode页面: {episode_url}") 474 | 475 | try: 476 | rsp = self.fetch(episode_url, headers=headers) 477 | if not rsp or rsp.status_code != 200: 478 | print(f"请求失败,状态码: {getattr(rsp, 'status_code', 'N/A')}") 479 | result["parse"] = 0 480 | result["url"] = id 481 | result["header"] = json.dumps(headers) 482 | return result 483 | 484 | html = rsp.text 485 | print(f"获取页面大小: {len(html)} 字节") 486 | 487 | # 尝试从NEXT_DATA提取视频链接 488 | mp4_url = None 489 | 490 | # 方法1: 从NEXT_DATA提取 491 | next_data_match = re.search(r'', html, re.DOTALL) 492 | if next_data_match: 493 | try: 494 | print("找到NEXT_DATA") 495 | next_data = json.loads(next_data_match.group(1)) 496 | page_props = next_data.get("props", {}).get("pageProps", {}) 497 | 498 | # 从chapterList中查找当前章节 499 | chapter_list = page_props.get("chapterList", []) 500 | print(f"找到章节列表,长度: {len(chapter_list)}") 501 | 502 | for chapter in chapter_list: 503 | if chapter.get("chapterId") == chapter_id: 504 | print(f"找到匹配的章节: {chapter.get('chapterName')}") 505 | chapter_video = chapter.get("chapterVideoVo", {}) 506 | mp4_url = chapter_video.get("mp4", "") or chapter_video.get("mp4720p", "") or chapter_video.get("vodMp4Url", "") 507 | if mp4_url: 508 | print(f"从chapterList找到MP4链接: {mp4_url}") 509 | break 510 | 511 | # 如果未找到,尝试从当前章节获取 512 | if not mp4_url: 513 | current_chapter = page_props.get("chapterInfo", {}) 514 | if current_chapter: 515 | print("找到当前章节信息") 516 | chapter_video = current_chapter.get("chapterVideoVo", {}) 517 | mp4_url = chapter_video.get("mp4", "") or chapter_video.get("mp4720p", "") or chapter_video.get("vodMp4Url", "") 518 | if mp4_url: 519 | print(f"从chapterInfo找到MP4链接: {mp4_url}") 520 | except Exception as e: 521 | print(f"解析NEXT_DATA失败: {str(e)}") 522 | print(traceback.format_exc()) 523 | 524 | # 方法2: 直接从HTML中提取MP4链接 525 | if not mp4_url: 526 | mp4_pattern = r'(https?://[^"\']+\.mp4)' 527 | mp4_matches = re.findall(mp4_pattern, html) 528 | if mp4_matches: 529 | # 查找含有chapter_id的链接 530 | matched_mp4 = False 531 | for url in mp4_matches: 532 | if chapter_id in url: 533 | mp4_url = url 534 | matched_mp4 = True 535 | print(f"从HTML直接提取章节MP4链接: {mp4_url}") 536 | break 537 | 538 | # 如果没找到包含chapter_id的链接,使用第一个 539 | if not matched_mp4 and mp4_matches: 540 | mp4_url = mp4_matches[0] 541 | print(f"从HTML直接提取MP4链接: {mp4_url}") 542 | 543 | if mp4_url and ".mp4" in mp4_url: 544 | print(f"最终找到的MP4链接: {mp4_url}") 545 | result["parse"] = 0 546 | result["url"] = mp4_url 547 | result["header"] = json.dumps(headers) 548 | return result 549 | else: 550 | print(f"未找到有效的MP4链接,尝试再次解析页面内容") 551 | # 再尝试一次从HTML中广泛搜索所有可能的MP4链接 552 | all_mp4_pattern = r'(https?://[^"\']+\.mp4)' 553 | all_mp4_matches = re.findall(all_mp4_pattern, html) 554 | if all_mp4_matches: 555 | mp4_url = all_mp4_matches[0] 556 | print(f"从HTML广泛搜索找到MP4链接: {mp4_url}") 557 | result["parse"] = 0 558 | result["url"] = mp4_url 559 | result["header"] = json.dumps(headers) 560 | return result 561 | 562 | print(f"未找到视频链接,返回原episode URL: {episode_url}") 563 | result["parse"] = 0 564 | result["url"] = episode_url 565 | result["header"] = json.dumps(headers) 566 | return result 567 | except Exception as e: 568 | print(f"请求或解析失败: {str(e)}") 569 | print(traceback.format_exc()) 570 | result["parse"] = 0 571 | result["url"] = id 572 | result["header"] = json.dumps(headers) 573 | return result 574 | 575 | def localProxy(self, param): 576 | # 本地代理处理,此处简单返回传入的参数 577 | return [200, "video/MP2T", {}, param] 578 | 579 | def destroy(self): 580 | # 资源回收 581 | pass -------------------------------------------------------------------------------- /zyhan.json: -------------------------------------------------------------------------------- 1 | { 2 | "analyze": [ 3 | {"id": 1,"name": "寒00","url": "https://im1907.top/?jx=","isActive": true}, 4 | {"id": 2,"name": "寒01","url": "https://jx.dj6u.com/?url=","isActive": true}, 5 | {"id": 3,"name": "寒02","url": "https://jx.yangtu.top/?url=","isActive": true}, 6 | {"id": 4,"name": "寒03","url": "https://jx.xmflv.com/?url=","isActive": true}, 7 | {"id": 5,"name": "寒04","url": "https://okjx.cc/?url=","isActive": false}, 8 | {"id": 6,"name": "寒05","url": "https://www.yemu.xyz/?url=","isActive": true}, 9 | {"id": 7,"name": "寒06","url": "https://jx.m3u8.tv/jiexi/?url=","isActive": true}, 10 | {"id": 8,"name": "寒07","url": "https://jx.blbo.cc:4433/?url=","isActive": false}, 11 | {"id": 9,"name": "寒08","url": "http://vip.wpsseo.cn/jx/?url=","isActive": false}, 12 | {"id": 10,"name": "寒09","url": "https://www.8090g.cn/?url=","isActive": false}, 13 | {"id": 11,"name": "寒10","url": "https://www.playm3u8.cn/jiexi.php?url=","isActive": false}, 14 | {"id": 12,"name": "寒11","url": "http://42.157.129.144:2323/CH/caihong_1993138546.php?url=","isActive": false}, 15 | {"id": 13,"name": "寒12","url": "https://www.pouyun.com/?url=","isActive": false}, 16 | {"id": 14,"name": "寒13","url": "http://119.91.123.253:2345/Api/yun.php?url=","isActive": false}, 17 | {"id": 15,"name": "寒14","url": "https://www.ckplayer.vip/jiexi/?url=","isActive": false}, 18 | {"id": 16,"name": "寒15","url": "https://api.quanminjiexi.com/?v=","isActive": false}, 19 | {"id": 17,"name": "寒16","url": "https://vip.bljiex.com/?v=","isActive": false}, 20 | {"id": 18,"name": "寒17","url": "https://api.jiexi.la/?url=","isActive": false}, 21 | {"id": 19,"name": "寒18","url": "https://jiexi.janan.net/jiexi/?url=","isActive": true}, 22 | {"id": 20,"name": "寒19","url": "https://www.mtosz.com/m3u8.php?url=","isActive": false}, 23 | {"id": 21,"name": "寒20","url": "https://www.pangujiexi.cc/jiexi.php?url=","isActive": false}, 24 | {"id": 22,"name": "寒21","url": "https://go.yh0523.cn/y.cy?url=","isActive": false}, 25 | {"id": 23,"name": "寒22","url": "https://www.1717yun.com/jx/ty.php?url=","isActive": false}, 26 | {"id": 24,"name": "寒23","url": "https://jx.4kdv.com/?url=","isActive": false}, 27 | {"id": 25,"name": "寒24","url": "https://jx.000180.top/jx/?url=","isActive": false}, 28 | {"id": 26,"name": "寒25","url": "https://www.administratorw.com/video.php?url=","isActive": false}, 29 | {"id": 27,"name": "寒26","url": "https://jx.jsonplayer.com/player/?url=","isActive": false}, 30 | {"id": 28,"name": "寒27","url": "https://jx.playerjy.com/?url=","isActive": true,"id": 250} 31 | ], 32 | 33 | "iptv": [ 34 | { 35 | "id": 1, 36 | "name": "胜寒1", 37 | "url": "https://github.moeyy.xyz/raw.bgithub.xyz/hanhan8127/TVBox/main/live.txt", 38 | "type": "remote", 39 | "isActive": true, 40 | "epg": "https://epg.112114.xyz/" 41 | }, 42 | { 43 | "id": 2, 44 | "name": "胜寒2", 45 | "url": "https://mirror.ghproxy.com/raw.bgithub.xyz/hanhan8127/TVBox/main/live.txt", 46 | "isActive": true, 47 | "type": "remote", 48 | "epg": "https://epg.112114.xyz/" 49 | }, 50 | { 51 | "id": 3, 52 | "name": "888", 53 | "url": "http://a.rihou.cc/lib/live.txt", 54 | "isActive": true, 55 | "type": "remote", 56 | "epg": "https://epg.112114.xyz/" 57 | }, 58 | 59 | { 60 | "name": "999", 61 | "url": "http://qrh.yimkj.cn/ym/lib/zb1122.txt", 62 | "epg": "https://epg.112114.xyz/", 63 | "type": "remote", 64 | "isActive": true, 65 | "id": 4 66 | } 67 | ], 68 | 69 | "sites": [ 70 | 71 | { 72 | "key": "cb658939-5abf-5d37-81d9-16633d80818e", 73 | "name": "胜寒推荐", 74 | "api": "https://api.1080zyku.com/inc/apijson.php", 75 | "download": "", 76 | "playUrl": "", 77 | "group": "影视", 78 | "search": 1, 79 | "status": true, 80 | "type": 1, 81 | "id": 1, 82 | "isActive": true, 83 | "resource": 48916 84 | }, 85 | { 86 | "key": "lziapi", 87 | "name": "量子资源", 88 | "api": "http://cj.lziapi.com/api.php/provide/vod/", 89 | "playUrl": "", 90 | "search": 1, 91 | "group": "切片", 92 | "status": true, 93 | "type": 1, 94 | "id": 2, 95 | "isActive": true, 96 | "resource": 75607 97 | }, 98 | { 99 | "key": "apibdzy", 100 | "name": "百度云", 101 | "api": "https://api.apibdzy.com/api.php/provide/vod/", 102 | "playUrl": "", 103 | "search": 0, 104 | "group": "切片", 105 | "status": true, 106 | "type": 1, 107 | "id": 3, 108 | "isActive": true, 109 | "resource": 45213 110 | }, 111 | { 112 | "key": "xinlangapi", 113 | "name": "新浪资源", 114 | "api": "https://api.xinlangapi.com/xinlangapi.php/provide/vod/", 115 | "playUrl": "", 116 | "search": 1, 117 | "group": "切片", 118 | "status": true, 119 | "type": 1, 120 | "id": 4, 121 | "isActive": true, 122 | "resource": 48942 123 | }, 124 | //新浪资源备用网址:xinlangzy.com、xinlangziyuan.com 125 | { 126 | "key": "39kan", 127 | "name": "39影视", 128 | "api": "https://www.39kan.com/api.php/provide/vod/", 129 | "playUrl": "", 130 | "search": 1, 131 | "group": "切片", 132 | "status": false, 133 | "type": 1, 134 | "id": 5 135 | }, 136 | { 137 | "key": "vipmv", 138 | "name": "天堂资源", 139 | "api": "http://vipmv.cc/api.php/provide/vod/", 140 | "playUrl": "", 141 | "search": 1, 142 | "group": "切片", 143 | "status": true, 144 | "type": 1, 145 | "id": 6 146 | }, 147 | { 148 | "key": "wolongzyw", 149 | "name": "卧龙资源", 150 | "api": "https://collect.wolongzyw.com/api.php/provide/vod/", 151 | "playUrl": "", 152 | "search": 1, 153 | "group": "切片", 154 | "status": true, 155 | "type": 1, 156 | "id": 7, 157 | "isActive": true, 158 | "resource": 65188 159 | }, 160 | { 161 | "key": "6Uzy", 162 | "name": "6U资源", 163 | "api": "http://zy.ataoju.com/inc/api.php", 164 | "playUrl": "", 165 | "search": 1, 166 | "group": "切片", 167 | "status": false, 168 | "type": 1, 169 | "id": 8 170 | }, 171 | 172 | { 173 | "key": "foxzyapi", 174 | "name": "FOX资源", 175 | "api": "https://api.foxzyapi.com/api.php/provide/vod/", 176 | "playUrl": "", 177 | "search": 1, 178 | "group": "切片", 179 | "status": false, 180 | "type": 1, 181 | "id": 9 182 | }, 183 | { 184 | "key": "lehootv", 185 | "name": "乐活影视", 186 | "api": "https://lehootv.com/api.php/provide/vod/", 187 | "playUrl": "", 188 | "search": 1, 189 | "group": "切片", 190 | "status": false, 191 | "type": 1, 192 | "id": 10 193 | }, 194 | { 195 | "key": "kuaibozy", 196 | "name": "快播资源", 197 | "api": "http://www.kuaibozy.com/api.php/provide/vod/", 198 | "playUrl": "", 199 | "search": 1, 200 | "group": "切片", 201 | "status": false, 202 | "type": 11, 203 | "id": 8 204 | }, 205 | 206 | { 207 | "key": "tomziyuan", 208 | "name": "tom资源网", 209 | "api": "https://tomziyuan.com/api.php/provide/vod/", 210 | "playUrl": "", 211 | "search": 1, 212 | "group": "切片", 213 | "status": false, 214 | "type": 1, 215 | "id": 12 216 | }, 217 | { 218 | "key": "明帝影视", 219 | "name": "明帝影视", 220 | "api": "https://ys.md214.cn/api.php/provide/vod/", 221 | "playUrl": "", 222 | "search": 1, 223 | "group": "切片", 224 | "status": true, 225 | "type": 1, 226 | "id": 13 227 | }, 228 | { 229 | "key": "kudianzy", 230 | "name": "酷点资源", 231 | "api": "https://kudianzy.com/api.php/provide/vod/", 232 | "playUrl": "", 233 | "search": 1, 234 | "group": "切片", 235 | "status": false, 236 | "type": 1, 237 | "id": 14 238 | }, 239 | { 240 | "key": "taopianapi", 241 | "name": "淘片资源", 242 | "api": "https://taopianapi.com/home/cjapi/as/mc10/vod/json", 243 | "playUrl": "", 244 | "search": 1, 245 | "group": "切片", 246 | "status": true, 247 | "type": 1, 248 | "id": 15 249 | }, 250 | { 251 | "key": "快车资源", 252 | "name": "快车资源", 253 | "api": "https://caiji.kczyapi.com/api.php/provide/vod/", 254 | "playUrl": "", 255 | "search": 1, 256 | "group": "切片", 257 | "status": true, 258 | "type": 1, 259 | "id": 16, 260 | "isActive": true, 261 | "resource": 32427 262 | }, 263 | { 264 | "key": "yulecj", 265 | "name": "鱼乐资源网", 266 | "api": "https://api.yulecj.com/api.php/provide/vod/", 267 | "playUrl": "", 268 | "search": 1, 269 | "group": "切片", 270 | "status": true, 271 | "type": 1, 272 | "id": 17 273 | }, 274 | { 275 | "key": "sdzyapi", 276 | "name": "闪电资源网", 277 | "api": "https://sdzyapi.com/api.php/provide/vod/", 278 | "playUrl": "", 279 | "search": 1, 280 | "group": "切片", 281 | "status": true, 282 | "type": 1, 283 | "id": 18 284 | }, 285 | { 286 | "key": "yparse", 287 | "name": "步步高资源", 288 | "api": "https://api.yparse.com/api/json", 289 | "playUrl": "", 290 | "search": 1, 291 | "group": "切片", 292 | "status": true, 293 | "type": 1, 294 | "id": 19, 295 | "isActive": true, 296 | "resource": 178984 297 | }, 298 | { 299 | "key": "ckzy", 300 | "name": "CK资源", 301 | "api": "https://ckzy.me/api.php/provide/vod/", 302 | "playUrl": "", 303 | "search": 1, 304 | "group": "切片", 305 | "status": false, 306 | "type": 1, 307 | "id": 20 308 | }, 309 | { 310 | "key": "guangsuapi", 311 | "name": "光速资源", 312 | "api": "https://api.guangsuapi.com/api.php/provide/vod/", 313 | "playUrl": "", 314 | "search": 1, 315 | "group": "切片", 316 | "status": true, 317 | "type": 1, 318 | "id": 21, 319 | "isActive": true, 320 | "resource": 49167 321 | }, 322 | { 323 | "key": "jyzyapi", 324 | "name": "金鹰资源", 325 | "api": "https://jyzyapi.com/provide/vod/", 326 | "playUrl": "", 327 | "search": 1, 328 | "group": "切片", 329 | "status": true, 330 | "type": 1, 331 | "id": 22, 332 | "isActive": true, 333 | "resource": 48914 334 | }, 335 | { 336 | "key": "tiankongapi", 337 | "name": "天空资源", 338 | "api": "https://api.tiankongapi.com/api.php/provide/vod/", 339 | "playUrl": "", 340 | "search": 1, 341 | "group": "切片", 342 | "status": true, 343 | "type": 1, 344 | "id": 23, 345 | "isActive": true, 346 | "resource": 54970 347 | }, 348 | { 349 | "key": "feisuzy", 350 | "name": "飞速资源", 351 | "api": "https://www.feisuzy.com/api.php/provide/vod/", 352 | "playUrl": "", 353 | "search": 1, 354 | "group": "切片", 355 | "isActive": true, 356 | "status": false, 357 | "type": 1, 358 | "id": 24, 359 | "resource": 54598 360 | }, 361 | { 362 | "key": "ylzy1", 363 | "name": "鱼乐资源", 364 | "api": "https://api.ylzy1.com/api.php/provide/vod/", 365 | "playUrl": "", 366 | "search": 1, 367 | "group": "切片", 368 | "status": false, 369 | "type": 1, 370 | "id": 25 371 | }, 372 | { 373 | "key": "zzrhgg", 374 | "name": "飘花资源", 375 | "api": "http://www.zzrhgg.com/api.php/provide/vod/", 376 | "playUrl": "", 377 | "search": 1, 378 | "group": "切片", 379 | "status": false, 380 | "type": 1, 381 | "id": 26 382 | }, 383 | { 384 | "key": "hanjuzy", 385 | "name": "韩剧资源", 386 | "api": "http://www.hanjuzy.com/inc/apijson_vod.php", 387 | "playUrl": "", 388 | "search": 1, 389 | "group": "切片", 390 | "status": true, 391 | "type": 1, 392 | "id": 27 393 | }, 394 | { 395 | "key": "28393120-9d11-5110-b209-c925b2d8f87e", 396 | "name": "非凡资源", 397 | "api": "http://cj.ffzyapi.com/api.php/provide/vod/from/ffm3u8/", 398 | "playUrl": "", 399 | "search": 1, 400 | "group": "切片", 401 | "status": true, 402 | "isActive": true, 403 | "type": 1, 404 | "id": 28, 405 | "resource": 61764 406 | }, 407 | { 408 | "key": "9fbbb48c-d822-55ed-baee-40964804d8a9", 409 | "name": "Ikun资源", 410 | "api": "https://ikunzyapi.com/api.php/provide/vod", 411 | "playUrl": "", 412 | "search": 1, 413 | "group": "切片", 414 | "status": true, 415 | "type": 1, 416 | "id": 29, 417 | "isActive": true, 418 | "resource": 47725 419 | }, 420 | { 421 | "key": "apiyhzy", 422 | "name": "樱花动漫", 423 | "api": "https://m3u8.apiyhzy.com/api.php/provide/vod/", 424 | "playUrl": "", 425 | "search": 1, 426 | "group": "切片", 427 | "status": false, 428 | "type": 1, 429 | "id": 30, 430 | "isActive": true, 431 | "resource": 96615 432 | }, 433 | { 434 | "key": "rrvipw", 435 | "name": "rrvipw", 436 | "api": "https://www.rrvipw.com/api.php/provide/vod/", 437 | "playUrl": "", 438 | "search": 1, 439 | "group": "切片", 440 | "status": false, 441 | "type": 1, 442 | "id": 31 443 | }, 444 | { 445 | "key": "1080zyku", 446 | "name": "1080zyku", 447 | "api": "http://api.1080zyku.com/inc/api_mac10.php", 448 | "playUrl": "", 449 | "search": 1, 450 | "group": "切片", 451 | "status": false, 452 | "type": 1, 453 | "id": 32, 454 | "isActive": true, 455 | "resource": 48916 456 | }, 457 | { 458 | "key": "ukuapi", 459 | "name": "U酷资源", 460 | "api": "https://api.ukuapi.com/api.php/provide/vod/", 461 | "playUrl": "", 462 | "search": 1, 463 | "group": "切片", 464 | "status": true, 465 | "type": 1, 466 | "id": 33, 467 | "isActive": true, 468 | "resource": 34834 469 | }, 470 | { 471 | "key": "vodimg", 472 | "name": "影图资源", 473 | "api": "https://cj.vodimg.top/api.php/provide/vod/", 474 | "playUrl": "", 475 | "search": 1, 476 | "group": "切片", 477 | "status": true, 478 | "type": 1, 479 | "id": 34 480 | }, 481 | { 482 | "key": "无尽资源", 483 | "name": "无尽资源", 484 | "api": "https://api.wujinapi.me/api.php/provide/vod/", 485 | "playUrl": "", 486 | "search": 1, 487 | "group": "切片", 488 | "status": true, 489 | "isActive": true, 490 | "type": 1, 491 | "id": 35, 492 | "resource": 56329 493 | }, 494 | { 495 | "key": "南国资源", 496 | "name": "南国资源", 497 | "api": "http://api.nguonphim.tv/api.php/provide/vod/", 498 | "playUrl": "", 499 | "search": 1, 500 | "group": "切片", 501 | "status": false, 502 | "type": 1, 503 | "id": 36 504 | }, 505 | { 506 | "key": "xiaomaomi", 507 | "name": "小猫咪", 508 | "api": "http://zy.xiaomaomi.cc/api.php/provide/vod/", 509 | "playUrl": "http://106.225.218.183:10209/home/api?type=ys&uid=2742611&key=efmqzACFGKORTY3479&url=", 510 | "search": 1, 511 | "group": "官采", 512 | "status": true, 513 | "type": 1, 514 | "id": 37 515 | }, 516 | { 517 | "key": "映迷影院", 518 | "name": "映迷影院", 519 | "api": "https://www.inmi.app/api.php/provide/vod/", 520 | "playUrl": "", 521 | "search": 1, 522 | "group": "切片", 523 | "status": true, 524 | "type": 1, 525 | "id": 38, 526 | "isActive": true, 527 | "resource": 70585 528 | }, 529 | { 530 | "key": "1080资源", 531 | "name": "1080资源", 532 | "api": "https://1080p.tv/api.php/provide/vod", 533 | "playUrl": "", 534 | "search": 1, 535 | "group": "切片", 536 | "status": false, 537 | "type": 1, 538 | "id": 39 539 | }, 540 | { 541 | "key": "易看资源", 542 | "name": "易看资源", 543 | "api": "https://api.yikanapi.com/api.php/provide/vod/", 544 | "playUrl": "", 545 | "search": 1, 546 | "group": "切片", 547 | "status": true, 548 | "type": 1, 549 | "id": 40 550 | }, 551 | { 552 | "key": "忆梦资源", 553 | "name": "忆梦资源", 554 | "api": "http://anltv.cn/api.php/provide/vod/", 555 | "playUrl": "", 556 | "search": 1, 557 | "group": "切片", 558 | "status": true, 559 | "type": 1, 560 | "id": 41, 561 | "isActive": true, 562 | "resource": 25265 563 | }, 564 | { 565 | "key": "TOM资源", 566 | "name": "TOM资源", 567 | "api": "https://api.tomcaiji.com/api.php/provide/vod/", 568 | "playUrl": "", 569 | "search": 1, 570 | "group": "切片", 571 | "status": false, 572 | "type": 1, 573 | "id": 42 574 | }, 575 | { 576 | "key": "红牛资源", 577 | "name": "红牛资源", 578 | "api": "https://www.hongniuzy2.com/api.php/provide/vod/", 579 | "playUrl": "", 580 | "search": 1, 581 | "group": "切片", 582 | "status": true, 583 | "type": 1, 584 | "id": 43, 585 | "isActive": true, 586 | "resource": 48723 587 | }, 588 | { 589 | "key": "77韩剧", 590 | "name": "77韩剧", 591 | "api": "https://www.77hanju.com/api.php/provide/vod/", 592 | "playUrl": "", 593 | "search": 1, 594 | "group": "切片", 595 | "status": true, 596 | "type": 1, 597 | "id": 44 598 | }, 599 | { 600 | "key": "wandouzy", 601 | "name": "豌豆影院", 602 | "api": "https://ks.wandouzy.cc/api.php/provide/vod/", 603 | "playUrl": "", 604 | "search": 1, 605 | "group": "综合", 606 | "status": false, 607 | "type": 1, 608 | "id": 45 609 | }, 610 | { 611 | "key": "ganfan", 612 | "name": "干饭", 613 | "api": "http://124.220.183.81:83/api.php/provide/vod/", 614 | "playUrl": "http://106.225.218.183:10209/home/api?type=ys&uid=2742611&key=efmqzACFGKORTY3479&url=", 615 | "search": 1, 616 | "group": "官采", 617 | "status": true, 618 | "type": 1, 619 | "id": 46 620 | }, 621 | { 622 | "key": "feimao", 623 | "name": "肥猫", 624 | "api": "http://i.xn--z7x900a.love:63/api.php/provide/vod/", 625 | "playUrl": "https://api.tyun77.cn/api.php/provide/parseDicturl?url=", 626 | "search": 1, 627 | "group": "官采", 628 | "status": true, 629 | "type": 1, 630 | "id": 47 631 | }, 632 | { 633 | "key": "buleitv", 634 | "name": "布蕾", 635 | "api": "http://117.175.212.198:8088/api.php/app/", 636 | "playUrl": "", 637 | "search": 1, 638 | "group": "app", 639 | "status": true, 640 | "type": 3, 641 | "id": 48 642 | }, 643 | { 644 | "key": "adys", 645 | "name": "小龟", 646 | "api": "https://api123.adys.app/xgapp.php/v3/", 647 | "playUrl": "", 648 | "search": 1, 649 | "group": "app", 650 | "status": false, 651 | "type": 3, 652 | "id": 49 653 | }, 654 | { 655 | "key": "realdou", 656 | "name": "真逗", 657 | "api": "http://ys.realdou.cn/api.php/app/", 658 | "playUrl": "", 659 | "search": 1, 660 | "group": "app", 661 | "status": true, 662 | "type": 3, 663 | "id": 50 664 | }, 665 | { 666 | "key": "gvideo", 667 | "name": "苹果云视听", 668 | "api": "https://www.gvideo.me/api.php/app/", 669 | "playUrl": "", 670 | "search": 1, 671 | "group": "app", 672 | "status": true, 673 | "type": 3, 674 | "id": 51 675 | }, 676 | { 677 | "key": "iptv8848", 678 | "name": "8848", 679 | "api": "http://bn.iptv8848.site/api.php/app/", 680 | "playUrl": "", 681 | "search": 1, 682 | "group": "app", 683 | "status": true, 684 | "isActive": true, 685 | "type": 3, 686 | "id": 52, 687 | "resource": 9999 688 | }, 689 | { 690 | "key": "jlys6", 691 | "name": "家里有事", 692 | "api": "http://jlys6.top/mogai_api.php/v1.vod", 693 | "playUrl": "", 694 | "search": 1, 695 | "group": "app", 696 | "status": true, 697 | "type": 4, 698 | "id": 53 699 | }, 700 | { 701 | "key": "sc1080", 702 | "name": "上次", 703 | "api": "https://sc1080.top/api.php/v1.vod", 704 | "playUrl": "", 705 | "search": 1, 706 | "group": "app", 707 | "status": true, 708 | "type": 4, 709 | "id": 54 710 | }, 711 | { 712 | "key": "juquanweb", 713 | "name": "具全", 714 | "api": "http://xinxing.juquanweb.top/icciu_api.php/v1.vod", 715 | "playUrl": "", 716 | "search": 1, 717 | "group": "app", 718 | "status": true, 719 | "type": 4, 720 | "id": 55, 721 | "isActive": true, 722 | "resource": 131944 723 | }, 724 | { 725 | "key": "chiguafilm", 726 | "name": "吃瓜", 727 | "api": "https://www.chiguafilm.com/api.php/v1.vod", 728 | "playUrl": "", 729 | "search": 0, 730 | "group": "app", 731 | "status": true, 732 | "type": 4, 733 | "id": 56 734 | }, 735 | { 736 | "key": "laimi", 737 | "name": "徕米", 738 | "api": "https://www.laimi.me/api.php/v1.vod?limit=12&page=1", 739 | "playUrl": "", 740 | "search": 1, 741 | "group": "app", 742 | "status": true, 743 | "type": 4, 744 | "id": 57, 745 | "isActive": true, 746 | "resource": 10321 747 | }, 748 | { 749 | "key": "ishen520", 750 | "name": "i神520", 751 | "api": "http://app.ishen520.com/api.php/v1.vod", 752 | "playUrl": "", 753 | "search": 1, 754 | "group": "app", 755 | "status": true, 756 | "type": 4, 757 | "id": 58 758 | }, 759 | { 760 | "key": "非凡资源", 761 | "name": "非凡资源", 762 | "api": "http://www.ffzy.tv/api.php/provide/vod/", 763 | "group": "默认", 764 | "status": true, 765 | "isActive": true, 766 | "type": 1, 767 | "resource": 61765, 768 | "id": 59, 769 | "search": 1, 770 | "playUrl": "" 771 | }, 772 | { 773 | "key": "飞速资源", 774 | "name": "飞速资源", 775 | "api": "https://www.feisuzyapi.com/api.php/provide/vod/", 776 | "group": "默认", 777 | "status": true, 778 | "type": 1, 779 | "id": 60, 780 | "search": 1, 781 | "playUrl": "", 782 | "isActive": true, 783 | "resource": 54753 784 | }, 785 | { 786 | "key": "速播", 787 | "name": "速播", 788 | "api": "https://subocaiji.com/api.php/provide/vod/", 789 | "group": "默认", 790 | "status": true, 791 | "type": 1, 792 | "search": 1, 793 | "id": 61, 794 | "playUrl": "", 795 | "isActive": true, 796 | "resource": 47689 797 | }, 798 | { 799 | "key": "葡萄资源", 800 | "name": "葡萄资源", 801 | "api": "https://caiji.putaozy.net/inc/api.php", 802 | "group": "18+", 803 | "status": false, 804 | "search": 2, 805 | "type": 0, 806 | "id": 62, 807 | "playUrl": "" 808 | }, 809 | { 810 | "key": "探探资源", 811 | "name": "探探资源", 812 | "api": "https://apittzy.com/api.php/provide/vod/at/xml", 813 | "group": "18+", 814 | "status": true, 815 | "search": 2, 816 | "type": 0, 817 | "id": 63, 818 | "playUrl": "" 819 | }, 820 | { 821 | "key": "KK资源网", 822 | "name": "KK资源网", 823 | "api": "https://kkzy.me/api.php/provide/vod/at/xmlsea", 824 | "group": "18+", 825 | "status": true, 826 | "search": 2, 827 | "type": 0, 828 | "id": 64, 829 | "playUrl": "" 830 | }, 831 | { 832 | "key": "色猫资源", 833 | "name": "色猫资源", 834 | "api": "https://api.maozyapi.com/inc/api.php", 835 | "group": "18+", 836 | "status": true, 837 | "search": 2, 838 | "type": 0, 839 | "id": 65, 840 | "playUrl": "" 841 | }, 842 | { 843 | "key": "乐播", 844 | "name": "乐播", 845 | "api": "https://lbapi9.com/api.php/provide/vod/at/xml", 846 | "group": "18+", 847 | "status": true, 848 | "search": 2, 849 | "type": 0, 850 | "id": 66, 851 | "playUrl": "", 852 | "isActive": true, 853 | "resource": 150067 854 | }, 855 | { 856 | "key": "哥哥妹妹", 857 | "name": "哥哥妹妹", 858 | "type": 0, 859 | "api": "http://www.ggmmzy.com:9999/inc/xml", 860 | "group": "18+", 861 | "status": true, 862 | "search": 2, 863 | "id": 67, 864 | "playUrl": "", 865 | "isActive": true, 866 | "resource": 21335 867 | }, 868 | { 869 | "key": "shayu", 870 | "name": "shayu", 871 | "api": "https://shayuapi.com/api.php/Seacms/vod/", 872 | "playUrl": "", 873 | "group": "18+", 874 | "search": 2, 875 | "status": true, 876 | "type": 0, 877 | "id": 68 878 | }, 879 | { 880 | "key": "色屌丝", 881 | "name": "色屌丝", 882 | "api": "http://sdszyapi.com/home/cjapi/asbb/mc10/vod/xml", 883 | "playUrl": "", 884 | "group": "18+", 885 | "search": 2, 886 | "status": true, 887 | "type": 0, 888 | "id": 69 889 | }, 890 | { 891 | "key": "番号资源", 892 | "name": "番号资源 ", 893 | "api": "http://fhapi9.com/api.php/provide/vod/at/xml", 894 | "group": "18+", 895 | "status": true, 896 | "type": 0, 897 | "search": 2, 898 | "id": 70, 899 | "playUrl": "" 900 | }, 901 | { 902 | "key": "点点娱乐", 903 | "name": "点点娱乐 ", 904 | "api": "https://xx55zyapi.com/home/cjapi/ascf/mc10/vod/xml", 905 | "group": "18+", 906 | "status": true, 907 | "type": 0, 908 | "search": 2, 909 | "id": 71, 910 | "playUrl": "" 911 | }, 912 | { 913 | "key": "52AVAV", 914 | "name": "52AVAV ", 915 | "api": "https://52zyapi.com/home/cjapi/asda/mc10/vod/xml", 916 | "group": "18+", 917 | "status": true, 918 | "type": 0, 919 | "search": 2, 920 | "id": 72, 921 | "playUrl": "" 922 | }, 923 | { 924 | "key": "小姐姐资源", 925 | "name": "小姐姐资源 ", 926 | "api": "https://xjjzyapi.com/home/cjapi/askl/mc10/vod/xml", 927 | "group": "18+", 928 | "status": true, 929 | "type": 0, 930 | "search": 2, 931 | "id": 73, 932 | "playUrl": "" 933 | }, 934 | { 935 | "key": "色窝资源", 936 | "name": "色窝资源 ", 937 | "api": "https://sewozyapi.com/api.php/provide/vod/at/xml", 938 | "group": "18+", 939 | "status": true, 940 | "search": 2, 941 | "type": 0, 942 | "id": 74, 943 | "playUrl": "" 944 | }, 945 | { 946 | "key": "大地", 947 | "name": "大地", 948 | "api": "https://dadiapi.com/api.php", 949 | "group": "18+", 950 | "status": true, 951 | "type": 0, 952 | "search": 2, 953 | "id": 75, 954 | "playUrl": "" 955 | }, 956 | { 957 | "key": "老鸭", 958 | "name": "老鸭", 959 | "api": "https://api.apilyzy.com/api.php/provide/vod/at/xml", 960 | "group": "18+", 961 | "status": true, 962 | "search": 2, 963 | "type": 0, 964 | "id": 76, 965 | "playUrl": "", 966 | "isActive": true, 967 | "resource": 149569 968 | }, 969 | { 970 | "key": "花魁", 971 | "name": "花魁", 972 | "api": "https://caiji.huakuiapi.com/inc/apijson_vod.php", 973 | "group": "18+", 974 | "status": true, 975 | "search": 2, 976 | "type": 1, 977 | "id": 77, 978 | "playUrl": "" 979 | }, 980 | { 981 | "key": "大MM资源", 982 | "name": "大MM资源 ", 983 | "api": "https://www.dmmapi.com/home/cjapi/asd2c7/mc10/vod/xml", 984 | "group": "18+", 985 | "status": true, 986 | "type": 0, 987 | "search": 2, 988 | "id": 78, 989 | "playUrl": "" 990 | }, 991 | { 992 | "key": "精工厂资源", 993 | "name": "精工厂资源 ", 994 | "api": "https://jgczyapi.com/home/cjapi/kld2/mc10/vod/xml", 995 | "group": "18+", 996 | "status": true, 997 | "type": 0, 998 | "search": 2, 999 | "id": 79, 1000 | "playUrl": "" 1001 | }, 1002 | { 1003 | "key": "最大资源", 1004 | "name": "最大资源", 1005 | "api": "http://zuidazy.me/api.php/provide/vod/at/xml", 1006 | "group": "默认", 1007 | "status": true, 1008 | "type": 0, 1009 | "search": 1, 1010 | "id": 80, 1011 | "playUrl": "" 1012 | }, 1013 | { 1014 | "key": "656b916e-94fe-5b57-b300-80ccc1be1cea", 1015 | "name": "辣椒", 1016 | "api": "https://apilj.com/api.php/provide/vod/at/json/", 1017 | "playUrl": "", 1018 | "group": "18+", 1019 | "search": 2, 1020 | "status": false, 1021 | "type": 1, 1022 | "id": 81 1023 | }, 1024 | { 1025 | "key": "cee0fca9-1808-5017-9a69-0d9013f95b47", 1026 | "name": "芒果", 1027 | "api": "https://mgzyz1.com/api.php/provide/vod/?ac=list", 1028 | "playUrl": "https://mgm3u8-player.com/player/DPm3u8.php?url=", 1029 | "group": "18+", 1030 | "search": 2, 1031 | "status": false, 1032 | "type": 1, 1033 | "id": 82 1034 | }, 1035 | { 1036 | "key": "b0684274-ce9e-5d4f-bf54-f61afbdaf49d", 1037 | "name": "玉兔", 1038 | "api": "https://apiyutu.com/api.php/provide/vod/?ac=list", 1039 | "playUrl": "https://yutujx.com/?url=", 1040 | "group": "18+", 1041 | "search": 2, 1042 | "status": true, 1043 | "type": 1, 1044 | "id": 83 1045 | }, 1046 | { 1047 | "key": "70f4c18c-3276-50f1-adaa-85614f5441eb", 1048 | "name": "森林", 1049 | "api": "https://slapibf.com/api.php/provide/vod/?ac=list", 1050 | "playUrl": "https://sljxsl.com/?url=", 1051 | "group": "18+", 1052 | "search": 2, 1053 | "status": true, 1054 | "type": 1, 1055 | "id": 84 1056 | }, 1057 | { 1058 | "key": "9d8974ba-ddfc-5e53-b008-29f37e5fc88b", 1059 | "name": "155", 1060 | "api": "https://155api.com/api.php/provide/vod/?ac=list", 1061 | "playUrl": "https://www.155jx.com/?url=", 1062 | "group": "18+", 1063 | "search": 2, 1064 | "status": true, 1065 | "type": 1, 1066 | "id": 85, 1067 | "isActive": true, 1068 | "resource": 52882 1069 | }, 1070 | { 1071 | "key": "a93050f8-e282-521d-9c92-cdbbf5add205", 1072 | "name": "色猫", 1073 | "api": "https://caiji.semaozy.net/inc/apijson_vod.php", 1074 | "playUrl": "https://jiexi.99mao.xyz/m3u8/?url=", 1075 | "group": "18+", 1076 | "search": 2, 1077 | "status": true, 1078 | "type": 1, 1079 | "id": 86 1080 | }, 1081 | { 1082 | "key": "447fa6df-7552-5830-ab64-d45afbf39b42", 1083 | "name": "草榴", 1084 | "api": "https://www.caoliuzy.com/api.php/provide/vod/at/json/", 1085 | "playUrl": "https://jx.caoliuzycdn.com/m3u8.php?url=", 1086 | "group": "18+", 1087 | "search": 2, 1088 | "status": false, 1089 | "type": 1, 1090 | "id": 87 1091 | }, 1092 | { 1093 | "key": "8a885bf6-666b-5bbf-8669-4c7f1ffb7a71", 1094 | "name": "开云", 1095 | "api": "https://kaiyunzy5.com/inc/apijson_vod.php", 1096 | "playUrl": "https://jiexi.kaiyunzy.vip/m3u8/?url=", 1097 | "group": "18+", 1098 | "search": 2, 1099 | "status": true, 1100 | "type": 1, 1101 | "id": 88 1102 | }, 1103 | { 1104 | "key": "5ad3edc1-8e52-5bf6-90f1-2f785465ec2a", 1105 | "name": "奇虎", 1106 | "api": "https://caiji.qhzyapi.com/api.php/provide/vod/?ac=list", 1107 | "playUrl": "奇虎", 1108 | "group": "影视", 1109 | "search": 1, 1110 | "status": true, 1111 | "type": 1, 1112 | "id": 89, 1113 | "isActive": true, 1114 | "resource": 18543 1115 | }, 1116 | { 1117 | "key": "a5a4498a-04ae-5267-b11c-a68eb32ff1e8", 1118 | "name": "极速", 1119 | "api": "https://jszyapi.com/api.php/provide/vod/at/json", 1120 | "playUrl": "https://jsjiexi.com/play/?url=", 1121 | "group": "影视", 1122 | "search": 1, 1123 | "status": true, 1124 | "type": 1, 1125 | "id": 90, 1126 | "isActive": true, 1127 | "resource": 47097 1128 | }, 1129 | { 1130 | "key": "a4d8e39c-5981-5c07-84f8-19ab9839e160", 1131 | "name": "黄瓜", 1132 | "api": "https://www.avre00.com/api.php/Prodao/vod/?ac=list", 1133 | "playUrl": "https://player.avre20.com:5418/player/?url=", 1134 | "group": "18+", 1135 | "search": 2, 1136 | "status": true, 1137 | "type": 1, 1138 | "id": 91 1139 | }, 1140 | { 1141 | "key": "dbf45aab-a93b-5952-97e5-6e1a2c130e4d", 1142 | "name": "大漠", 1143 | "api": "https://damozy.com/api.php/provide/vod/?ac=list", 1144 | "playUrl": "https://www.damojx.com/dm/dm.html?url=", 1145 | "group": "影视", 1146 | "search": 1, 1147 | "status": true, 1148 | "type": 1, 1149 | "id": 92, 1150 | "isActive": true, 1151 | "resource": 21129 1152 | }, 1153 | { 1154 | "key": "ffc08730-71ad-56b8-a153-e2e563e6d64c", 1155 | "name": "奶香", 1156 | "api": "https://Naixxzy.com/api.php/provide/vod/?ac=list", 1157 | "playUrl": "https://nxxzynxp.com/?url=", 1158 | "group": "18+", 1159 | "search": 2, 1160 | "status": true, 1161 | "type": 1, 1162 | "id": 93, 1163 | "isActive": true, 1164 | "resource": 44553 1165 | }, 1166 | { 1167 | "key": "b4c96d80-854d-527e-b6d8-cc9e21960eeb", 1168 | "name": "68", 1169 | "api": "https://caiji.68zyapi.com/api.php/provide/vod/?ac=list ", 1170 | "playUrl": "https://jiexi.68zy.vip/m3u8/?url= ", 1171 | "group": "影视", 1172 | "search": 1, 1173 | "status": false, 1174 | "type": 1, 1175 | "id": 94 1176 | }, 1177 | { 1178 | "key": "f81ab05d-3269-5fb9-97bb-1597b00e0e02", 1179 | "name": "伊人", 1180 | "api": "https://api.yrzyapi.com/api.php/provide/vod/?ac=list", 1181 | "playUrl": "https://player.yrplay1.com/m3u8/?url=", 1182 | "group": "18+", 1183 | "search": 2, 1184 | "status": true, 1185 | "type": 1, 1186 | "id": 95, 1187 | "isActive": true, 1188 | "resource": 62345 1189 | }, 1190 | { 1191 | "key": "f4d594ec-8a57-5e48-8ab6-d5ba4a64615c", 1192 | "name": "江南", 1193 | "api": "https://api.yjiexi.com/provide/xml.html", 1194 | "playUrl": "https://player.yjiexi.com/player?url= ", 1195 | "group": "影视", 1196 | "search": 1, 1197 | "status": false, 1198 | "type": 0, 1199 | "id": 96 1200 | }, 1201 | { 1202 | "key": "a00bc761-7b9f-5804-9bfd-7a07322159b5", 1203 | "name": "海外", 1204 | "api": "http://api.haiwaikan.com/v1/vod?ac=list", 1205 | "playUrl": "http://api.haiwaikan.com/v1/vod?ac=list", 1206 | "group": "影视", 1207 | "search": 1, 1208 | "status": false, 1209 | "type": 1, 1210 | "id": 97 1211 | }, 1212 | { 1213 | "key": "b8b48f6e-9e96-5619-96ba-d884ef9cb442", 1214 | "name": "奥斯卡", 1215 | "api": "https://aosikazy.com/api.php/provide/vod/?ac=list", 1216 | "playUrl": "https://aosikazy11.com/?url=", 1217 | "group": "18+", 1218 | "search": 2, 1219 | "status": false, 1220 | "type": 1, 1221 | "id": 98, 1222 | "isActive": true, 1223 | "resource": 86306 1224 | }, 1225 | { 1226 | "key": "f951be46-17fa-5f4f-9f41-ff25d21e8d74", 1227 | "name": "美少女", 1228 | "api": "https://www.msnii.com/api/xml.php", 1229 | "playUrl": "", 1230 | "group": "18+", 1231 | "search": 2, 1232 | "status": true, 1233 | "type": 0, 1234 | "id": 99, 1235 | "isActive": true, 1236 | "resource": 17664 1237 | }, 1238 | { 1239 | "key": "54658e47-58bb-5221-bec2-82b8a3be2ec4", 1240 | "name": "淫水机", 1241 | "api": "https://www.xrbsp.com/api/xml.php", 1242 | "playUrl": "", 1243 | "group": "18+", 1244 | "search": 2, 1245 | "status": true, 1246 | "type": 0, 1247 | "id": 100, 1248 | "isActive": true, 1249 | "resource": 16428 1250 | }, 1251 | { 1252 | "key": "f951be46-17fa-5f4f-9f41-ff25d21e8d74", 1253 | "name": "花椒", 1254 | "api": "https://apihjzy.com/api.php/provide/vod/at/xml/", 1255 | "playUrl": "", 1256 | "group": "18+", 1257 | "search": 2, 1258 | "status": true, 1259 | "type": 0, 1260 | "id": 101, 1261 | "isActive": true, 1262 | "resource": 17664 1263 | }, 1264 | { 1265 | "key": "cfa8e308-0120-5e43-a937-eebb76f99626", 1266 | "name": "丝袜", 1267 | "api": "https://www.siwazyw.cc/api.php/provide/vod/at/xml/", 1268 | "playUrl": "https://help.siwazywcdn2.com:5278/m3u8.php?url=", 1269 | "group": "18+", 1270 | "search": 2, 1271 | "status": false, 1272 | "type": 0, 1273 | "id": 102 1274 | }, 1275 | { 1276 | "key": "34cd623c-0b62-5426-a653-9c1db4a850e8", 1277 | "name": "黄AV", 1278 | "api": "https://www.pgxdy.com/api/xml.php", 1279 | "playUrl": "", 1280 | "group": "18+", 1281 | "search": 2, 1282 | "status": false, 1283 | "type": 0, 1284 | "id": 103, 1285 | "isActive": true, 1286 | "resource": 16643 1287 | }, 1288 | { 1289 | "key": "bajiecaiji", 1290 | "name": "八戒采集", 1291 | "api": "https://cj.bajiecaiji.com/inc/apijson.php", 1292 | "group": "影视", 1293 | "status": true, 1294 | "type": 1, 1295 | "search": 1, 1296 | "id": 104, 1297 | "playUrl": "", 1298 | "isActive": true, 1299 | "resource": 1011 1300 | }, 1301 | { 1302 | "key": "Osu3dV", 1303 | "name": "香奶儿", 1304 | "api": "https://www.gdlsp.com/api/xml.php", 1305 | "group": "18+", 1306 | "status": true, 1307 | "type": 0, 1308 | "search": 2, 1309 | "id": 105, 1310 | "playUrl": "" 1311 | }, 1312 | { 1313 | "name": "91麻豆", 1314 | "api": "https://91md.me/api.php/provide/vod/at/xml/", 1315 | "group": "18+", 1316 | "status": true, 1317 | "type": 0, 1318 | "search": 2, 1319 | "key": "07b96ce7-0791-5f19-9321-ba6085145eef", 1320 | "id": 106, 1321 | "playUrl": "" 1322 | }, 1323 | { 1324 | "name": "白嫖", 1325 | "api": "https://www.kxgav.com/api/xml.php", 1326 | "group": "18+", 1327 | "status": true, 1328 | "type": 0, 1329 | "search": 2, 1330 | "key": "4eef8bc4-71f8-54fa-bffd-d1d3d9e77dce", 1331 | "id": 107, 1332 | "playUrl": "", 1333 | "isActive": true, 1334 | "resource": 16460 1335 | }, 1336 | { 1337 | "name": "爱播", 1338 | "api": "https://cj.apiabzy.com/api.php/provide/vod/at/xml/", 1339 | "group": "18+", 1340 | "status": false, 1341 | "type": 0, 1342 | "search": 2, 1343 | "key": "f881d19e-9433-56d4-9c06-4a842b280877", 1344 | "id": 108, 1345 | "playUrl": "" 1346 | }, 1347 | { 1348 | "name": "草莓", 1349 | "api": "https://caiji.caomeiapi.com/inc/api.php", 1350 | "group": "18+", 1351 | "status": true, 1352 | "type": 0, 1353 | "search": 2, 1354 | "key": "54658e47-58bb-5221-bec2-82b8a3be2ec4", 1355 | "id": 109, 1356 | "playUrl": "", 1357 | "isActive": true, 1358 | "resource": 16428 1359 | }, 1360 | { 1361 | "name": "小湿妹", 1362 | "api": "https://www.afasu.com/api/xml.php", 1363 | "group": "18+", 1364 | "status": false, 1365 | "type": 0, 1366 | "search": 2, 1367 | "key": "b6b384a4-43d1-5937-babe-c7af2ea5e21b", 1368 | "id": 110, 1369 | "playUrl": "" 1370 | }, 1371 | { 1372 | "name": "久久", 1373 | "api": "http://99zy.pw/api.php/provide/vod/at/xml/", 1374 | "group": "18+", 1375 | "status": false, 1376 | "type": 0, 1377 | "search": 2, 1378 | "key": "20a58291-0246-5461-97b6-b080245200dd", 1379 | "id": 111, 1380 | "playUrl": "" 1381 | }, 1382 | { 1383 | "name": "秀色", 1384 | "api": "https://api.xiuseapi.com/api.php/provide/vod/at/xml", 1385 | "group": "18+", 1386 | "status": false, 1387 | "type": 0, 1388 | "search": 2, 1389 | "key": "34cd623c-0b62-5426-a653-9c1db4a850e8", 1390 | "id": 112, 1391 | "playUrl": "", 1392 | "isActive": true, 1393 | "resource": 16643 1394 | }, 1395 | { 1396 | "name": "芒果", 1397 | "api": "https://www.mgav1.cc/api.php/provide/vod/at/xml/", 1398 | "group": "18+", 1399 | "status": false, 1400 | "type": 0, 1401 | "search": 2, 1402 | "key": "cee0fca9-1808-5017-9a69-0d9013f95b47", 1403 | "id": 113, 1404 | "playUrl": "" 1405 | }, 1406 | { 1407 | "name": "花椒", 1408 | "api": "https://cj.apihjzy.com/inc/api.php", 1409 | "group": "18+", 1410 | "status": true, 1411 | "type": 0, 1412 | "search": 2, 1413 | "key": "f951be46-17fa-5f4f-9f41-ff25d21e8d74", 1414 | "id": 114, 1415 | "playUrl": "", 1416 | "isActive": true, 1417 | "resource": 17664 1418 | }, 1419 | { 1420 | "name": "辣椒2", 1421 | "api": "http://api.11bat.com/api.php/provide/vod/at/xml/", 1422 | "group": "18+", 1423 | "status": true, 1424 | "type": 0, 1425 | "search": 2, 1426 | "key": "2286c2fd-8e65-52d2-9a7a-f21ec0cae006", 1427 | "id": 115, 1428 | "playUrl": "" 1429 | }, 1430 | { 1431 | "key": "ruifenglb", 1432 | "name": "瑞丰", 1433 | "api": "http://81.69.23.108:5566/ruifenglb_api.php/v1.vod", 1434 | "playUrl": "", 1435 | "search": 1, 1436 | "group": "app", 1437 | "status": true, 1438 | "type": 4, 1439 | "id": 116 1440 | }, 1441 | { 1442 | "name": "天堂", 1443 | "api": "http://bttcj.com/inc/sapi.php", 1444 | "group": "18+", 1445 | "status": false, 1446 | "type": 0, 1447 | "search": 2, 1448 | "key": "b0619031-953f-5e05-9d68-a621e8bc6514", 1449 | "id": 117, 1450 | "playUrl": "" 1451 | } 1452 | 1453 | ], 1454 | 1455 | "setting": [ 1456 | { 1457 | "id": 0, 1458 | "theme": "auto", 1459 | "externalPlayer": "", 1460 | "defaultHot": "kylive", 1461 | "defaultSearchRecommend": "douban", 1462 | "defaultSearchType": "group", 1463 | "defaultCheckModel": true, 1464 | "defaultChangeModel": false, 1465 | "defaultIptvEpg": "https://epg.112114.eu.org/", 1466 | "iptvSkipIpv6": true, 1467 | "iptvThumbnail": false, 1468 | "restoreWindowPositionAndSize": false, 1469 | "pauseWhenMinimize": true, 1470 | "defaultSite": 3, 1471 | "defaultIptv": 17, 1472 | "defaultAnalyze": 3, 1473 | "analyzeFlag": [ 1474 | "youku", 1475 | "qq", 1476 | "iqiyi", 1477 | "qiyi", 1478 | "letv", 1479 | "sohu", 1480 | "tudou", 1481 | "pptv", 1482 | "mgtv" 1483 | ], 1484 | "analyzeQuickSearchType": "platform", 1485 | "analyzeSupport": true, 1486 | "broadcasterType": "xgplayer", 1487 | "softSolution": false, 1488 | "skipStartEnd": true, 1489 | "agreementMask": true, 1490 | "recordShortcut": "Shift+Command+Z", 1491 | "selfBoot": false, 1492 | "hardwareAcceleration": true, 1493 | "doh": "", 1494 | "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36", 1495 | "communitySubscribe": "", 1496 | "iptvStatus": true, 1497 | "dns": "https://sm2.doh.pub/dns-query", 1498 | "webdevUrl": "https://dav.jianguoyun.com/dav/", 1499 | "webdevUsername": "wy-hai@qq.com", 1500 | "webdevPassword": "ai4ymsm38zc4y7c7", 1501 | "snifferType": "pie", 1502 | "defaultDrive": 33 1503 | } 1504 | ], 1505 | "analyzeHistory": [ 1506 | { 1507 | "date": "2023-09-03", 1508 | "analyzeId": 2, 1509 | "videoUrl": "https://v.qq.com/x/cover/mzc00200v6zk1xm.html", 1510 | "videoName": "前夜", 1511 | "id": 1 1512 | } 1513 | ], 1514 | "history": [], 1515 | "searchHistory": [ 1516 | { 1517 | "title": "父辈的荣耀", 1518 | "type": "film", 1519 | "id": 1 1520 | } 1521 | ], 1522 | "star": [] 1523 | } 1524 | -------------------------------------------------------------------------------- /lib/drpy2.min.js: -------------------------------------------------------------------------------- 1 | import cheerio from "assets://js/lib/cheerio.min.js"; import "assets://js/lib/crypto-js.js"; import "./jsencrypt.js"; import 模板 from "../js/模板.js"; import { gbkTool } from "./gbk.js"; function init_test() { console.log("init_test_start"); console.log("当前版本号:" + VERSION); console.log(RKEY); console.log(JSON.stringify(rule)); console.log("init_test_end") } function pre() { if (typeof rule.预处理 === "string" && rule.预处理 && rule.预处理.trim()) { let code = rule.预处理.trim(); console.log("执行预处理代码:" + code); if (code.startsWith("js:")) { code = code.replace("js:", "") } try { eval(code) } catch (e) { console.log("预处理执行失败:" + e.message) } } } let rule = {}; let vercode = typeof pdfl === "function" ? "drpy2.1" : "drpy2"; const VERSION = vercode + " 3.9.49beta40 202400426"; const MOBILE_UA = "Mozilla/5.0 (Linux; Android 11; M2007J3SC Build/RKQ1.200826.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/77.0.3865.120 MQQBrowser/6.2 TBS/045714 Mobile Safari/537.36"; const PC_UA = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36"; const UA = "Mozilla/5.0"; const UC_UA = "Mozilla/5.0 (Linux; U; Android 9; zh-CN; MI 9 Build/PKQ1.181121.001) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.108 UCBrowser/12.5.5.1035 Mobile Safari/537.36"; const IOS_UA = "Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1"; const RULE_CK = "cookie"; const CATE_EXCLUDE = "首页|留言|APP|下载|资讯|新闻|动态"; const TAB_EXCLUDE = "猜你|喜欢|下载|剧情|热播"; const OCR_RETRY = 3; const OCR_API = "http://drpy.nokia.press:8028/ocr/drpy/text"; if (typeof MY_URL === "undefined") { var MY_URL } var HOST; var RKEY; var fetch; var print; var log; var rule_fetch_params; var fetch_params; var oheaders; var _pdfh; var _pdfa; var _pd; const DOM_CHECK_ATTR = /(url|src|href|-original|-src|-play|-url|style)$/; const SPECIAL_URL = /^(ftp|magnet|thunder|ws):/; const NOADD_INDEX = /:eq|:lt|:gt|:first|:last|^body$|^#/; const URLJOIN_ATTR = /(url|src|href|-original|-src|-play|-url|style)$/; const SELECT_REGEX = /:eq|:lt|:gt|#/g; const SELECT_REGEX_A = /:eq|:lt|:gt/g; if (typeof Object.assign != "function") { Object.assign = function () { let target = arguments[0]; for (let i = 1; i < arguments.length; i++) { let source = arguments[i]; for (let key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key] } } } return target } } if (!String.prototype.includes) { String.prototype.includes = function (search, start) { if (typeof start !== "number") { start = 0 } if (start + search.length > this.length) { return false } else { return this.indexOf(search, start) !== -1 } } } if (!Array.prototype.includes) { Object.defineProperty(Array.prototype, "includes", { value: function (searchElement, fromIndex) { if (this == null) { throw new TypeError('"this" is null or not defined') } var o = Object(this); var len = o.length >>> 0; if (len === 0) { return false } var n = fromIndex | 0; var k = Math.max(n >= 0 ? n : len - Math.abs(n), 0); while (k < len) { if (o[k] === searchElement) { return true } k++ } return false } }) } if (typeof String.prototype.startsWith != "function") { String.prototype.startsWith = function (prefix) { return this.slice(0, prefix.length) === prefix } } if (typeof String.prototype.endsWith != "function") { String.prototype.endsWith = function (suffix) { return this.indexOf(suffix, this.length - suffix.length) !== -1 } } Object.prototype.myValues = function (obj) { if (obj == null) { throw new TypeError("Cannot convert undefined or null to object") } var res = []; for (var k in obj) { if (obj.hasOwnProperty(k)) { res.push(obj[k]) } } return res }; if (typeof Object.prototype.values != "function") { Object.prototype.values = function (obj) { if (obj == null) { throw new TypeError("Cannot convert undefined or null to object") } var res = []; for (var k in obj) { if (obj.hasOwnProperty(k)) { res.push(obj[k]) } } return res } } if (typeof Array.prototype.join != "function") { Array.prototype.join = function (emoji) { emoji = emoji || ""; let self = this; let str = ""; let i = 0; if (!Array.isArray(self)) { throw String(self) + "is not Array" } if (self.length === 0) { return "" } if (self.length === 1) { return String(self[0]) } i = 1; str = this[0]; for (; i < self.length; i++) { str += String(emoji) + String(self[i]) } return str } } if (typeof Array.prototype.toReversed != "function") { Array.prototype.toReversed = function () { const clonedList = this.slice(); const reversedList = clonedList.reverse(); return reversedList } } String.prototype.rstrip = function (chars) { let regex = new RegExp(chars + "$"); return this.replace(regex, "") }; Array.prototype.append = Array.prototype.push; String.prototype.strip = String.prototype.trim; function 是否正版(vipUrl) { let flag = new RegExp("qq.com|iqiyi.com|youku.com|mgtv.com|bilibili.com|sohu.com|ixigua.com|pptv.com|miguvideo.com|le.com|1905.com|fun.tv"); return flag.test(vipUrl) } function urlDeal(vipUrl) { if (!vipUrl) { return "" } if (!是否正版(vipUrl)) { return vipUrl } if (!/miguvideo/.test(vipUrl)) { vipUrl = vipUrl.split("#")[0].split("?")[0] } return vipUrl } function setResult(d) { if (!Array.isArray(d)) { return [] } VODS = []; d.forEach(function (it) { let obj = { vod_id: it.url || "", vod_name: it.title || "", vod_remarks: it.desc || "", vod_content: it.content || "", vod_pic: it.pic_url || it.img || "" }; let keys = Object.keys(it); if (keys.includes("tname")) { obj.type_name = it.tname || "" } if (keys.includes("tid")) { obj.type_id = it.tid || "" } if (keys.includes("year")) { obj.vod_year = it.year || "" } if (keys.includes("actor")) { obj.vod_actor = it.actor || "" } if (keys.includes("director")) { obj.vod_director = it.director || "" } if (keys.includes("area")) { obj.vod_area = it.area || "" } VODS.push(obj) }); return VODS } function setResult2(res) { VODS = res.list || []; return VODS } function setHomeResult(res) { if (!res || typeof res !== "object") { return [] } return setResult(res.list) } function rc(js) { if (js === "maomi_aes.js") { var a = CryptoJS.enc.Utf8.parse("625222f9149e961d"); var t = CryptoJS.enc.Utf8.parse("5efdtf6060e2o330"); return { De: function (word) { word = CryptoJS.enc.Hex.parse(word); return CryptoJS.AES.decrypt(CryptoJS.enc.Base64.stringify(word), a, { iv: t, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 }).toString(CryptoJS.enc.Utf8) }, En: function (word) { var Encrypted = CryptoJS.AES.encrypt(word, a, { iv: t, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 }); return Encrypted.ciphertext.toString() } } } return {} } function maoss(jxurl, ref, key) { fetch_params = JSON.parse(JSON.stringify(rule_fetch_params)); eval(getCryptoJS()); try { var getVideoInfo = function (text) { return CryptoJS.AES.decrypt(text, key, { iv: iv, padding: CryptoJS.pad.Pkcs7 }).toString(CryptoJS.enc.Utf8) }; var token_key = key == undefined ? "dvyYRQlnPRCMdQSe" : key; if (ref) { var html = request(jxurl, { headers: { Referer: ref } }) } else { var html = request(jxurl) } if (html.indexOf("&btwaf=") != -1) { html = request(jxurl + "&btwaf" + html.match(/&btwaf(.*?)"/)[1], { headers: { Referer: ref } }) } var token_iv = html.split('_token = "')[1].split('"')[0]; var key = CryptoJS.enc.Utf8.parse(token_key); var iv = CryptoJS.enc.Utf8.parse(token_iv); eval(html.match(/var config = {[\s\S]*?}/)[0] + ""); if (!config.url.startsWith("http")) { config.url = CryptoJS.AES.decrypt(config.url, key, { iv: iv, padding: CryptoJS.pad.Pkcs7 }).toString(CryptoJS.enc.Utf8) } return config.url } catch (e) { return "" } } function urlencode(str) { str = (str + "").toString(); return encodeURIComponent(str).replace(/!/g, "%21").replace(/'/g, "%27").replace(/\(/g, "%28").replace(/\)/g, "%29").replace(/\*/g, "%2A").replace(/%20/g, "+") } function base64Encode(text) { return CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(text)) } function base64Decode(text) { return CryptoJS.enc.Utf8.stringify(CryptoJS.enc.Base64.parse(text)) } function md5(text) { return CryptoJS.MD5(text).toString() } function encodeStr(input, encoding) { encoding = encoding || "gbk"; if (encoding.startsWith("gb")) { const strTool = gbkTool(); input = strTool.encode(input) } return input } function decodeStr(input, encoding) { encoding = encoding || "gbk"; if (encoding.startsWith("gb")) { const strTool = gbkTool(); input = strTool.decode(input) } return input } function getCryptoJS() { return 'console.log("CryptoJS已装载");' } const RSA = { decode: function (data, key, option) { option = option || {}; if (typeof JSEncrypt === "function") { let chunkSize = option.chunkSize || 117; let privateKey = this.getPrivateKey(key); const decryptor = new JSEncrypt; decryptor.setPrivateKey(privateKey); let uncrypted = ""; uncrypted = decryptor.decryptUnicodeLong(data); return uncrypted } else { return false } }, encode: function (data, key, option) { option = option || {}; if (typeof JSEncrypt === "function") { let chunkSize = option.chunkSize || 117; let publicKey = this.getPublicKey(key); const encryptor = new JSEncrypt; encryptor.setPublicKey(publicKey); let encrypted = ""; encrypted = encryptor.encryptUnicodeLong(data); return encrypted } else { return false } }, fixKey(key, prefix, endfix) { if (!key.includes(prefix)) { key = prefix + key } if (!key.includes(endfix)) { key += endfix } return key }, getPrivateKey(key) { let prefix = "-----BEGIN RSA PRIVATE KEY-----"; let endfix = "-----END RSA PRIVATE KEY-----"; return this.fixKey(key, prefix, endfix) }, getPublicKey(key) { let prefix = "-----BEGIN PUBLIC KEY-----"; let endfix = "-----END PUBLIC KEY-----"; return this.fixKey(key, prefix, endfix) } }; function getProxyUrl() { if (typeof getProxy === "function") { return getProxy(true) } else { return "http://127.0.0.1:9978/proxy?do=js" } } function fixAdM3u8(m3u8_text, m3u8_url, ad_remove) { if (!m3u8_text && !m3u8_url || !m3u8_text && m3u8_url && !m3u8_url.startsWith("http")) { return "" } if (!m3u8_text) { log("m3u8_url:" + m3u8_url); m3u8_text = request(m3u8_url) } log("len(m3u8_text):" + m3u8_text.length); if (!ad_remove) { return m3u8_text } if (ad_remove.startsWith("reg:")) { ad_remove = ad_remove.slice(4) } else if (ad_remove.startsWith("js:")) { ad_remove = ad_remove.slice(3) } let m3u8_start = m3u8_text.slice(0, m3u8_text.indexOf("#EXTINF")).trim(); let m3u8_body = m3u8_text.slice(m3u8_text.indexOf("#EXTINF"), m3u8_text.indexOf("#EXT-X-ENDLIST")).trim(); let m3u8_end = m3u8_text.slice(m3u8_text.indexOf("#EXT-X-ENDLIST")).trim(); let murls = []; let m3_body_list = m3u8_body.split("\n"); let m3_len = m3_body_list.length; let i = 0; while (i < m3_len) { let mi = m3_body_list[i]; let mi_1 = m3_body_list[i + 1]; if (mi.startsWith("#EXTINF")) { murls.push([mi, mi_1].join("&")); i += 2 } else if (mi.startsWith("#EXT-X-DISCONTINUITY")) { let mi_2 = m3_body_list[i + 2]; murls.push([mi, mi_1, mi_2].join("&")); i += 3 } else { break } } let new_m3u8_body = []; for (let murl of murls) { if (ad_remove && new RegExp(ad_remove).test(murl)) { } else { let murl_list = murl.split("&"); if (!murl_list[murl_list.length - 1].startsWith("http") && m3u8_url.startsWith("http")) { murl_list[murl_list.length - 1] = urljoin(m3u8_url, murl_list[murl_list.length - 1]) } murl_list.forEach(it => { new_m3u8_body.push(it) }) } } new_m3u8_body = new_m3u8_body.join("\n").trim(); m3u8_text = [m3u8_start, new_m3u8_body, m3u8_end].join("\n").trim(); return m3u8_text } function fixAdM3u8Ai(m3u8_url) { let ts = (new Date).getTime(); function b(s1, s2) { let i = 0; while (i < s1.length) { if (s1[i] !== s2[i]) { break } i++ } return i } function reverseString(str) { return str.split("").reverse().join("") } let m3u8 = request(m3u8_url); m3u8 = m3u8.trim().split("\n").map(it => it.startsWith("#") ? it : urljoin(m3u8_url, it)).join("\n"); let last_url = m3u8.split("\n").slice(-1)[0]; if (last_url.includes(".m3u8") && last_url !== m3u8_url) { m3u8_url = last_url; m3u8 = request(m3u8_url) } let s = m3u8.trim().split("\n").filter(it => it.trim()).join("\n"); let ss = s.split("\n"); let firststr = ss.find(x => !x.startsWith("#")); let maxl = 0; let firststrlen = firststr.length; let ml = Math.round(ss.length / 2).toString().length; let laststr = ss.toReversed().find(x => { if (!x.startsWith("#")) { let k = b(reverseString(firststr), reverseString(x)); maxl = b(firststr, x); if (firststrlen - maxl <= ml + k) { return true } } return false }); log("最后一条切片:" + laststr); let ad_urls = []; for (let i = 0; i < ss.length; i++) { let s = ss[i]; if (!s.startsWith("#")) { if (b(firststr, s) < maxl) { ad_urls.push(s); ss.splice(i - 1, 2); i = i - 2 } else { ss[i] = urljoin(m3u8_url, s) } } else { ss[i] = s.replace(/URI=\"(.*)\"/, 'URI="' + urljoin(m3u8_url, "$1") + '"') } } log("处理的m3u8地址:" + m3u8_url); log("----广告地址----"); log(ad_urls); m3u8 = ss.join("\n"); log("处理耗时:" + ((new Date).getTime() - ts).toString()); return m3u8 } function forceOrder(lists, key, option) { let start = Math.floor(lists.length / 2); let end = Math.min(lists.length - 1, start + 1); if (start >= end) { return lists } let first = lists[start]; let second = lists[end]; if (key) { try { first = first[key]; second = second[key] } catch (e) { } } if (option && typeof option === "function") { try { first = option(first); second = option(second) } catch (e) { } } first += ""; second += ""; if (first.match(/(\d+)/) && second.match(/(\d+)/)) { let num1 = Number(first.match(/(\d+)/)[1]); let num2 = Number(second.match(/(\d+)/)[1]); if (num1 > num2) { lists.reverse() } } return lists } let VODS = []; let VOD = {}; let TABS = []; let LISTS = []; globalThis.encodeUrl = urlencode; globalThis.urlencode = urlencode; function urljoin(fromPath, nowPath) { fromPath = fromPath || ""; nowPath = nowPath || ""; return joinUrl(fromPath, nowPath) } var urljoin2 = urljoin; const defaultParser = { pdfh: pdfh, pdfa: pdfa, pd: pd }; function pdfh2(html, parse) { let html2 = html; try { if (typeof html !== "string") { html2 = html.rr(html.ele).toString() } } catch (e) { print("html对象转文本发生了错误:" + e.message) } let result = defaultParser.pdfh(html2, parse); let option = parse.includes("&&") ? parse.split("&&").slice(-1)[0] : parse.split(" ").slice(-1)[0]; if (/style/.test(option.toLowerCase()) && /url\(/.test(result)) { try { result = result.match(/url\((.*?)\)/)[1]; result = result.replace(/^['|"](.*)['|"]$/, "$1") } catch (e) { } } return result } function pdfa2(html, parse) { let html2 = html; try { if (typeof html !== "string") { html2 = html.rr(html.ele).toString() } } catch (e) { print("html对象转文本发生了错误:" + e.message) } return defaultParser.pdfa(html2, parse) } function pd2(html, parse, uri) { let ret = pdfh2(html, parse); if (typeof uri === "undefined" || !uri) { uri = "" } if (DOM_CHECK_ATTR.test(parse) && !SPECIAL_URL.test(ret)) { if (/http/.test(ret)) { ret = ret.slice(ret.indexOf("http")) } else { ret = urljoin(MY_URL, ret) } } return ret } const parseTags = { jsp: { pdfh: pdfh2, pdfa: pdfa2, pd: pd2 }, json: { pdfh(html, parse) { if (!parse || !parse.trim()) { return "" } if (typeof html === "string") { html = JSON.parse(html) } parse = parse.trim(); if (!parse.startsWith("$.")) { parse = "$." + parse } parse = parse.split("||"); for (let ps of parse) { let ret = cheerio.jp(ps, html); if (Array.isArray(ret)) { ret = ret[0] || "" } else { ret = ret || "" } if (ret && typeof ret !== "string") { ret = ret.toString() } if (ret) { return ret } } return "" }, pdfa(html, parse) { if (!parse || !parse.trim()) { return "" } if (typeof html === "string") { html = JSON.parse(html) } parse = parse.trim(); if (!parse.startsWith("$.")) { parse = "$." + parse } let ret = cheerio.jp(parse, html); if (Array.isArray(ret) && Array.isArray(ret[0]) && ret.length === 1) { return ret[0] || [] } return ret || [] }, pd(html, parse) { let ret = parseTags.json.pdfh(html, parse); if (ret) { return urljoin(MY_URL, ret) } return ret } }, jq: { pdfh(html, parse) { if (!html || !parse || !parse.trim()) { return "" } parse = parse.trim(); let result = defaultParser.pdfh(html, parse); return result }, pdfa(html, parse) { if (!html || !parse || !parse.trim()) { return [] } parse = parse.trim(); let result = defaultParser.pdfa(html, parse); print(`pdfa解析${parse}=>${result.length}`); return result }, pd(html, parse, base_url) { if (!html || !parse || !parse.trim()) { return "" } parse = parse.trim(); base_url = base_url || MY_URL; return defaultParser.pd(html, parse, base_url) } }, getParse(p0) { if (p0.startsWith("jsp:")) { return this.jsp } else if (p0.startsWith("json:")) { return this.json } else if (p0.startsWith("jq:")) { return this.jq } else { return this.jq } } }; const stringify = JSON.stringify; const jsp = parseTags.jsp; const jq = parseTags.jq; function readFile(filePath) { filePath = filePath || "./uri.min.js"; var fd = os.open(filePath); var buffer = new ArrayBuffer(1024); var len = os.read(fd, buffer, 0, 1024); console.log(len); let text = String.fromCharCode.apply(null, new Uint8Array(buffer)); console.log(text); return text } function dealJson(html) { try { html = html.trim(); if (!(html.startsWith("{") && html.endsWith("}") || html.startsWith("[") && html.endsWith("]"))) { html = "{" + html.match(/.*?\{(.*)\}/m)[1] + "}" } } catch (e) { } try { html = JSON.parse(html) } catch (e) { } return html } var OcrApi = { api: OCR_API, classification: function (img) { let code = ""; try { log("通过drpy_ocr验证码接口过验证..."); let html = request(OCR_API, { data: { img: img }, headers: { "User-Agent": PC_UA }, method: "POST" }, true); code = html || "" } catch (e) { log(`OCR识别验证码发生错误:${e.message}`) } return code } }; function verifyCode(url) { let cnt = 0; let host = getHome(url); let cookie = ""; while (cnt < OCR_RETRY) { try { let yzm_url = `${host}/index.php/verify/index.html`; console.log(`验证码链接:${yzm_url}`); let hhtml = request(yzm_url, { withHeaders: true, toBase64: true }, true); let json = JSON.parse(hhtml); if (!cookie) { let setCk = Object.keys(json).find(it => it.toLowerCase() === "set-cookie"); cookie = setCk ? json[setCk].split(";")[0] : "" } console.log("cookie:" + cookie); let img = json.body; let code = OcrApi.classification(img); console.log(`第${cnt + 1}次验证码识别结果:${code}`); let submit_url = `${host}/index.php/ajax/verify_check?type=search&verify=${code}`; console.log(submit_url); let html = request(submit_url, { headers: { Cookie: cookie, "User-Agent": MOBILE_UA }, method: "POST" }); html = JSON.parse(html); if (html.msg === "ok") { console.log(`第${cnt + 1}次验证码提交成功`); return cookie } else if (html.msg !== "ok" && cnt + 1 >= OCR_RETRY) { cookie = "" } } catch (e) { console.log(`第${cnt + 1}次验证码提交失败:${e.message}`); if (cnt + 1 >= OCR_RETRY) { cookie = "" } } cnt += 1 } return cookie } function setItem(k, v) { local.set(RKEY, k, v); console.log(`规则${RKEY}设置${k} => ${v}`) } function getItem(k, v) { return local.get(RKEY, k) || v } function clearItem(k) { local.delete(RKEY, k) } function getHome(url) { if (!url) { return "" } let tmp = url.split("//"); url = tmp[0] + "//" + tmp[1].split("/")[0]; try { url = decodeURIComponent(url) } catch (e) { } return url } function buildUrl(url, obj) { obj = obj || {}; if (url.indexOf("?") < 0) { url += "?" } let param_list = []; let keys = Object.keys(obj); keys.forEach(it => { param_list.push(it + "=" + obj[it]) }); let prs = param_list.join("&"); if (keys.length > 0 && !url.endsWith("?")) { url += "&" } url += prs; return url } function require(url) { eval(request(url)) } function request(url, obj, ocr_flag) { ocr_flag = ocr_flag || false; if (typeof obj === "undefined" || !obj || obj === {}) { if (!fetch_params || !fetch_params.headers) { let headers = { "User-Agent": MOBILE_UA }; if (rule.headers) { Object.assign(headers, rule.headers) } if (!fetch_params) { fetch_params = {} } fetch_params.headers = headers } if (!fetch_params.headers.Referer) { fetch_params.headers.Referer = getHome(url) } obj = fetch_params } else { let headers = obj.headers || {}; let keys = Object.keys(headers).map(it => it.toLowerCase()); if (!keys.includes("user-agent")) { headers["User-Agent"] = MOBILE_UA } if (!keys.includes("referer")) { headers["Referer"] = getHome(url) } obj.headers = headers } if (rule.encoding && rule.encoding !== "utf-8" && !ocr_flag) { if (!obj.headers.hasOwnProperty("Content-Type") && !obj.headers.hasOwnProperty("content-type")) { obj.headers["Content-Type"] = "text/html; charset=" + rule.encoding } } if (typeof obj.body != "undefined" && obj.body && typeof obj.body === "string") { if (!obj.headers.hasOwnProperty("Content-Type") && !obj.headers.hasOwnProperty("content-type")) { obj.headers["Content-Type"] = "application/x-www-form-urlencoded; charset=" + rule.encoding } } else if (typeof obj.body != "undefined" && obj.body && typeof obj.body === "object") { obj.data = obj.body; delete obj.body } if (!url) { return obj.withHeaders ? "{}" : "" } if (obj.toBase64) { obj.buffer = 2; delete obj.toBase64 } if (obj.redirect === false) { obj.redirect = 0 } console.log(JSON.stringify(obj.headers)); console.log("request:" + url + `|method:${obj.method || "GET"}|body:${obj.body || ""}`); let res = req(url, obj); let html = res.content || ""; if (obj.withHeaders) { let htmlWithHeaders = res.headers; htmlWithHeaders.body = html; return JSON.stringify(htmlWithHeaders) } else { return html } } function post(url, obj) { obj.method = "POST"; return request(url, obj) } fetch = request; print = function (data) { data = data || ""; if (typeof data == "object" && Object.keys(data).length > 0) { try { data = JSON.stringify(data); console.log(data) } catch (e) { console.log(typeof data + ":" + data.length); return } } else if (typeof data == "object" && Object.keys(data).length < 1) { console.log("null object") } else { console.log(data) } }; log = print; function checkHtml(html, url, obj) { if (/\?btwaf=/.test(html)) { let btwaf = html.match(/btwaf(.*?)"/)[1]; url = url.split("#")[0] + "?btwaf" + btwaf; print("宝塔验证访问链接:" + url); html = request(url, obj) } return html } function getCode(url, obj) { let html = request(url, obj); html = checkHtml(html, url, obj); return html } function getHtml(url) { let obj = {}; if (rule.headers) { obj.headers = rule.headers } let cookie = getItem(RULE_CK, ""); if (cookie) { if (obj.headers && !Object.keys(obj.headers).map(it => it.toLowerCase()).includes("cookie")) { log("历史无cookie,新增过验证后的cookie"); obj.headers["Cookie"] = cookie } else if (obj.headers && obj.headers.cookie && obj.headers.cookie !== cookie) { obj.headers["Cookie"] = cookie; log("历史有小写过期的cookie,更新过验证后的cookie") } else if (obj.headers && obj.headers.Cookie && obj.headers.Cookie !== cookie) { obj.headers["Cookie"] = cookie; log("历史有大写过期的cookie,更新过验证后的cookie") } else if (!obj.headers) { obj.headers = { Cookie: cookie }; log("历史无headers,更新过验证后的含cookie的headers") } } let html = getCode(url, obj); return html } function homeParse(homeObj) { fetch_params = JSON.parse(JSON.stringify(rule_fetch_params)); let classes = []; if (homeObj.class_name && homeObj.class_url) { let names = homeObj.class_name.split("&"); let urls = homeObj.class_url.split("&"); let cnt = Math.min(names.length, urls.length); for (let i = 0; i < cnt; i++) { classes.push({ type_id: urls[i], type_name: names[i] }) } } if (homeObj.class_parse) { if (homeObj.class_parse.startsWith("js:")) { var input = homeObj.MY_URL; try { eval(homeObj.class_parse.replace("js:", "")); if (Array.isArray(input)) { classes = input } } catch (e) { log("通过js动态获取分类发生了错误:" + e.message) } } else { let p = homeObj.class_parse.split(";"); let p0 = p[0]; let _ps = parseTags.getParse(p0); let is_json = p0.startsWith("json:"); _pdfa = _ps.pdfa; _pdfh = _ps.pdfh; _pd = _ps.pd; MY_URL = rule.url; if (is_json) { try { let cms_cate_url = homeObj.MY_URL.replace("ac=detail", "ac=list"); let html = getHtml(cms_cate_url); if (html) { if (cms_cate_url === homeObj.MY_URL) { homeHtmlCache = html } let list = _pdfa(html, p0.replace("json:", "")); if (list && list.length > 0) { classes = list } } } catch (e) { console.log(e.message) } } else if (p.length >= 3 && !is_json) { try { let html = getHtml(homeObj.MY_URL); if (html) { homeHtmlCache = html; let list = _pdfa(html, p0); if (list && list.length > 0) { list.forEach((it, idex) => { try { let name = _pdfh(it, p[1]); if (homeObj.cate_exclude && new RegExp(homeObj.cate_exclude).test(name)) { return } let url = _pd(it, p[2]); if (p.length > 3 && p[3]) { let exp = new RegExp(p[3]); url = url.match(exp)[1] } classes.push({ type_id: url.trim(), type_name: name.trim() }) } catch (e) { console.log(`分类列表定位第${idex}个元素正常报错:${e.message}`) } }) } } } catch (e) { console.log(e.message) } } } } classes = classes.filter(it => !homeObj.cate_exclude || !new RegExp(homeObj.cate_exclude).test(it.type_name)); let resp = { class: classes }; if (homeObj.filter) { resp.filters = homeObj.filter } console.log(JSON.stringify(resp)); return JSON.stringify(resp) } function getPP(p, pn, pp, ppn) { try { let ps = p[pn] === "*" && pp.length > ppn ? pp[ppn] : p[pn]; return ps } catch (e) { return "" } } function homeVodParse(homeVodObj) { fetch_params = JSON.parse(JSON.stringify(rule_fetch_params)); let d = []; MY_URL = homeVodObj.homeUrl; console.log(MY_URL); let t1 = (new Date).getTime(); let p = homeVodObj.推荐; print("p:" + p); if (p === "*" && rule.一级) { p = rule.一级; homeVodObj.double = false } if (!p || typeof p !== "string") { return "{}" } p = p.trim(); let pp = rule.一级.split(";"); if (p.startsWith("js:")) { const TYPE = "home"; var input = MY_URL; HOST = rule.host; eval(p.replace("js:", "")); d = VODS } else { p = p.split(";"); if (!homeVodObj.double && p.length < 5) { return "{}" } else if (homeVodObj.double && p.length < 6) { return "{}" } let p0 = getPP(p, 0, pp, 0); let _ps = parseTags.getParse(p0); _pdfa = _ps.pdfa; _pdfh = _ps.pdfh; _pd = _ps.pd; let is_json = p0.startsWith("json:"); p0 = p0.replace(/^(jsp:|json:|jq:)/, ""); let html = homeHtmlCache || getHtml(MY_URL); homeHtmlCache = undefined; if (is_json) { html = dealJson(html) } try { console.log("double:" + homeVodObj.double); if (homeVodObj.double) { let items = _pdfa(html, p0); let p1 = getPP(p, 1, pp, 0); let p2 = getPP(p, 2, pp, 1); let p3 = getPP(p, 3, pp, 2); let p4 = getPP(p, 4, pp, 3); let p5 = getPP(p, 5, pp, 4); let p6 = getPP(p, 6, pp, 5); for (let item of items) { let items2 = _pdfa(item, p1); for (let item2 of items2) { try { let title = _pdfh(item2, p2); let img = ""; try { img = _pd(item2, p3) } catch (e) { } let desc = ""; try { desc = _pdfh(item2, p4) } catch (e) { } let links = []; for (let _p5 of p5.split("+")) { let link = !homeVodObj.detailUrl ? _pd(item2, _p5, MY_URL) : _pdfh(item2, _p5); links.push(link) } let content; if (p.length > 6 && p[6]) { content = _pdfh(item2, p6) } else { content = "" } let vid = links.join("$"); if (rule.二级 === "*") { vid = vid + "@@" + title + "@@" + img } let vod = { vod_name: title, vod_pic: img, vod_remarks: desc, vod_content: content, vod_id: vid }; d.push(vod) } catch (e) { console.log("首页列表双层定位处理发生错误:" + e.message) } } } } else { let items = _pdfa(html, p0); let p1 = getPP(p, 1, pp, 1); let p2 = getPP(p, 2, pp, 2); let p3 = getPP(p, 3, pp, 3); let p4 = getPP(p, 4, pp, 4); let p5 = getPP(p, 5, pp, 5); for (let item of items) { try { let title = _pdfh(item, p1); let img = ""; try { img = _pd(item, p2, MY_URL) } catch (e) { } let desc = ""; try { desc = _pdfh(item, p3) } catch (e) { } let links = []; for (let _p5 of p4.split("+")) { let link = !homeVodObj.detailUrl ? _pd(item, _p5, MY_URL) : _pdfh(item, _p5); links.push(link) } let content; if (p.length > 5 && p[5]) { content = _pdfh(item, p5) } else { content = "" } let vid = links.join("$"); if (rule.二级 === "*") { vid = vid + "@@" + title + "@@" + img } let vod = { vod_name: title, vod_pic: img, vod_remarks: desc, vod_content: content, vod_id: vid }; d.push(vod) } catch (e) { console.log("首页列表单层定位处理发生错误:" + e.message) } } } } catch (e) { } } let t2 = (new Date).getTime(); console.log("加载首页推荐耗时:" + (t2 - t1) + "毫秒"); if (rule.图片替换 && rule.图片替换.includes("=>")) { let replace_from = rule.图片替换.split("=>")[0]; let replace_to = rule.图片替换.split("=>")[1]; d.forEach(it => { if (it.vod_pic && it.vod_pic.startsWith("http")) { it.vod_pic = it.vod_pic.replace(replace_from, replace_to) } }) } if (rule.图片来源) { d.forEach(it => { if (it.vod_pic && it.vod_pic.startsWith("http")) { it.vod_pic = it.vod_pic + rule.图片来源 } }) } if (d.length > 0) { print(d.slice(0, 2)) } return JSON.stringify({ list: d }) } function categoryParse(cateObj) { fetch_params = JSON.parse(JSON.stringify(rule_fetch_params)); let p = cateObj.一级; if (!p || typeof p !== "string") { return "{}" } let d = []; let url = cateObj.url.replaceAll("fyclass", cateObj.tid); if (cateObj.pg === 1 && url.includes("[") && url.includes("]")) { url = url.split("[")[1].split("]")[0] } else if (cateObj.pg > 1 && url.includes("[") && url.includes("]")) { url = url.split("[")[0] } if (rule.filter_url) { if (!/fyfilter/.test(url)) { if (!url.endsWith("&") && !rule.filter_url.startsWith("&")) { url += "&" } url += rule.filter_url } else { url = url.replace("fyfilter", rule.filter_url) } let fl = cateObj.filter ? cateObj.extend : {}; if (rule.filter_def && typeof rule.filter_def === "object") { try { if (Object.keys(rule.filter_def).length > 0 && rule.filter_def.hasOwnProperty(cateObj.tid)) { let self_fl_def = rule.filter_def[cateObj.tid]; if (self_fl_def && typeof self_fl_def === "object") { let fl_def = JSON.parse(JSON.stringify(self_fl_def)); fl = Object.assign(fl_def, fl) } } } catch (e) { print("合并不同分类对应的默认筛选出错:" + e.message) } } let new_url; new_url = cheerio.jinja2(url, { fl: fl }); url = new_url } if (/fypage/.test(url)) { if (url.includes("(") && url.includes(")")) { let url_rep = url.match(/.*?\((.*)\)/)[1]; let cnt_page = url_rep.replaceAll("fypage", cateObj.pg); let cnt_pg = eval(cnt_page); url = url.replaceAll(url_rep, cnt_pg).replaceAll("(", "").replaceAll(")", "") } else { url = url.replaceAll("fypage", cateObj.pg) } } MY_URL = url; console.log(MY_URL); p = p.trim(); const MY_CATE = cateObj.tid; if (p.startsWith("js:")) { var MY_FL = cateObj.extend; const TYPE = "cate"; var input = MY_URL; const MY_PAGE = cateObj.pg; var desc = ""; eval(p.trim().replace("js:", "")); d = VODS } else { p = p.split(";"); if (p.length < 5) { return "{}" } let _ps = parseTags.getParse(p[0]); _pdfa = _ps.pdfa; _pdfh = _ps.pdfh; _pd = _ps.pd; let is_json = p[0].startsWith("json:"); p[0] = p[0].replace(/^(jsp:|json:|jq:)/, ""); try { let html = getHtml(MY_URL); if (html) { if (is_json) { html = dealJson(html) } let list = _pdfa(html, p[0]); list.forEach(it => { let links = p[4].split("+").map(p4 => { return !rule.detailUrl ? _pd(it, p4, MY_URL) : _pdfh(it, p4) }); let link = links.join("$"); let vod_id = rule.detailUrl ? MY_CATE + "$" + link : link; let vod_name = _pdfh(it, p[1]).replace(/\n|\t/g, "").trim(); let vod_pic = _pd(it, p[2], MY_URL); if (rule.二级 === "*") { vod_id = vod_id + "@@" + vod_name + "@@" + vod_pic } d.push({ vod_id: vod_id, vod_name: vod_name, vod_pic: vod_pic, vod_remarks: _pdfh(it, p[3]).replace(/\n|\t/g, "").trim() }) }) } } catch (e) { console.log(e.message) } } if (rule.图片替换 && rule.图片替换.includes("=>")) { let replace_from = rule.图片替换.split("=>")[0]; let replace_to = rule.图片替换.split("=>")[1]; d.forEach(it => { if (it.vod_pic && it.vod_pic.startsWith("http")) { it.vod_pic = it.vod_pic.replace(replace_from, replace_to) } }) } if (rule.图片来源) { d.forEach(it => { if (it.vod_pic && it.vod_pic.startsWith("http")) { it.vod_pic = it.vod_pic + rule.图片来源 } }) } if (d.length > 0) { print(d.slice(0, 2)) } let pagecount = 0; if (rule.pagecount && typeof rule.pagecount === "object" && rule.pagecount.hasOwnProperty(MY_CATE)) { print(`MY_CATE:${MY_CATE},pagecount:${JSON.stringify(rule.pagecount)}`); pagecount = parseInt(rule.pagecount[MY_CATE]) } let nodata = { list: [{ vod_name: "无数据,防无限请求", vod_id: "no_data", vod_remarks: "不要点,会崩的", vod_pic: "https://ghproxy.net/https://raw.githubusercontent.com/hjdhnx/dr_py/main/404.jpg" }], total: 1, pagecount: 1, page: 1, limit: 1 }; let vod = d.length < 1 ? JSON.stringify(nodata) : JSON.stringify({ page: parseInt(cateObj.pg), pagecount: pagecount || 999, limit: 20, total: 999, list: d }); return vod } function searchParse(searchObj) { fetch_params = JSON.parse(JSON.stringify(rule_fetch_params)); let d = []; if (!searchObj.searchUrl) { return "{}" } let p = searchObj.搜索 === "*" && rule.一级 ? rule.一级 : searchObj.搜索; if (!p || typeof p !== "string") { return "{}" } p = p.trim(); let pp = rule.一级.split(";"); let url = searchObj.searchUrl.replaceAll("**", searchObj.wd); if (searchObj.pg === 1 && url.includes("[") && url.includes("]") && !url.includes("#")) { url = url.split("[")[1].split("]")[0] } else if (searchObj.pg > 1 && url.includes("[") && url.includes("]") && !url.includes("#")) { url = url.split("[")[0] } if (/fypage/.test(url)) { if (url.includes("(") && url.includes(")")) { let url_rep = url.match(/.*?\((.*)\)/)[1]; let cnt_page = url_rep.replaceAll("fypage", searchObj.pg); let cnt_pg = eval(cnt_page); url = url.replaceAll(url_rep, cnt_pg).replaceAll("(", "").replaceAll(")", "") } else { url = url.replaceAll("fypage", searchObj.pg) } } MY_URL = url; console.log(MY_URL); if (p.startsWith("js:")) { const TYPE = "search"; const MY_PAGE = searchObj.pg; const KEY = searchObj.wd; var input = MY_URL; var detailUrl = rule.detailUrl || ""; eval(p.trim().replace("js:", "")); d = VODS } else { p = p.split(";"); if (p.length < 5) { return "{}" } let p0 = getPP(p, 0, pp, 0); let _ps = parseTags.getParse(p0); _pdfa = _ps.pdfa; _pdfh = _ps.pdfh; _pd = _ps.pd; let is_json = p0.startsWith("json:"); p0 = p0.replace(/^(jsp:|json:|jq:)/, ""); try { let req_method = MY_URL.split(";").length > 1 ? MY_URL.split(";")[1].toLowerCase() : "get"; let html; if (req_method === "post") { let rurls = MY_URL.split(";")[0].split("#"); let rurl = rurls[0]; let params = rurls.length > 1 ? rurls[1] : ""; print(`post=》rurl:${rurl},params:${params}`); let _fetch_params = JSON.parse(JSON.stringify(rule_fetch_params)); let postData = { body: params }; Object.assign(_fetch_params, postData); html = post(rurl, _fetch_params) } else if (req_method === "postjson") { let rurls = MY_URL.split(";")[0].split("#"); let rurl = rurls[0]; let params = rurls.length > 1 ? rurls[1] : ""; print(`postjson-》rurl:${rurl},params:${params}`); try { params = JSON.parse(params) } catch (e) { params = "{}" } let _fetch_params = JSON.parse(JSON.stringify(rule_fetch_params)); let postData = { body: params }; Object.assign(_fetch_params, postData); html = post(rurl, _fetch_params) } else { html = getHtml(MY_URL) } if (html) { if (/系统安全验证|输入验证码/.test(html)) { let cookie = verifyCode(MY_URL); if (cookie) { console.log(`本次成功过验证,cookie:${cookie}`); setItem(RULE_CK, cookie) } else { console.log(`本次自动过搜索验证失败,cookie:${cookie}`) } html = getHtml(MY_URL) } if (!html.includes(searchObj.wd)) { console.log("搜索结果源码未包含关键字,疑似搜索失败,正为您打印结果源码"); console.log(html) } if (is_json) { html = dealJson(html) } let list = _pdfa(html, p0); let p1 = getPP(p, 1, pp, 1); let p2 = getPP(p, 2, pp, 2); let p3 = getPP(p, 3, pp, 3); let p4 = getPP(p, 4, pp, 4); let p5 = getPP(p, 5, pp, 5); list.forEach(it => { let links = p4.split("+").map(_p4 => { return !rule.detailUrl ? _pd(it, _p4, MY_URL) : _pdfh(it, _p4) }); let link = links.join("$"); let content; if (p.length > 5 && p[5]) { content = _pdfh(it, p5) } else { content = "" } let vod_id = link; let vod_name = _pdfh(it, p1).replace(/\n|\t/g, "").trim(); let vod_pic = _pd(it, p2, MY_URL); if (rule.二级 === "*") { vod_id = vod_id + "@@" + vod_name + "@@" + vod_pic } let ob = { vod_id: vod_id, vod_name: vod_name, vod_pic: vod_pic, vod_remarks: _pdfh(it, p3).replace(/\n|\t/g, "").trim(), vod_content: content.replace(/\n|\t/g, "").trim() }; d.push(ob) }) } } catch (e) { print("搜索发生错误:" + e.message); return "{}" } } if (rule.图片替换 && rule.图片替换.includes("=>")) { let replace_from = rule.图片替换.split("=>")[0]; let replace_to = rule.图片替换.split("=>")[1]; d.forEach(it => { if (it.vod_pic && it.vod_pic.startsWith("http")) { it.vod_pic = it.vod_pic.replace(replace_from, replace_to) } }) } if (rule.图片来源) { d.forEach(it => { if (it.vod_pic && it.vod_pic.startsWith("http")) { it.vod_pic = it.vod_pic + rule.图片来源 } }) } return JSON.stringify({ page: parseInt(searchObj.pg), pagecount: 10, limit: 20, total: 100, list: d }) } function detailParse(detailObj) { let t1 = (new Date).getTime(); fetch_params = JSON.parse(JSON.stringify(rule_fetch_params)); let orId = detailObj.orId; let vod_name = "片名"; let vod_pic = ""; let vod_id = orId; if (rule.二级 === "*") { let extra = orId.split("@@"); vod_name = extra.length > 1 ? extra[1] : vod_name; vod_pic = extra.length > 2 ? extra[2] : vod_pic } let vod = { vod_id: vod_id, vod_name: vod_name, vod_pic: vod_pic, type_name: "类型", vod_year: "年份", vod_area: "地区", vod_remarks: "更新信息", vod_actor: "主演", vod_director: "导演", vod_content: "简介" }; let p = detailObj.二级; let url = detailObj.url; let detailUrl = detailObj.detailUrl; let fyclass = detailObj.fyclass; let tab_exclude = detailObj.tab_exclude; let html = detailObj.html || ""; MY_URL = url; if (detailObj.二级访问前) { try { print(`尝试在二级访问前执行代码:${detailObj.二级访问前}`); eval(detailObj.二级访问前.trim().replace("js:", "")) } catch (e) { print(`二级访问前执行代码出现错误:${e.message}`) } } if (p === "*") { vod.vod_play_from = "道长在线"; vod.vod_remarks = detailUrl; vod.vod_actor = "没有二级,只有一级链接直接嗅探播放"; vod.vod_content = MY_URL; vod.vod_play_url = "嗅探播放$" + MY_URL.split("@@")[0] } else if (typeof p === "string" && p.trim().startsWith("js:")) { const TYPE = "detail"; var input = MY_URL; var play_url = ""; eval(p.trim().replace("js:", "")); vod = VOD; console.log(JSON.stringify(vod)) } else if (p && typeof p === "object") { let tt1 = (new Date).getTime(); if (!html) { html = getHtml(MY_URL) } print(`二级${MY_URL}仅获取源码耗时:${(new Date).getTime() - tt1}毫秒`); let _ps; if (p.is_json) { print("二级是json"); _ps = parseTags.json; html = dealJson(html) } else if (p.is_jsp) { print("二级是jsp"); _ps = parseTags.jsp } else if (p.is_jq) { print("二级是jq"); _ps = parseTags.jq } else { print("二级默认jq"); _ps = parseTags.jq } let tt2 = (new Date).getTime(); print(`二级${MY_URL}获取并装载源码耗时:${tt2 - tt1}毫秒`); _pdfa = _ps.pdfa; _pdfh = _ps.pdfh; _pd = _ps.pd; if (p.title) { let p1 = p.title.split(";"); vod.vod_name = _pdfh(html, p1[0]).replace(/\n|\t/g, "").trim(); let type_name = p1.length > 1 ? _pdfh(html, p1[1]).replace(/\n|\t/g, "").replace(/ /g, "").trim() : ""; vod.type_name = type_name || vod.type_name } if (p.desc) { try { let p1 = p.desc.split(";"); vod.vod_remarks = _pdfh(html, p1[0]).replace(/\n|\t/g, "").trim(); vod.vod_year = p1.length > 1 ? _pdfh(html, p1[1]).replace(/\n|\t/g, "").trim() : ""; vod.vod_area = p1.length > 2 ? _pdfh(html, p1[2]).replace(/\n|\t/g, "").trim() : ""; vod.vod_actor = p1.length > 3 ? _pdfh(html, p1[3]).replace(/\n|\t/g, "").trim() : ""; vod.vod_director = p1.length > 4 ? _pdfh(html, p1[4]).replace(/\n|\t/g, "").trim() : "" } catch (e) { } } if (p.content) { try { let p1 = p.content.split(";"); vod.vod_content = _pdfh(html, p1[0]).replace(/\n|\t/g, "").trim() } catch (e) { } } if (p.img) { try { let p1 = p.img.split(";"); vod.vod_pic = _pd(html, p1[0], MY_URL) } catch (e) { } } let vod_play_from = "$$$"; let playFrom = []; if (p.重定向 && p.重定向.startsWith("js:")) { print("开始执行重定向代码:" + p.重定向); html = eval(p.重定向.replace("js:", "")) } if (p.tabs) { if (p.tabs.startsWith("js:")) { print("开始执行tabs代码:" + p.tabs); var input = MY_URL; eval(p.tabs.replace("js:", "")); playFrom = TABS } else { let p_tab = p.tabs.split(";")[0]; let vHeader = _pdfa(html, p_tab); console.log(vHeader.length); let tab_text = p.tab_text || "body&&Text"; let new_map = {}; for (let v of vHeader) { let v_title = _pdfh(v, tab_text).trim(); if (!v_title) { v_title = "线路空" } console.log(v_title); if (tab_exclude && new RegExp(tab_exclude).test(v_title)) { continue } if (!new_map.hasOwnProperty(v_title)) { new_map[v_title] = 1 } else { new_map[v_title] += 1 } if (new_map[v_title] > 1) { v_title += Number(new_map[v_title] - 1) } playFrom.push(v_title) } } console.log(JSON.stringify(playFrom)) } else { playFrom = ["道长在线"] } vod.vod_play_from = playFrom.join(vod_play_from); let vod_play_url = "$$$"; let vod_tab_list = []; if (p.lists) { if (p.lists.startsWith("js:")) { print("开始执行lists代码:" + p.lists); try { var input = MY_URL; var play_url = ""; eval(p.lists.replace("js:", "")); for (let i in LISTS) { if (LISTS.hasOwnProperty(i)) { try { LISTS[i] = LISTS[i].map(it => it.split("$").slice(0, 2).join("$")) } catch (e) { print("格式化LISTS发生错误:" + e.message) } } } vod_play_url = LISTS.map(it => it.join("#")).join(vod_play_url) } catch (e) { print("js执行lists: 发生错误:" + e.message) } } else { let list_text = p.list_text || "body&&Text"; let list_url = p.list_url || "a&&href"; let is_tab_js = p.tabs.trim().startsWith("js:"); for (let i = 0; i < playFrom.length; i++) { let tab_name = playFrom[i]; let tab_ext = p.tabs.split(";").length > 1 && !is_tab_js ? p.tabs.split(";")[1] : ""; let p1 = p.lists.replaceAll("#idv", tab_name).replaceAll("#id", i); tab_ext = tab_ext.replaceAll("#idv", tab_name).replaceAll("#id", i); let tabName = tab_ext ? _pdfh(html, tab_ext) : tab_name; console.log(tabName); let new_vod_list = []; let tt1 = (new Date).getTime(); if (typeof pdfl === "function") { new_vod_list = pdfl(html, p1, list_text, list_url, MY_URL) } else { let vodList = []; try { vodList = _pdfa(html, p1); console.log("len(vodList):" + vodList.length) } catch (e) { } for (let i = 0; i < vodList.length; i++) { let it = vodList[i]; new_vod_list.push(_pdfh(it, list_text).trim() + "$" + _pd(it, list_url, MY_URL)) } } if (new_vod_list.length > 0) { new_vod_list = forceOrder(new_vod_list, "", x => x.split("$")[0]); console.log(`drpy影响性能代码共计列表数循环次数:${new_vod_list.length},耗时:${(new Date).getTime() - tt1}毫秒`) } let vlist = new_vod_list.join("#"); vod_tab_list.push(vlist) } vod_play_url = vod_tab_list.join(vod_play_url) } } vod.vod_play_url = vod_play_url } if (rule.图片替换 && rule.图片替换.includes("=>")) { let replace_from = rule.图片替换.split("=>")[0]; let replace_to = rule.图片替换.split("=>")[1]; vod.vod_pic = vod.vod_pic.replace(replace_from, replace_to) } if (rule.图片来源 && vod.vod_pic && vod.vod_pic.startsWith("http")) { vod.vod_pic = vod.vod_pic + rule.图片来源 } if (!vod.vod_id || vod_id.includes("$") && vod.vod_id !== vod_id) { vod.vod_id = vod_id } let t2 = (new Date).getTime(); console.log(`加载二级界面${MY_URL}耗时:${t2 - t1}毫秒`); vod = vodDeal(vod); return JSON.stringify({ list: [vod] }) } function get_tab_index(vod) { let obj = {}; vod.vod_play_from.split("$$$").forEach((it, index) => { obj[it] = index }); return obj } function vodDeal(vod) { let vod_play_from = vod.vod_play_from.split("$$$"); let vod_play_url = vod.vod_play_url.split("$$$"); let tab_removed_list = vod_play_from; let tab_ordered_list = vod_play_from; let tab_renamed_list = vod_play_from; let tab_list = vod_play_from; let play_ordered_list = vod_play_url; if (rule.tab_remove && rule.tab_remove.length > 0 || rule.tab_order && rule.tab_order.length > 0) { let tab_index_dict = get_tab_index(vod); if (rule.tab_remove && rule.tab_remove.length > 0) { tab_removed_list = vod_play_from.filter(it => !rule.tab_remove.includes(it)); tab_list = tab_removed_list } if (rule.tab_order && rule.tab_order.length > 0) { let tab_order = rule.tab_order; tab_ordered_list = tab_removed_list.sort((a, b) => { return (tab_order.indexOf(a) === -1 ? 9999 : tab_order.indexOf(a)) - (tab_order.indexOf(b) === -1 ? 9999 : tab_order.indexOf(b)) }); tab_list = tab_ordered_list } play_ordered_list = tab_list.map(it => vod_play_url[tab_index_dict[it]]) } if (rule.tab_rename && typeof rule.tab_rename === "object" & Object.keys(rule.tab_rename).length > 0) { tab_renamed_list = tab_list.map(it => rule.tab_rename[it] || it); tab_list = tab_renamed_list } vod.vod_play_from = tab_list.join("$$$"); vod.vod_play_url = play_ordered_list.join("$$$"); return vod } function tellIsJx(url) { try { let is_vip = !/\.(m3u8|mp4|m4a)$/.test(url.split("?")[0]) && 是否正版(url); return is_vip ? 1 : 0 } catch (e) { return 1 } } function playParse(playObj) { fetch_params = JSON.parse(JSON.stringify(rule_fetch_params)); MY_URL = playObj.url; var MY_FLAG = playObj.flag; if (!/http/.test(MY_URL)) { try { MY_URL = base64Decode(MY_URL) } catch (e) { } } MY_URL = decodeURIComponent(MY_URL); var input = MY_URL; var flag = MY_FLAG; let common_play = { parse: 1, url: input, flag: flag, jx: tellIsJx(input) }; let lazy_play; if (!rule.play_parse || !rule.lazy) { lazy_play = common_play } else if (rule.play_parse && rule.lazy && typeof rule.lazy === "string") { try { let lazy_code = rule.lazy.replace("js:", "").trim(); print("开始执行js免嗅=>" + lazy_code); eval(lazy_code); lazy_play = typeof input === "object" ? input : { parse: 1, jx: tellIsJx(input), url: input } } catch (e) { print("js免嗅错误:" + e.message); lazy_play = common_play } } else { lazy_play = common_play } if (Array.isArray(rule.play_json) && rule.play_json.length > 0) { let web_url = lazy_play.url; for (let pjson of rule.play_json) { if (pjson.re && (pjson.re === "*" || web_url.match(new RegExp(pjson.re)))) { if (pjson.json && typeof pjson.json === "object") { let base_json = pjson.json; lazy_play = Object.assign(lazy_play, base_json); break } } } } else if (rule.play_json && !Array.isArray(rule.play_json)) { let base_json = { jx: 1, parse: 1 }; lazy_play = Object.assign(lazy_play, base_json) } else if (!rule.play_json) { let base_json = { jx: 0, parse: 1 }; lazy_play = Object.assign(lazy_play, base_json) } console.log(JSON.stringify(lazy_play)); return JSON.stringify(lazy_play) } function proxyParse(proxyObj) { var input = proxyObj.params; if (proxyObj.proxy_rule) { log("准备执行本地代理规则:\n" + proxyObj.proxy_rule); try { eval(proxyObj.proxy_rule); if (input && input !== proxyObj.params && Array.isArray(input) && input.length === 3) { return input } else { return [404, "text/plain", "Not Found"] } } catch (e) { return [500, "text/plain", "代理规则错误:" + e.message] } } else { return [404, "text/plain", "Not Found"] } } function isVideoParse(isVideoObj) { var input = isVideoObj.url; if (!isVideoObj.t) { let re_matcher = new RegExp(isVideoObj.isVideo, "i"); return re_matcher.test(input) } else { try { eval(isVideoObj.isVideo); if (typeof input === "boolean") { return input } else { return false } } catch (e) { log("执行嗅探规则发生错误:" + e.message); return false } } } function init(ext) { console.log("init"); try { let muban = 模板.getMubans(); if (typeof ext == "object") { rule = ext } else if (typeof ext == "string") { if (ext.startsWith("http")) { let js = request(ext, { method: "GET" }); if (js) { eval(js.replace("var rule", "rule")) } } else { eval(ext.replace("var rule", "rule")) } } if (rule.模板 && muban.hasOwnProperty(rule.模板)) { print("继承模板:" + rule.模板); rule = Object.assign(muban[rule.模板], rule) } let rule_cate_excludes = (rule.cate_exclude || "").split("|").filter(it => it.trim()); let rule_tab_excludes = (rule.tab_exclude || "").split("|").filter(it => it.trim()); rule_cate_excludes = rule_cate_excludes.concat(CATE_EXCLUDE.split("|").filter(it => it.trim())); rule_tab_excludes = rule_tab_excludes.concat(TAB_EXCLUDE.split("|").filter(it => it.trim())); rule.cate_exclude = rule_cate_excludes.join("|"); rule.tab_exclude = rule_tab_excludes.join("|"); rule.host = (rule.host || "").rstrip("/"); HOST = rule.host; if (rule.hostJs) { console.log(`检测到hostJs,准备执行...`); try { eval(rule.hostJs); rule.host = HOST.rstrip("/") } catch (e) { console.log(`执行${rule.hostJs}获取host发生错误:` + e.message) } } rule.url = rule.url || ""; rule.double = rule.double || false; rule.homeUrl = rule.homeUrl || ""; rule.detailUrl = rule.detailUrl || ""; rule.searchUrl = rule.searchUrl || ""; rule.homeUrl = rule.host && rule.homeUrl ? urljoin(rule.host, rule.homeUrl) : rule.homeUrl || rule.host; rule.homeUrl = cheerio.jinja2(rule.homeUrl, { rule: rule }); rule.detailUrl = rule.host && rule.detailUrl ? urljoin(rule.host, rule.detailUrl) : rule.detailUrl; rule.二级访问前 = rule.二级访问前 || ""; if (rule.url.includes("[") && rule.url.includes("]")) { let u1 = rule.url.split("[")[0]; let u2 = rule.url.split("[")[1].split("]")[0]; rule.url = rule.host && rule.url ? urljoin(rule.host, u1) + "[" + urljoin(rule.host, u2) + "]" : rule.url } else { rule.url = rule.host && rule.url ? urljoin(rule.host, rule.url) : rule.url } if (rule.searchUrl.includes("[") && rule.searchUrl.includes("]") && !rule.searchUrl.includes("#")) { let u1 = rule.searchUrl.split("[")[0]; let u2 = rule.searchUrl.split("[")[1].split("]")[0]; rule.searchUrl = rule.host && rule.searchUrl ? urljoin(rule.host, u1) + "[" + urljoin(rule.host, u2) + "]" : rule.searchUrl } else { rule.searchUrl = rule.host && rule.searchUrl ? urljoin(rule.host, rule.searchUrl) : rule.searchUrl } rule.timeout = rule.timeout || 5e3; rule.encoding = rule.编码 || rule.encoding || "utf-8"; rule.search_encoding = rule.搜索编码 || rule.search_encoding || ""; rule.图片来源 = rule.图片来源 || ""; rule.图片替换 = rule.图片替换 || ""; rule.play_json = rule.hasOwnProperty("play_json") ? rule.play_json : []; rule.pagecount = rule.hasOwnProperty("pagecount") ? rule.pagecount : {}; rule.proxy_rule = rule.hasOwnProperty("proxy_rule") ? rule.proxy_rule : ""; rule.sniffer = rule.hasOwnProperty("sniffer") ? rule.sniffer : ""; rule.sniffer = !!(rule.sniffer && rule.sniffer !== "0" && rule.sniffer !== "false"); rule.isVideo = rule.hasOwnProperty("isVideo") ? rule.isVideo : ""; rule.tab_remove = rule.hasOwnProperty("tab_remove") ? rule.tab_remove : []; rule.tab_order = rule.hasOwnProperty("tab_order") ? rule.tab_order : []; rule.tab_rename = rule.hasOwnProperty("tab_rename") ? rule.tab_rename : {}; if (rule.headers && typeof rule.headers === "object") { try { let header_keys = Object.keys(rule.headers); for (let k of header_keys) { if (k.toLowerCase() === "user-agent") { let v = rule.headers[k]; console.log(v); if (["MOBILE_UA", "PC_UA", "UC_UA", "IOS_UA", "UA"].includes(v)) { rule.headers[k] = eval(v) } } else if (k.toLowerCase() === "cookie") { let v = rule.headers[k]; if (v && v.startsWith("http")) { console.log(v); try { v = fetch(v); console.log(v); rule.headers[k] = v } catch (e) { console.log(`从${v}获取cookie发生错误:` + e.message) } } } } } catch (e) { console.log("处理headers发生错误:" + e.message) } } rule_fetch_params = { headers: rule.headers || false, timeout: rule.timeout, encoding: rule.encoding }; oheaders = rule.headers || {}; RKEY = typeof key !== "undefined" && key ? key : "drpy_" + (rule.title || rule.host); pre(); init_test() } catch (e) { console.log("init_test发生错误:" + e.message) } } let homeHtmlCache = undefined; function home(filter) { console.log("home"); let homeObj = { filter: rule.filter || false, MY_URL: rule.homeUrl, class_name: rule.class_name || "", class_url: rule.class_url || "", class_parse: rule.class_parse || "", cate_exclude: rule.cate_exclude }; return homeParse(homeObj) } function homeVod(params) { console.log("homeVod"); let homeVodObj = { "推荐": rule.推荐, double: rule.double, homeUrl: rule.homeUrl, detailUrl: rule.detailUrl }; return homeVodParse(homeVodObj) } function category(tid, pg, filter, extend) { let cateObj = { url: rule.url, "一级": rule.一级, tid: tid, pg: parseInt(pg), filter: filter, extend: extend }; return categoryParse(cateObj) } function detail(vod_url) { let orId = vod_url; let fyclass = ""; log("orId:" + orId); if (vod_url.indexOf("$") > -1) { let tmp = vod_url.split("$"); fyclass = tmp[0]; vod_url = tmp[1] } let detailUrl = vod_url.split("@@")[0]; let url; if (!detailUrl.startsWith("http") && !detailUrl.includes("/")) { url = rule.detailUrl.replaceAll("fyid", detailUrl).replaceAll("fyclass", fyclass) } else if (detailUrl.includes("/")) { url = urljoin(rule.homeUrl, detailUrl) } else { url = detailUrl } let detailObj = { orId: orId, url: url, "二级": rule.二级, "二级访问前": rule.二级访问前, detailUrl: detailUrl, fyclass: fyclass, tab_exclude: rule.tab_exclude }; return detailParse(detailObj) } function play(flag, id, flags) { let playObj = { url: id, flag: flag, flags: flags }; return playParse(playObj) } function search(wd, quick, pg) { if (rule.search_encoding) { if (rule.search_encoding.toLowerCase() !== "utf-8") { wd = encodeStr(wd, rule.search_encoding) } } else if (rule.encoding && rule.encoding.toLowerCase() !== "utf-8") { wd = encodeStr(wd, rule.encoding) } let searchObj = { searchUrl: rule.searchUrl, "搜索": rule.搜索, wd: wd, pg: pg || 1, quick: quick }; return searchParse(searchObj) } function proxy(params) { if (rule.proxy_rule && rule.proxy_rule.trim()) { rule.proxy_rule = rule.proxy_rule.trim() } if (rule.proxy_rule.startsWith("js:")) { rule.proxy_rule = rule.proxy_rule.replace("js:", "") } let proxyObj = { params: params, proxy_rule: rule.proxy_rule }; return proxyParse(proxyObj) } function sniffer() { let enable_sniffer = rule.sniffer || false; if (enable_sniffer) { log("开始执行辅助嗅探代理规则...") } return enable_sniffer } function isVideo(url) { let t = 0; let is_video; if (rule.isVideo && rule.isVideo.trim()) { is_video = rule.isVideo.trim() } if (is_video.startsWith("js:")) { is_video = is_video.replace("js:", ""); t = 1 } let isVideoObj = { url: url, isVideo: is_video, t: t }; let result = isVideoParse(isVideoObj); if (result) { log("成功执行辅助嗅探规则并检测到视频地址:\n" + rule.isVideo) } return result } function DRPY() { return { init: init, home: home, homeVod: homeVod, category: category, detail: detail, play: play, search: search, proxy: proxy, sniffer: sniffer, isVideo: isVideo } } export default { init: init, home: home, homeVod: homeVod, category: category, detail: detail, play: play, search: search, proxy: proxy, sniffer: sniffer, isVideo: isVideo, DRPY: DRPY }; --------------------------------------------------------------------------------