From 77c526af9bfcefff24b941564dce042035fef5f3 Mon Sep 17 00:00:00 2001 From: hjdhnx Date: Thu, 8 Sep 2022 13:37:40 +0800 Subject: [PATCH] =?UTF-8?q?=E4=B8=80=E7=BA=A7=E5=AE=8C=E7=BE=8E=E6=94=AF?= =?UTF-8?q?=E6=8C=81js?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- controllers/cms.py | 127 +++++++++----- ...07\347\217\215\345\274\202\345\205\275.js" | 30 ++++ libs/pre.js | 165 +++++++++++++----- ...07\350\211\272\344\270\200\347\272\247.js" | 60 +++++++ 4 files changed, 291 insertions(+), 91 deletions(-) create mode 100644 "js/\345\245\207\347\217\215\345\274\202\345\205\275.js" create mode 100644 "py/\347\210\261\345\245\207\350\211\272\344\270\200\347\272\247.js" diff --git a/controllers/cms.py b/controllers/cms.py index 332630a..7ff72e1 100644 --- a/controllers/cms.py +++ b/controllers/cms.py @@ -24,7 +24,8 @@ from easydict import EasyDict as edict py_ctx = { 'requests':requests,'print':print,'base64Encode':base64Encode,'baseDecode':baseDecode, 'log':logger.info,'fetch':fetch,'post':post,'request':request,'getCryptoJS':getCryptoJS, -'buildUrl':buildUrl,'getHome':getHome,'setDetail':setDetail,'join':join,'urljoin2':urljoin2 +'buildUrl':buildUrl,'getHome':getHome,'setDetail':setDetail,'join':join,'urljoin2':urljoin2, +'PC_UA':PC_UA,'MOBILE_UA':MOBILE_UA,'UC_UA':UC_UA } # print(getCryptoJS()) @@ -514,59 +515,89 @@ class CMS: url = self.url.replace('fyclass',fyclass).replace('fypage',pg) if fypage == 1 and self.test('[\[\]]',url): url = url.split('[')[1].split(']')[0] - p = self.一级.split(';') # 解析 - if len(p) < 5: - return self.blank() - + p = self.一级 jsp = jsoup(self.url) - is_json = str(p[0]).startswith('json:') - pdfh = jsp.pjfh if is_json else jsp.pdfh - pdfa = jsp.pjfa if is_json else jsp.pdfa - pd = jsp.pj if is_json else jsp.pd - # print(pdfh(r.text,'body a.module-poster-item.module-item:eq(1)&&Text')) - # print(pdfh(r.text,'body a.module-poster-item.module-item:eq(0)')) - # print(pdfh(r.text,'body a.module-poster-item.module-item:first')) - videos = [] - items = [] - try: - r = requests.get(url, headers=self.headers, timeout=self.timeout) - r.encoding = self.encoding - print(r.url) - # html = r.text - html = r.json() if is_json else r.text - # print(html) - items = pdfa(html,p[0].replace('json:','',1)) - except: - pass - # print(items) - for item in items: - # print(item) + is_js = isinstance(p, str) and str(p).startswith('js:') # 是js + if is_js: + headers['Referer'] = getHome(url) + py_ctx.update({ + 'input': url, + 'fetch_params': {'headers': headers, 'timeout': self.d.timeout, 'encoding': self.d.encoding}, + 'd': self.d, + 'cateID':fyclass, # 分类id + 'detailUrl':self.detailUrl or '', # 详情页链接 + 'getParse': self.d.getParse, + 'saveParse': self.d.saveParse, + 'jsp': jsp, 'setDetail': setDetail, + }) + ctx = py_ctx + # print(ctx) + jscode = getPreJs() + p.replace('js:', '', 1) + # print(jscode) + loader, _ = runJScode(jscode, ctx=ctx) + # print(loader.toString()) + vods = loader.eval('VODS') + # print(vods) + if isinstance(vods, JsObjectWrapper): + videos = vods.to_list() + + else: + p = p.split(';') # 解析 + if len(p) < 5: + return self.blank() + + is_json = str(p[0]).startswith('json:') + pdfh = jsp.pjfh if is_json else jsp.pdfh + pdfa = jsp.pjfa if is_json else jsp.pdfa + pd = jsp.pj if is_json else jsp.pd + # print(pdfh(r.text,'body a.module-poster-item.module-item:eq(1)&&Text')) + # print(pdfh(r.text,'body a.module-poster-item.module-item:eq(0)')) + # print(pdfh(r.text,'body a.module-poster-item.module-item:first')) + + items = [] try: - title = pdfh(item, p[1]) - img = pd(item, p[2]) - desc = pdfh(item, p[3]) - links = [pd(item, p4) if not self.detailUrl else pdfh(item, p4) for p4 in p[4].split('+')] - link = '$'.join(links) - content = '' if len(p) < 6 else pdfh(item, p[5]) - # sid = self.regStr(sid, "/video/(\\S+).html") - videos.append({ - "vod_id": f'{fyclass}${link}' if self.detailUrl else link,# 分类,播放链接 - "vod_name": title, - "vod_pic": img, - "vod_remarks": desc, - "vod_content": content, - }) - except Exception as e: - print(f'发生了错误:{e}') + r = requests.get(url, headers=self.headers, timeout=self.timeout) + r.encoding = self.encoding + print(r.url) + # html = r.text + html = r.json() if is_json else r.text + # print(html) + items = pdfa(html,p[0].replace('json:','',1)) + except: pass + # print(items) + for item in items: + # print(item) + try: + title = pdfh(item, p[1]) + img = pd(item, p[2]) + desc = pdfh(item, p[3]) + links = [pd(item, p4) if not self.detailUrl else pdfh(item, p4) for p4 in p[4].split('+')] + link = '$'.join(links) + content = '' if len(p) < 6 else pdfh(item, p[5]) + # sid = self.regStr(sid, "/video/(\\S+).html") + videos.append({ + "vod_id": f'{fyclass}${link}' if self.detailUrl else link,# 分类,播放链接 + "vod_name": title, + "vod_pic": img, + "vod_remarks": desc, + "vod_content": content, + }) + except Exception as e: + print(f'发生了错误:{e}') + pass + # print(videos) + limit = 40 + cnt = 9999 if len(videos) > 0 else 0 result['list'] = videos result['page'] = fypage - result['pagecount'] = 9999 - result['limit'] = 9999 - result['total'] = 999999 + result['pagecount'] = max(cnt,fypage) + result['limit'] = limit + result['total'] = cnt + # print(result) logger.info(f'{self.getName()}获取分类{fyclass}第{fypage}页耗时:{get_interval(t1)}毫秒,共计{round(len(str(result)) / 1000, 2)} kb') - + return result def detailOneVod(self,id,fyclass=''): @@ -576,7 +607,7 @@ class CMS: url = self.detailUrl.replace('fyid', detailUrl).replace('fyclass',fyclass) else: url = detailUrl - # print(url) + print(url) try: p = self.二级 # 解析 if p == '*': diff --git "a/js/\345\245\207\347\217\215\345\274\202\345\205\275.js" "b/js/\345\245\207\347\217\215\345\274\202\345\205\275.js" new file mode 100644 index 0000000..ecededc --- /dev/null +++ "b/js/\345\245\207\347\217\215\345\274\202\345\205\275.js" @@ -0,0 +1,30 @@ +var rule = { + title:'奇珍异兽', + host:'https://www.iqiyi.com', + homeUrl:'', + // detailUrl:'https://pcw-api.iqiyi.com/albums/album/avlistinfo?aid=fyid&size=2000&page=1', + detailUrl:'https://pcw-api.iqiyi.com/video/video/videoinfowithuser/fyid?agent_type=1&authcookie=&subkey=fyid&subscribe=1', + searchUrl:'https://search.video.iqiyi.com/o?if=html5&key=**&pageNum=fypage&pos=1&pageSize=24&site=iqiyi', + searchable:1, + quickSearch:1, + url:'https://pcw-api.iqiyi.com/search/recommend/list?channel_id=fyclass&data_type=1&is_purchase=&mode=24&page_id=fypage&ret_num=48&three_category_id=', + // url:'https://pcw-api.iqiyi.com/search/video/videolists?channel_id=fyclass&pageNum=fypage&pageSize=24&data_type=1&site=iqiyi', + headers:{ + 'User-Agent':'MOBILE_UA' + }, + timeout:5000, + class_name:'电影&电视剧&纪录片&动漫&综艺&音乐&网络电影', + class_url:'1&2&3&4&6&5&16', + limit:20, + // play_parse:true, + // 手动调用解析请求json的url,此lazy不方便 + lazy:'js:input="https://cache.json.icu/home/api?type=ys&uid=292796&key=fnoryABDEFJNPQV269&url="+input.split("?")[0];log(input);let html=JSON.parse(request(input));log(html);input=html.url||input', + // 推荐:'.list_item;img&&alt;img&&src;a&&Text;a&&data-float', + // 一级:'json:.data.list;.name;.imageUrl;.latestOrder;.albumId', + 一级:'js:let d=[];if(cateID==="16"){input=input.replace("channel_id=16","channel_id=1").split("three_category_id")[0];input+="three_category_id=27401"}else if(cateID==="5"){input=input.replace("data_type=1","data_type=2")}let html=fetch(input,fetch_params);let json=JSON.parse(html);if(json.code==="A00003"){fetch_params.headers["user-agent"]=PC_UA;json=JSON.parse(fetch(input,fetch_params))}json.data.list.forEach(function(data){if(data.channelId===1){desc=data.hasOwnProperty("score")?data.score+"分\\t":""}else if(data.channelId===2||data.channelId===4){if(data.latestOrder===data.videoCount){desc=(data.hasOwnProperty("score")?data.score+"分\\t":"")+data.latestOrder+"集全"}else{if(data.videoCount){desc=(data.hasOwnProperty("score")?data.score+"分\\t":"")+data.latestOrder+"/"+data.videoCount+"集"}else{desc="更新至 "+data.latestOrder+"集"}}}else if(data.channelId===6){desc=data.period+"期"}else if(data.channelId===5){desc=data.focus}else{if(data.latestOrder){desc="更新至 第"+data.latestOrder+"期"}else if(data.period){desc=data.period}else{desc=data.focus}}url=cateID+"$"+data.albumId;d.push({url:url,title:data.name,desc:desc,pic_url:data.imageUrl.replace(".jpg","_390_520.jpg?caplist=jpg,webp")})});setResult(d);', + // 一级:'json:.data.list;.name;.imageUrl;.playUrl;.latestOrder', + // 二级:{is_json:1,"title":"data.title;data.moviecategory[0]+data.moviecategory[1]","img":"data.cdncover","desc":"data.area[0];data.director[0]","content":"data.description","tabs":"data.playlink_sites;data.playlinksdetail.#idv.quality","lists":"data.playlinksdetail.#idv.default_url"}, + 二级:{is_json:1,"title":"data.name+data.subtitle;data.latestOrder","img":"data.imageUrl","desc":"data.categories;data.areas","content":"data.description","tabs":"data.name","lists":"data.playlinksdetail.#idv.default_url"}, + // 二级:'', + 搜索:'json:.data.docinfos;.albumDocInfo.albumTitle;.albumDocInfo.albumVImage;.albumDocInfo.channel;.albumDocInfo.albumId;.albumDocInfo.tvFocus', +} \ No newline at end of file diff --git a/libs/pre.js b/libs/pre.js index 92df381..1e8b198 100644 --- a/libs/pre.js +++ b/libs/pre.js @@ -1,3 +1,47 @@ +var VODS = []; + 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) {//this是空或者未定义,抛出错误 + throw new TypeError('"this" is null or not defined'); + } + + var o = Object(this);//将this转变成对象 + var len = o.length >>> 0;//无符号右移0位,获取对象length属性,如果未定义就会变成0 + + if (len === 0) {//length为0直接返回false未找到目标值 + 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) {//如果某一位置与寻找目标相等,返回true,找到了 + return true; + } + k++; + } + return false;//未找到,返回false + } + }); + } Object.assign = function () { var target = arguments[0]; for (var i = 1; i < arguments.length; i++) { @@ -37,49 +81,84 @@ Array.prototype.join = function (emoji) { } return str; }; +function setResult(d){ + if(!Array.isArray(d)){ + return [] + } + 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 +} // 千万不要用for in 推荐 forEach (for in 会打乱顺序) //猫函数 - function maoss(jxurl, ref, key) { - 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); - // log("iv:"+iv); - // log(html); - eval(html.match(/var config = {[\s\S]*?}/)[0] + ''); - if (config.url.slice(0, 4) != 'http') { - //config.url = decodeURIComponent(AES(config.url, key, iv)); - 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 maoss(jxurl, ref, key) { + 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 + } + }) } - } \ No newline at end of file + 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); + // log("iv:"+iv); + // log(html); + eval(html.match(/var config = {[\s\S]*?}/)[0] + ''); + if (config.url.slice(0, 4) != 'http') { + //config.url = decodeURIComponent(AES(config.url, key, iv)); + config.url = CryptoJS.AES.decrypt(config.url, key, { + iv: iv, + padding: CryptoJS.pad.Pkcs7 + }).toString(CryptoJS.enc.Utf8) + } + return config.url; + } catch (e) { + return ''; + } +} \ No newline at end of file diff --git "a/py/\347\210\261\345\245\207\350\211\272\344\270\200\347\272\247.js" "b/py/\347\210\261\345\245\207\350\211\272\344\270\200\347\272\247.js" new file mode 100644 index 0000000..159c94f --- /dev/null +++ "b/py/\347\210\261\345\245\207\350\211\272\344\270\200\347\272\247.js" @@ -0,0 +1,60 @@ +js: +let d = []; // 一级固定返回VODS变量,内置变量有 cateID,detailUrl,setResult用法跟海阔相同 +if(cateID==='16'){//网络电影 + input = input.replace("channel_id=16", "channel_id=1").split("three_category_id")[0]; + input+= "three_category_id=27401"; + // input+= "three_category_id=27401;must,地区;must,类型;must,规格;must"; +}else if(cateID==='5'){//音乐 + input = input.replace("data_type=1", "data_type=2"); +} +let html = fetch(input,fetch_params); +let json = JSON.parse(html); +if (json.code === "A00003") { + fetch_params.headers['user-agent'] = PC_UA; + // print(fetch_params); + json = JSON.parse(fetch(input,fetch_params)); +} +// print(json); +json.data.list.forEach(function (data){ + if (data.channelId === 1) { + desc = (data.hasOwnProperty("score") ? data.score + "分\t" : ''); + } else if (data.channelId === 2 || data.channelId === 4) { + if (data.latestOrder === data.videoCount) { + desc = (data.hasOwnProperty("score") ? data.score + "分\t" : '') + data.latestOrder + "集全"; + } else { + if (data.videoCount) { + desc = (data.hasOwnProperty("score") ? data.score + "分\t" : '') + data.latestOrder + "/" + data.videoCount + "集"; + } else { + desc = "更新至 " + data.latestOrder + "集" + } + } + } else if (data.channelId === 6) { + desc = data.period + "期"; + } else if (data.channelId === 5) { + desc = data.focus; + } else { + if (data.latestOrder) { + desc = "更新至 第" + data.latestOrder + "期"; + } else if (data.period) { + desc = data.period; + } else { + desc = data.focus; + } + } + // url = "https://pcw-api.iqiyi.com/video/video/videoinfowithuser/" + data.albumId + "?agent_type=1&authcookie=&subkey=" + data.albumId + "&subscribe=1"; + url = cateID +'$'+data.albumId; + // d.push({ + // vod_id:url, + // vod_name: data.name, + // vod_remarks: desc, + // vod_pic: data.imageUrl.replace('.jpg', '_390_520.jpg?caplist=jpg,webp'), + // }); + d.push({ + url:url, + title: data.name, + desc: desc, + pic_url: data.imageUrl.replace('.jpg', '_390_520.jpg?caplist=jpg,webp'), + }); +}); +// VODS = d; +setResult(d); \ No newline at end of file -- GitLab