drpy2.js 97 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808
  1. import cheerio from 'assets://js/lib/cheerio.min.js';
  2. import 'assets://js/lib/crypto-js.js';
  3. import './jsencrypt.js';
  4. import 模板 from "../js/模板.js"
  5. import {gbkTool} from './gbk.js'
  6. // import cheerio from "https://ghproxy.net/https://raw.githubusercontent.com/hjdhnx/dr_py/main/libs/cheerio.min.js";
  7. // import "https://ghproxy.net/https://raw.githubusercontent.com/hjdhnx/dr_py/main/libs/crypto-js.js";
  8. // import 模板 from"https://ghproxy.net/https://raw.githubusercontent.com/hjdhnx/dr_py/main/js/模板.js";
  9. // import {gbkTool} from 'https://ghproxy.net/https://raw.githubusercontent.com/hjdhnx/dr_py/main/libs/gbk.js'
  10. function init_test(){
  11. // console.log(typeof(CryptoJS));
  12. console.log("init_test_start");
  13. // print(模板);
  14. // print(typeof(模板.getMubans));
  15. console.log("当前版本号:"+VERSION);
  16. console.log(RKEY);
  17. console.log(JSON.stringify(rule));
  18. console.log("init_test_end");
  19. // log('typeof (JSEncrypt):'+typeof (JSEncrypt));
  20. // let publicKey = 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwEc7wBMtYKkxvrQNI3+ITBZwAkPkGvsv4TsAHFskKGZWz9eYl3scivhmlEfWHlEkdyb0m82CmB1qAgef+pD4cZu+Cdmm2e9lnExhLwm8cBgpkAen9QRNdjojZgxM0W+JcReH4W6pw+uFXiLRn4AIQkDftWGNLg6wlNS+39Z/RvP9zyATJLZ9AKDdHp62XMxEK1KZvWBuIg+Oa5UzgA9jy+2XyIqwhBtO8tPbUl21t2pvTzHoLUjSkPNm2LurcUk6+jQ2r6aiS2CN1NXIucPJU6mkuIQ821SjvkYPtIdRMntW4y2u4cyiqVEEQwlzWVMHh+/vfrWAQr9fgjDuYYtvPQIDAQAB';
  21. // let privateKey = 'MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDARzvAEy1gqTG+tA0jf4hMFnACQ+Qa+y/hOwAcWyQoZlbP15iXexyK+GaUR9YeUSR3JvSbzYKYHWoCB5/6kPhxm74J2abZ72WcTGEvCbxwGCmQB6f1BE12OiNmDEzRb4lxF4fhbqnD64VeItGfgAhCQN+1YY0uDrCU1L7f1n9G8/3PIBMktn0AoN0enrZczEQrUpm9YG4iD45rlTOAD2PL7ZfIirCEG07y09tSXbW3am9PMegtSNKQ82bYu6txSTr6NDavpqJLYI3U1ci5w8lTqaS4hDzbVKO+Rg+0h1Eye1bjLa7hzKKpUQRDCXNZUweH7+9+tYBCv1+CMO5hi289AgMBAAECggEBAIRbRJUWXmEwdq64kGbELlV6CIZ2p3mvOSlIjO34Cy7IK7AMz9xOgbpj/XDK9miOIJTouu7ZC7GcZdGZ4BUCYBMMS0fKjGFuurpZlXhkslNTPqEHtCUkXhIpOR7RDrwIlErGEOIsZC4aXQcM3tF1t7mroJLh4OY4dHMu82lv5NM4hhFMNvHzXVvrPXeTzw26gddHVG/ke0WUYOcB5j3cPp8xaVp7JV8bdxtGtkqIfBLY/dIczzJu/3F3cBpU2nNwt8uVUF/w/HKlr7j8FqqFHXWh182beU0n5AIdRyRJBrRUAEhdtsUnvJOVBDqzZa+9DJ5395F7V8KRlQptxETdhCECgYEA4x/2HM9fnVIhG6wTbEt1LhGTKYb/igMAHLqquEMfRsB44tobI8gVNwR3qJQY/nKXxcQemQV29PcdqpENCKyXUXGD8SI1UPg15rHFBI8CIqlCXfzJybdHjmzlhaA9I5lofIVh+5MW7WkvHZoRy7NeDMhHUuaiveuqC4OJ8n+dD2kCgYEA2LkmUVef3WkBBwUBRdkyoog3DMwR+/ubb0ncJVYy3ItYVJltQ4HqmrRiJc8xBAoFnG8rbiqDnmTnDR3WbuxU1G2hml09fqId+rQds2UfESswCXHU43A4f77m1XyA6PprBxpozVIcmK69N4rR9jOXflLWo3O+p2ipUbmNpId7+rUCgYBSpcbBJRT+AmzZzPwkZDD32p1ady114zGfQq3s7z/qVw+mPQezNZPCuXVxerK9pKVl6b/Ynwxyh5nb/3xms6c8k7oXfQM5u5ihof63cfKs+jqUSPCE3pTDVw0OWwjkc2Z6KW9GRHgLXEMw2mevYE3RCPArUpHV2nO+TNddzuIwQQKBgQDOZwdnUNygMfEYjlu3+jOPN8u2FGTMZ8SRKPbRWFb4VH27lKPLN2AIFuOivsEf56uQYRAry7GumMq0Y0ZmPg5Mglz2dvaqNBv5OLFQuW3tHAST+iWWtroYb+fISts7B8QG79AAO8OgZksvKrbslBYj6SEiaomZRsR7YQzVNXOOQQKBgQCovElZ50c8ZJ6m9D9fw3Nes7u9vshpyyac5tt4tZ7yfU4l5pWGrIUqCE703qZp4NAqEvlZUCJbj9kkysaj/2MfFb2b9jSvdNB+V/YW9Cwg+5TziYoOcQzN1z2u4p4goTAv0S+pTNSr3qWaTUI4TXUXQajif45Fexv+MrP5AAXQyw=='
  22. // // let text = '你好';
  23. // let text = '[{"vod_name":"兔小贝原创儿歌","vod_pic":"https://resource-cdn.tuxiaobei.com/video-album/FnQ8ieJHgsbgCKWXNBg4uoOmKgG5.jpg","vod_remarks":"共229首","vod_content":"","vod_id":"/subject/17@@兔小贝原创儿歌@@https://resource-cdn.tuxiaobei.com/video-album/FnQ8ieJHgsbgCKWXNBg4uoOmKgG5.jpg"},{"vod_name":"英文儿歌","vod_pic":"https://resource-cdn.tuxiaobei.com/video-album/Fqjpx2H_-QaYNAYn2MekRuDpeyUv.jpg","vod_remarks":"共10首","vod_content":"","vod_id":"/subject/23@@英文儿歌@@https://resource-cdn.tuxiaobei.com/video-album/Fqjpx2H_-QaYNAYn2MekRuDpeyUv.jpg"}]';
  24. // let str = RSA.encode(text, publicKey);
  25. // console.log("加密数据:" + str);
  26. // let str1 = 'Wa2c/868VOm0PgpGG2s2aMrDbGOlJRdZXlSGswjFgywd3nZNB7ND8kVMdNB/OsNFoQXJXSJMvPaE73BH7rs8fz54JGdYQK+qTgfQRqQZvomCjbzseSR4bm4NOrtIOOslL3WqxlzOuU0M1P1eERmkLEVU2WSyc3RGtJro3b3MOWYCNdKMoZdncfOHJndkl4wm9V3GGc3uH98hs6OxLvBWgXoW9jZQ3n0vR2FtS2KYrPGuSuKGkxlt9Kw5TD6nri142NOimz05WK55Xe04YUQ1VZd51t0wzJGXolWgfzIQaK2zzhk5Zjlm+IQJxXqEWiJ2+O6TJ+lIttvsDSaUflcDXQ==';
  27. // let str2 = 'R86mW9DzBw05pxBSh9ECh1stXxINmnudgZBbzU/cz1EcFgrEgdk0Zk4ruAiJZB2fP5c7d3gMmN8+Dv19IfARWSzw85xCEjUhpdcMJ0jn6ZE5H+muadND9LzjeVisojqwYxot3YVdKof7HMhPFN8QR0jfzqhjmnGFTlY1jMXzJK0MSOLNRLDar480CdKNb/cxALC8+xKIlhM9E4B31t8J4rNMUWSCAr49lbZ3jx3PxieBpTQUdDJz96AttR93Pc+c51wrxh0Ch/Mt4Rs09HGMXwIpNV+CxsGwSGRQUlyJo2k3d0WqsVzpz6S8A4VGEMTRLGI3IjEt+eWt7wM3nAXarg==';
  28. // let str3 = 'D4eOsRqua+jYA5+ZOR9PLI2PExKjKfArQfv9/wGeG50bQSjWypShJPY6RQfO+rghyf0juzHIUSxqH91OxinhCFkONaF2Vod2QVyphyn9eh73dAcEFKIFFKGXoPCjbMWrr3p4d+hgVrHzrFeGqkRq8JFOvG2L5XDxVfWbV8KmUA0DKuz6QwWg7P4kesy+C7BbLALy5W/wfZchD3gnsBvx/pjFoe11VfAify9isLxg9a15jj52xr6lzQ9kge9C2JcV8yq85bFKaUpJWgobzz+BSIv3lVMU6vgcldmOrhkyiETpFGFGGF00DphGCEoK6uAyyNDh7+Jn8P17zf/DW1wV3A==';
  29. // let uncrypted = RSA.decode(str, privateKey);
  30. // log('解密数据:'+uncrypted);
  31. // uncrypted = RSA.decode(str1, privateKey);
  32. // log('解密数据1:'+uncrypted);
  33. // uncrypted = RSA.decode(str2, privateKey);
  34. // log('解密数据2:'+uncrypted);
  35. // uncrypted = RSA.decode(str3, privateKey);
  36. // log('解密数据3:'+uncrypted);
  37. // log('rsax:'+typeof(rsax));
  38. // log('rsaX:'+typeof(rsaX));
  39. // let data = base64Encode('你好');
  40. // let publicKey = 'dzyyds';
  41. // console.log(typeof (RSA.encode));
  42. // let encryptBase64Data = RSA.encode(data,publicKey);
  43. // log('encryptBase64Data:'+encryptBase64Data);
  44. // let str = RSA.decode(data,publicKey);
  45. // log('str:'+str);
  46. }
  47. /**
  48. * 执行预处理代码
  49. */
  50. function pre(){
  51. if(typeof(rule.预处理) === 'string' && rule.预处理 && rule.预处理.trim()){
  52. let code = rule.预处理.trim();
  53. console.log("执行预处理代码:"+code);
  54. if(code.startsWith('js:')){
  55. code = code.replace('js:','');
  56. }
  57. try {
  58. // code里可以进行get 或者 post请求cookie并改变rule.headers 里的cookie
  59. // 直接操作 rule_fetch_params 这个变量 .headers.Cookie
  60. eval(code);
  61. }catch (e) {
  62. console.log('预处理执行失败:'+e.message);
  63. }
  64. }
  65. }
  66. let rule = {};
  67. let vercode = typeof(pdfl) ==='function'?'drpy2.1':'drpy2';
  68. const VERSION = vercode+' 3.9.49beta40 202400426';
  69. /** 已知问题记录
  70. * 1.影魔的jinjia2引擎不支持 {{fl}}对象直接渲染 (有能力解决的话尽量解决下,支持对象直接渲染字符串转义,如果加了|safe就不转义)[影魔牛逼,最新的文件发现这问题已经解决了]
  71. * Array.prototype.append = Array.prototype.push; 这种js执行后有毛病,for in 循环列表会把属性给打印出来 (这个大毛病需要重点排除一下)
  72. * 2.import es6py.js但是里面的函数没有被装载进来.比如drpy规则报错setResult2 is undefiend(合并文件了可以不管了)
  73. * 3.无法重复导入cheerio(怎么解决drpy和parseTag里都需要导入cheerio的问题) 无法在副文件导入cheerio (现在是全部放在drpy一个文件里了,凑合解决?)
  74. * 4.有个错误不知道哪儿来的 executeScript: com.quickjs.JSObject$Undefined cannot be cast to java.lang.String 在 点击选集播放打印init_test_end后面打印(貌似不影响使用)
  75. * 5.需要实现 stringify 函数,比起JSON.strifngify函数,它会原封不动保留中文不会编码unicode
  76. * 6.base64Encode,base64Decode,md5函数还没有实现 (抄影魔代码实现了)
  77. * 7.eval(getCryptoJS());还没有实现 (可以空实现了,以后遇到能忽略)
  78. * done: jsp:{pdfa,pdfh,pd},json:{pdfa,pdfh,pd},jq:{pdfa,pdfh,pd}
  79. * 8.req函数不支持传递字符串的data参数 {'content-type':'text/plain'} 类型数据,因此无法直接调用alist的ocr接口
  80. * * 电脑看日志调试
  81. adb tcpip 5555
  82. adb connect 192.168.10.192
  83. adb devices -l
  84. adb logcat -c
  85. adb logcat | grep -i QuickJS
  86. adb logcat -c -b events
  87. adb logcat -c -b main -b events -b radio -b system
  88. adb logcat > 2.log DRPY:E | grep -i QuickJS
  89. * **/
  90. /*** 以下是内置变量和解析方法 **/
  91. 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';
  92. 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';
  93. const UA = 'Mozilla/5.0';
  94. 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';
  95. 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';
  96. const RULE_CK = 'cookie'; // 源cookie的key值
  97. // const KEY = typeof(key)!=='undefined'&&key?key:'drpy_' + (rule.title || rule.host); // 源的唯一标识
  98. const CATE_EXCLUDE = '首页|留言|APP|下载|资讯|新闻|动态';
  99. const TAB_EXCLUDE = '猜你|喜欢|下载|剧情|热播';
  100. const OCR_RETRY = 3;//ocr验证重试次数
  101. // const OCR_API = 'http://dm.mudery.com:10000';//ocr在线识别接口
  102. // const OCR_API = 'http://192.168.3.239:5705/parse/ocr';//ocr在线识别接口
  103. // const OCR_API = 'http://cms.nokia.press/parse/ocr';//ocr在线识别接口
  104. // const OCR_API = 'http://cms.nokia.press:5707/parse/ocr';//ocr在线识别接口
  105. const OCR_API = 'http://drpy.nokia.press:8028/ocr/drpy/text';//ocr在线识别接口
  106. if(typeof(MY_URL)==='undefined'){
  107. var MY_URL; // 全局注入变量,pd函数需要
  108. }
  109. var HOST;
  110. var RKEY; // 源的唯一标识
  111. var fetch;
  112. var print;
  113. var log;
  114. var rule_fetch_params;
  115. var fetch_params; // 每个位置单独的
  116. var oheaders;
  117. // var play_url; // 二级详情页注入变量,为了适配js模式0 (不在这里定义了,直接二级里定义了个空字符串)
  118. var _pdfh;
  119. var _pdfa;
  120. var _pd;
  121. // const DOM_CHECK_ATTR = ['url', 'src', 'href', 'data-original', 'data-src'];
  122. const DOM_CHECK_ATTR = /(url|src|href|-original|-src|-play|-url|style)$/;
  123. // 过滤特殊链接,不走urlJoin
  124. const SPECIAL_URL = /^(ftp|magnet|thunder|ws):/;
  125. const NOADD_INDEX = /:eq|:lt|:gt|:first|:last|^body$|^#/; // 不自动加eq下标索引
  126. const URLJOIN_ATTR = /(url|src|href|-original|-src|-play|-url|style)$/; // 需要自动urljoin的属性
  127. const SELECT_REGEX = /:eq|:lt|:gt|#/g;
  128. const SELECT_REGEX_A = /:eq|:lt|:gt/g;
  129. /**
  130. es6py扩展
  131. */
  132. if (typeof Object.assign != 'function') {
  133. Object.assign = function () {
  134. let target = arguments[0];
  135. for (let i = 1; i < arguments.length; i++) {
  136. let source = arguments[i];
  137. for (let key in source) {
  138. if (Object.prototype.hasOwnProperty.call(source, key)) {
  139. target[key] = source[key];
  140. }
  141. }
  142. }
  143. return target;
  144. };
  145. }
  146. if (!String.prototype.includes) {
  147. String.prototype.includes = function (search, start) {
  148. if (typeof start !== 'number') {
  149. start = 0;
  150. }
  151. if (start + search.length > this.length) {
  152. return false;
  153. } else {
  154. return this.indexOf(search, start) !== -1;
  155. }
  156. };
  157. }
  158. if (!Array.prototype.includes) {
  159. Object.defineProperty(Array.prototype, 'includes', {
  160. value: function (searchElement, fromIndex) {
  161. if (this == null) {//this是空或者未定义,抛出错误
  162. throw new TypeError('"this" is null or not defined');
  163. }
  164. var o = Object(this);//将this转变成对象
  165. var len = o.length >>> 0;//无符号右移0位,获取对象length属性,如果未定义就会变成0
  166. if (len === 0) {//length为0直接返回false未找到目标值
  167. return false;
  168. }
  169. var n = fromIndex | 0;//查找起始索引
  170. var k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);//计算正确起始索引,因为有可能是负值
  171. while (k < len) {//从起始索引处开始循环
  172. if (o[k] === searchElement) {//如果某一位置与寻找目标相等,返回true,找到了
  173. return true;
  174. }
  175. k++;
  176. }
  177. return false;//未找到,返回false
  178. }
  179. });
  180. }
  181. if (typeof String.prototype.startsWith != 'function') {
  182. String.prototype.startsWith = function (prefix){
  183. return this.slice(0, prefix.length) === prefix;
  184. };
  185. }
  186. if (typeof String.prototype.endsWith != 'function') {
  187. String.prototype.endsWith = function(suffix) {
  188. return this.indexOf(suffix, this.length - suffix.length) !== -1;
  189. };
  190. }
  191. Object.prototype.myValues=function(obj){
  192. if(obj ==null) {
  193. throw new TypeError("Cannot convert undefined or null to object");
  194. }
  195. var res=[]
  196. for(var k in obj){
  197. if(obj.hasOwnProperty(k)){//需判断是否是本身的属性
  198. res.push(obj[k]);
  199. }
  200. }
  201. return res;
  202. }
  203. if (typeof Object.prototype.values != 'function') {
  204. Object.prototype.values=function(obj){
  205. if(obj ==null) {
  206. throw new TypeError("Cannot convert undefined or null to object");
  207. }
  208. var res=[]
  209. for(var k in obj){
  210. if(obj.hasOwnProperty(k)){//需判断是否是本身的属性
  211. res.push(obj[k]);
  212. }
  213. }
  214. return res;
  215. }
  216. }
  217. if (typeof Array.prototype.join != 'function') {
  218. Array.prototype.join = function (emoji) {
  219. // emoji = emoji||',';
  220. emoji = emoji||'';
  221. let self = this;
  222. let str = "";
  223. let i = 0;
  224. if (!Array.isArray(self)) {throw String(self)+'is not Array'}
  225. if(self.length===0){return ''}
  226. if (self.length === 1){return String(self[0])}
  227. i = 1;
  228. str = this[0];
  229. for (; i < self.length; i++) {
  230. str += String(emoji)+String(self[i]);
  231. }
  232. return str;
  233. };
  234. }
  235. if (typeof Array.prototype.toReversed != 'function') {
  236. Array.prototype.toReversed = function () {
  237. const clonedList = this.slice();
  238. // 倒序新数组
  239. const reversedList = clonedList.reverse();
  240. return reversedList;
  241. };
  242. }
  243. String.prototype.rstrip = function (chars) {
  244. let regex = new RegExp(chars + "$");
  245. return this.replace(regex, "");
  246. };
  247. Array.prototype.append = Array.prototype.push;
  248. String.prototype.strip = String.prototype.trim;
  249. function 是否正版(vipUrl){
  250. 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');
  251. return flag.test(vipUrl);
  252. }
  253. function urlDeal(vipUrl){
  254. if(!vipUrl){
  255. return ''
  256. }
  257. if(!是否正版(vipUrl)){
  258. return vipUrl
  259. }
  260. if(!/miguvideo/.test(vipUrl)){
  261. vipUrl=vipUrl.split('#')[0].split('?')[0];
  262. }
  263. return vipUrl
  264. }
  265. function setResult(d){
  266. if(!Array.isArray(d)){
  267. return []
  268. }
  269. VODS = [];
  270. // print(d);
  271. d.forEach(function (it){
  272. let obj = {
  273. vod_id:it.url||'',
  274. vod_name: it.title||'',
  275. vod_remarks: it.desc||'',
  276. vod_content: it.content||'',
  277. vod_pic: it.pic_url||it.img||'',
  278. };
  279. let keys = Object.keys(it);
  280. if(keys.includes('tname')){
  281. obj.type_name = it.tname||'';
  282. }
  283. if(keys.includes('tid')){
  284. obj.type_id = it.tid||'';
  285. }
  286. if(keys.includes('year')){
  287. obj.vod_year = it.year||'';
  288. }
  289. if(keys.includes('actor')){
  290. obj.vod_actor = it.actor||'';
  291. }
  292. if(keys.includes('director')){
  293. obj.vod_director = it.director||'';
  294. }
  295. if(keys.includes('area')){
  296. obj.vod_area = it.area||'';
  297. }
  298. VODS.push(obj);
  299. });
  300. return VODS
  301. }
  302. function setResult2(res){
  303. VODS = res.list||[];
  304. return VODS
  305. }
  306. function setHomeResult(res){
  307. if(!res||typeof(res)!=='object'){
  308. return []
  309. }
  310. return setResult(res.list);
  311. }
  312. // 猫了个咪
  313. function rc(js) {
  314. if (js === 'maomi_aes.js') {
  315. var a = CryptoJS.enc.Utf8.parse("625222f9149e961d");
  316. var t = CryptoJS.enc.Utf8.parse("5efdtf6060e2o330");
  317. return {
  318. De: function (word) {
  319. word = CryptoJS.enc.Hex.parse(word)
  320. return CryptoJS.AES.decrypt(CryptoJS.enc.Base64.stringify(word), a, {
  321. iv: t,
  322. mode: CryptoJS.mode.CBC,
  323. padding: CryptoJS.pad.Pkcs7
  324. }).toString(CryptoJS.enc.Utf8)
  325. },
  326. En: function (word) {
  327. // print(a);
  328. // print(word);
  329. var Encrypted = CryptoJS.AES.encrypt(word, a, {
  330. iv: t,
  331. mode: CryptoJS.mode.CBC,
  332. padding: CryptoJS.pad.Pkcs7
  333. });
  334. return Encrypted.ciphertext.toString();
  335. }
  336. };
  337. }
  338. return {};
  339. }
  340. // 千万不要用for in 推荐 forEach (for in 会打乱顺序)
  341. //猫函数
  342. function maoss(jxurl, ref, key) {
  343. fetch_params = JSON.parse(JSON.stringify(rule_fetch_params));
  344. eval(getCryptoJS());
  345. try {
  346. var getVideoInfo = function (text) {
  347. return CryptoJS.AES.decrypt(text, key, {iv: iv, padding: CryptoJS.pad.Pkcs7}).toString(CryptoJS.enc.Utf8);
  348. };
  349. var token_key = key == undefined ? 'dvyYRQlnPRCMdQSe' : key;
  350. if (ref) {
  351. var html = request(jxurl, {
  352. headers: {
  353. 'Referer': ref
  354. }
  355. });
  356. } else {
  357. var html = request(jxurl);
  358. }
  359. // print(html);
  360. if (html.indexOf('&btwaf=') != -1) {
  361. html = request(jxurl + '&btwaf' + html.match(/&btwaf(.*?)"/)[1], {
  362. headers: {
  363. 'Referer': ref
  364. }
  365. })
  366. }
  367. var token_iv = html.split('_token = "')[1].split('"')[0];
  368. var key = CryptoJS.enc.Utf8.parse(token_key);
  369. var iv = CryptoJS.enc.Utf8.parse(token_iv);
  370. // log("iv:"+iv);
  371. // log(html);
  372. // print(key);
  373. // print(iv);
  374. eval(html.match(/var config = {[\s\S]*?}/)[0] + '');
  375. // config.url = config.url.replace(/,/g,'');
  376. // print(config.url);
  377. if (!config.url.startsWith('http')) {
  378. //config.url = decodeURIComponent(AES(config.url, key, iv));
  379. config.url = CryptoJS.AES.decrypt(config.url, key, {
  380. iv: iv,
  381. padding: CryptoJS.pad.Pkcs7
  382. }).toString(CryptoJS.enc.Utf8)
  383. }
  384. return config.url;
  385. } catch (e) {
  386. return '';
  387. }
  388. }
  389. function urlencode (str) {
  390. str = (str + '').toString();
  391. return encodeURIComponent(str).replace(/!/g, '%21').replace(/'/g, '%27').replace(/\(/g, '%28').
  392. replace(/\)/g, '%29').replace(/\*/g, '%2A').replace(/%20/g, '+');
  393. }
  394. function base64Encode(text){
  395. return CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(text));
  396. // return text
  397. }
  398. function base64Decode(text){
  399. return CryptoJS.enc.Utf8.stringify(CryptoJS.enc.Base64.parse(text));
  400. // return text
  401. }
  402. function md5(text) {
  403. return CryptoJS.MD5(text).toString();
  404. }
  405. /**
  406. * 字符串按指定编码
  407. * @param input
  408. * @param encoding
  409. * @returns {*}
  410. */
  411. function encodeStr(input,encoding){
  412. encoding = encoding||'gbk';
  413. if(encoding.startsWith('gb')){
  414. const strTool = gbkTool();
  415. input = strTool.encode(input);
  416. }
  417. return input
  418. }
  419. /**
  420. * 字符串指定解码
  421. * @param input
  422. * @param encoding
  423. * @returns {*}
  424. */
  425. function decodeStr(input,encoding){
  426. encoding = encoding||'gbk';
  427. if(encoding.startsWith('gb')){
  428. const strTool = gbkTool();
  429. input = strTool.decode(input);
  430. }
  431. return input
  432. }
  433. function getCryptoJS(){
  434. // return request('https://ghproxy.net/https://raw.githubusercontent.com/hjdhnx/dr_py/main/libs/crypto-hiker.js');
  435. return 'console.log("CryptoJS已装载");'
  436. }
  437. // 封装的RSA加解密类
  438. const RSA = {
  439. decode: function (data, key, option) {
  440. option = option || {};
  441. if (typeof (JSEncrypt) === 'function') {
  442. let chunkSize = option.chunkSize || 117; // 默认分段长度为117
  443. let privateKey = this.getPrivateKey(key); // 获取私钥
  444. const decryptor = new JSEncrypt(); //创建解密对象实例
  445. decryptor.setPrivateKey(privateKey); //设置秘钥
  446. let uncrypted = '';
  447. // uncrypted = decryptor.decrypt(data);
  448. uncrypted = decryptor.decryptUnicodeLong(data);
  449. return uncrypted;
  450. } else {
  451. return false
  452. }
  453. },
  454. encode: function (data, key, option) {
  455. option = option || {};
  456. if (typeof (JSEncrypt) === 'function') {
  457. let chunkSize = option.chunkSize || 117; // 默认分段长度为117
  458. let publicKey = this.getPublicKey(key); // 获取公钥
  459. const encryptor = new JSEncrypt();
  460. encryptor.setPublicKey(publicKey); // 设置公钥
  461. let encrypted = ''; // 加密结果
  462. // const textLen = data.length; // 待加密文本长度
  463. // let offset = 0; // 分段偏移量
  464. // // 分段加密
  465. // while (offset < textLen) {
  466. // let chunk = data.slice(offset, chunkSize); // 提取分段数据
  467. // let enc = encryptor.encrypt(chunk); // 加密分段数据
  468. // encrypted += enc; // 连接加密结果
  469. // offset += chunkSize; // 更新偏移量
  470. // }
  471. encrypted = encryptor.encryptUnicodeLong(data);
  472. return encrypted
  473. } else {
  474. return false
  475. }
  476. },
  477. fixKey(key, prefix, endfix) {
  478. if (!key.includes(prefix)) {
  479. key = prefix + key;
  480. }
  481. if (!key.includes(endfix)) {
  482. key += endfix
  483. }
  484. return key
  485. },
  486. getPrivateKey(key) {
  487. let prefix = '-----BEGIN RSA PRIVATE KEY-----';
  488. let endfix = '-----END RSA PRIVATE KEY-----';
  489. return this.fixKey(key, prefix, endfix);
  490. },
  491. getPublicKey(key) {
  492. let prefix = '-----BEGIN PUBLIC KEY-----';
  493. let endfix = '-----END PUBLIC KEY-----';
  494. return this.fixKey(key, prefix, endfix);
  495. }
  496. };
  497. /**
  498. * 获取壳子返回的代理地址
  499. * @returns {string|*}
  500. */
  501. function getProxyUrl(){
  502. if(typeof(getProxy)==='function'){//判断壳子里有getProxy函数就执行取返回结果。否则取默认的本地
  503. return getProxy(true)
  504. }else{
  505. return 'http://127.0.0.1:9978/proxy?do=js'
  506. }
  507. }
  508. /**
  509. * 根据正则处理原始m3u8里的广告ts片段,自动修复相对链接
  510. * @param m3u8_text m3u8原始文本,里面是最末级的只含ts片段的。不支持嵌套m3u8链接
  511. * @param m3u8_url m3u8原始地址
  512. * @param ad_remove 正则表达式如: reg:/video/adjump(.*?)ts
  513. * @returns {string|DocumentFragment|*|string}
  514. */
  515. function fixAdM3u8(m3u8_text, m3u8_url, ad_remove) {
  516. if ((!m3u8_text && !m3u8_url) || (!m3u8_text && m3u8_url && !m3u8_url.startsWith('http'))) {
  517. return ''
  518. }
  519. if (!m3u8_text) {
  520. log('m3u8_url:' + m3u8_url);
  521. m3u8_text = request(m3u8_url);
  522. }
  523. log('len(m3u8_text):' + m3u8_text.length);
  524. if (!ad_remove) {
  525. return m3u8_text
  526. }
  527. if (ad_remove.startsWith('reg:')) {
  528. ad_remove = ad_remove.slice(4)
  529. } else if (ad_remove.startsWith('js:')) {
  530. ad_remove = ad_remove.slice(3)
  531. }
  532. let m3u8_start = m3u8_text.slice(0, m3u8_text.indexOf('#EXTINF')).trim();
  533. let m3u8_body = m3u8_text.slice(m3u8_text.indexOf('#EXTINF'), m3u8_text.indexOf('#EXT-X-ENDLIST')).trim();
  534. let m3u8_end = m3u8_text.slice(m3u8_text.indexOf('#EXT-X-ENDLIST')).trim();
  535. let murls = [];
  536. let m3_body_list = m3u8_body.split('\n');
  537. let m3_len = m3_body_list.length;
  538. let i = 0;
  539. while (i < m3_len) {
  540. let mi = m3_body_list[i];
  541. let mi_1 = m3_body_list[i + 1];
  542. if (mi.startsWith('#EXTINF')) {
  543. murls.push([mi, mi_1].join('&'));
  544. i += 2
  545. } else if (mi.startsWith('#EXT-X-DISCONTINUITY')) {
  546. let mi_2 = m3_body_list[i + 2];
  547. murls.push([mi, mi_1, mi_2].join('&'));
  548. i += 3
  549. } else {
  550. break;
  551. }
  552. }
  553. let new_m3u8_body = [];
  554. for (let murl of murls) {
  555. if (ad_remove && new RegExp(ad_remove).test(murl)) {
  556. } else {
  557. let murl_list = murl.split('&');
  558. if (!murl_list[murl_list.length - 1].startsWith('http') && m3u8_url.startsWith('http')) {
  559. murl_list[murl_list.length - 1] = urljoin(m3u8_url, murl_list[murl_list.length - 1]);
  560. }
  561. murl_list.forEach((it) => {
  562. new_m3u8_body.push(it);
  563. });
  564. }
  565. }
  566. new_m3u8_body = new_m3u8_body.join('\n').trim();
  567. m3u8_text = [m3u8_start, new_m3u8_body, m3u8_end].join('\n').trim();
  568. return m3u8_text
  569. }
  570. /**
  571. * 智能对比去除广告。支持嵌套m3u8。只需要传入播放地址
  572. * @param m3u8_url m3u8播放地址
  573. * @returns {string}
  574. */
  575. function fixAdM3u8Ai(m3u8_url) {
  576. let ts = new Date().getTime();
  577. function b(s1, s2) {
  578. let i = 0;
  579. while (i < s1.length) {
  580. if (s1[i] !== s2[i]) {
  581. break
  582. }
  583. i++
  584. }
  585. return i;
  586. }
  587. function reverseString(str) {
  588. return str.split('').reverse().join('');
  589. }
  590. //log('播放的地址:' + m3u8_url);
  591. let m3u8 = request(m3u8_url);
  592. //log('m3u8处理前:' + m3u8);
  593. m3u8 = m3u8.trim().split('\n').map(it => it.startsWith('#') ? it : urljoin(m3u8_url, it)).join('\n');
  594. //log('m3u8处理后:============:' + m3u8);
  595. // 获取嵌套m3u8地址
  596. let last_url = m3u8.split('\n').slice(-1)[0];
  597. if (last_url.includes('.m3u8') && last_url !== m3u8_url) {
  598. m3u8_url = last_url;
  599. //log('嵌套的m3u8_url:' + m3u8_url);
  600. m3u8 = request(m3u8_url);
  601. }
  602. //log('----处理有广告的地址----');
  603. let s = m3u8.trim().split('\n').filter(it => it.trim()).join('\n');
  604. let ss = s.split('\n')
  605. //找出第一条播放地址
  606. let firststr = ss.find(x => !x.startsWith('#'));
  607. let maxl = 0;//最大相同字符
  608. let firststrlen = firststr.length;
  609. //log('字符串长度:' + firststrlen);
  610. let ml = Math.round(ss.length / 2).toString().length;//取数据的长度的位数
  611. //log('数据条数的长度:' + ml);
  612. //找出最后一条播放地址
  613. let laststr = ss.toReversed().find((x) => {
  614. if (!x.startsWith('#')) {
  615. let k = b(reverseString(firststr), reverseString(x));
  616. maxl = b(firststr, x);
  617. if (firststrlen - maxl <= ml + k) {
  618. return true
  619. }
  620. }
  621. return false
  622. });
  623. log('最后一条切片:' + laststr);
  624. //log('最小相同字符长度:' + maxl);
  625. let ad_urls = [];
  626. for (let i = 0; i < ss.length; i++) {
  627. let s = ss[i];
  628. if (!s.startsWith('#')) {
  629. if (b(firststr, s) < maxl) {
  630. ad_urls.push(s); // 广告地址加入列表
  631. ss.splice(i - 1, 2);
  632. i = i - 2;
  633. } else {
  634. ss[i] = urljoin(m3u8_url, s);
  635. }
  636. } else {
  637. ss[i] = s.replace(/URI=\"(.*)\"/, 'URI=\"' + urljoin(m3u8_url, '$1') + '\"');
  638. }
  639. }
  640. log('处理的m3u8地址:' + m3u8_url);
  641. log('----广告地址----');
  642. log(ad_urls);
  643. m3u8 = ss.join('\n');
  644. //log('处理完成');
  645. log('处理耗时:' + (new Date().getTime() - ts).toString());
  646. return m3u8
  647. }
  648. /**
  649. * 强制正序算法
  650. * @param lists 待正序列表
  651. * @param key 正序键
  652. * @param option 单个元素处理函数
  653. * @returns {*}
  654. */
  655. function forceOrder(lists,key,option){
  656. let start = Math.floor(lists.length/2);
  657. let end = Math.min(lists.length-1,start+1);
  658. if(start >= end){
  659. return lists;
  660. }
  661. let first = lists[start];
  662. let second = lists[end];
  663. if(key){
  664. try {
  665. first = first[key];
  666. second = second[key];
  667. }catch (e) {}
  668. }
  669. if(option && typeof(option)==='function'){
  670. try {
  671. first = option(first);
  672. second = option(second);
  673. }catch (e) {}
  674. }
  675. first+='';
  676. second+='';
  677. // console.log(first,second);
  678. if(first.match(/(\d+)/)&&second.match(/(\d+)/)){
  679. let num1 = Number(first.match(/(\d+)/)[1]);
  680. let num2 = Number(second.match(/(\d+)/)[1]);
  681. if (num1 > num2){
  682. lists.reverse();
  683. }
  684. }
  685. return lists
  686. }
  687. let VODS = [];// 一级或者搜索需要的数据列表
  688. let VOD = {};// 二级的单个数据
  689. let TABS = [];// 二级的自定义线路列表 如: TABS=['道长在线','道长在线2']
  690. let LISTS = [];// 二级的自定义选集播放列表 如: LISTS=[['第1集$http://1.mp4','第2集$http://2.mp4'],['第3集$http://1.mp4','第4集$http://2.mp4']]
  691. globalThis.encodeUrl = urlencode;
  692. globalThis.urlencode = urlencode;
  693. /**
  694. * url拼接
  695. * @param fromPath 初始当前页面url
  696. * @param nowPath 相对当前页面url
  697. * @returns {*}
  698. */
  699. function urljoin(fromPath, nowPath) {
  700. fromPath = fromPath||'';
  701. nowPath = nowPath||'';
  702. return joinUrl(fromPath, nowPath);
  703. // try {
  704. // // import Uri from './uri.min.js';
  705. // // var Uri = require('./uri.min.js');
  706. // // eval(request('https://cdn.bootcdn.net/ajax/libs/URI.js/1.19.11/URI.min.js'));
  707. // // let new_uri = URI(nowPath, fromPath);
  708. // let new_uri = Uri(nowPath, fromPath);
  709. // new_uri = new_uri.toString();
  710. // // console.log(new_uri);
  711. // // return fromPath + nowPath
  712. // return new_uri
  713. // }
  714. // catch (e) {
  715. // console.log('urljoin发生错误:'+e.message);
  716. // if(nowPath.startsWith('http')){
  717. // return nowPath
  718. // }if(nowPath.startsWith('/')){
  719. // return getHome(fromPath)+nowPath
  720. // }
  721. // return fromPath+nowPath
  722. // }
  723. }
  724. var urljoin2 = urljoin;
  725. // 内置 pdfh,pdfa,pd
  726. const defaultParser = {
  727. pdfh:pdfh,
  728. pdfa:pdfa,
  729. pd:pd,
  730. };
  731. /**
  732. * pdfh原版优化,能取style属性里的图片链接
  733. * @param html 源码
  734. * @param parse 解析表达式
  735. * @returns {string|*}
  736. */
  737. function pdfh2(html,parse){
  738. let html2 = html;
  739. try {
  740. if(typeof(html)!=='string'){
  741. html2 = html.rr(html.ele).toString();
  742. }
  743. }catch (e) {
  744. print('html对象转文本发生了错误:'+e.message);
  745. }
  746. let result = defaultParser.pdfh(html2,parse);
  747. let option = parse.includes('&&')?parse.split('&&').slice(-1)[0]:parse.split(' ').slice(-1)[0];
  748. if(/style/.test(option.toLowerCase())&&/url\(/.test(result)){
  749. try {
  750. result = result.match(/url\((.*?)\)/)[1];
  751. // 2023/07/28新增 style取内部链接自动去除首尾单双引号
  752. result = result.replace(/^['|"](.*)['|"]$/, "$1");
  753. }catch (e) {}
  754. }
  755. return result
  756. }
  757. /**
  758. * pdfa原版优化,可以转换jq的html对象
  759. * @param html
  760. * @param parse
  761. * @returns {*}
  762. */
  763. function pdfa2(html,parse){
  764. let html2 = html;
  765. try {
  766. if(typeof(html)!=='string'){
  767. html2 = html.rr(html.ele).toString();
  768. }
  769. }catch (e) {
  770. print('html对象转文本发生了错误:'+e.message);
  771. }
  772. return defaultParser.pdfa(html2,parse);
  773. }
  774. /**
  775. * pd原版方法重写-增加自动urljoin
  776. * @param html
  777. * @param parse
  778. * @param uri
  779. * @returns {*}
  780. */
  781. function pd2(html,parse,uri){
  782. let ret = pdfh2(html,parse);
  783. if(typeof(uri)==='undefined'||!uri){
  784. uri = '';
  785. }
  786. if(DOM_CHECK_ATTR.test(parse) && !SPECIAL_URL.test(ret)){
  787. if(/http/.test(ret)){
  788. ret = ret.slice(ret.indexOf('http'));
  789. }else{
  790. ret = urljoin(MY_URL,ret)
  791. }
  792. }
  793. // MY_URL = getItem('MY_URL',MY_URL);
  794. // console.log(`规则${RKEY}打印MY_URL:${MY_URL},uri:${uri}`);
  795. return ret
  796. }
  797. const parseTags = {
  798. jsp:{
  799. pdfh:pdfh2,
  800. pdfa:pdfa2,
  801. pd:pd2,
  802. },
  803. json:{
  804. pdfh(html, parse) {
  805. if (!parse || !parse.trim()){
  806. return '';
  807. }
  808. if (typeof(html) === 'string'){
  809. // print('jsonpath:pdfh字符串转dict');
  810. html = JSON.parse(html);
  811. }
  812. parse = parse.trim();
  813. if (!parse.startsWith('$.')){
  814. parse = '$.' + parse;
  815. }
  816. parse = parse.split('||');
  817. for (let ps of parse) {
  818. let ret = cheerio.jp(ps, html);
  819. if (Array.isArray(ret)){
  820. ret = ret[0] || '';
  821. } else{
  822. ret = ret || ''
  823. }
  824. if (ret && typeof (ret) !== 'string'){
  825. ret = ret.toString();
  826. }
  827. if(ret){
  828. return ret
  829. }
  830. }
  831. return '';
  832. },
  833. pdfa(html, parse) {
  834. if (!parse || !parse.trim()){
  835. return '';
  836. }
  837. if (typeof(html) === 'string'){
  838. // print('jsonpath:pdfa字符串转dict');
  839. html = JSON.parse(html);
  840. }
  841. parse = parse.trim()
  842. if (!parse.startsWith('$.')){
  843. parse = '$.' + parse;
  844. }
  845. let ret = cheerio.jp(parse, html);
  846. if (Array.isArray(ret) && Array.isArray(ret[0]) && ret.length === 1){
  847. return ret[0] || []
  848. }
  849. return ret || []
  850. },
  851. pd(html,parse){
  852. let ret = parseTags.json.pdfh(html,parse);
  853. if(ret){
  854. return urljoin(MY_URL,ret);
  855. }
  856. return ret
  857. },
  858. },
  859. jq:{
  860. pdfh(html, parse) {
  861. if (!html||!parse || !parse.trim()) {
  862. return ''
  863. }
  864. parse = parse.trim();
  865. let result = defaultParser.pdfh(html,parse);
  866. // print(`pdfh解析${parse}=>${result}`);
  867. return result;
  868. },
  869. pdfa(html, parse) {
  870. if (!html||!parse || !parse.trim()) {
  871. return [];
  872. }
  873. parse = parse.trim();
  874. let result = defaultParser.pdfa(html,parse);
  875. // print(result);
  876. print(`pdfa解析${parse}=>${result.length}`);
  877. return result;
  878. },
  879. pd(html,parse,base_url){
  880. if (!html||!parse || !parse.trim()) {
  881. return ''
  882. }
  883. parse = parse.trim();
  884. base_url = base_url||MY_URL;
  885. return defaultParser.pd(html, parse, base_url);
  886. },
  887. },
  888. getParse(p0){//非js开头的情况自动获取解析标签
  889. if(p0.startsWith('jsp:')){
  890. return this.jsp
  891. }else if(p0.startsWith('json:')){
  892. return this.json
  893. }else if(p0.startsWith('jq:')){
  894. return this.jq
  895. }else {
  896. return this.jq
  897. }
  898. }
  899. };
  900. const stringify = JSON.stringify;
  901. const jsp = parseTags.jsp;
  902. const jq = parseTags.jq;
  903. /*** 后台需要实现的java方法并注入到js中 ***/
  904. /**
  905. * 读取本地文件->应用程序目录
  906. * @param filePath
  907. * @returns {string}
  908. */
  909. function readFile(filePath){
  910. filePath = filePath||'./uri.min.js';
  911. var fd = os.open(filePath);
  912. var buffer = new ArrayBuffer(1024);
  913. var len = os.read(fd, buffer, 0, 1024);
  914. console.log(len);
  915. let text = String.fromCharCode.apply(null, new Uint8Array(buffer));
  916. console.log(text);
  917. return text
  918. }
  919. /**
  920. * 处理返回的json数据
  921. * @param html
  922. * @returns {*}
  923. */
  924. function dealJson(html) {
  925. try {
  926. // html = html.match(/[\w|\W|\s|\S]*?(\{[\w|\W|\s|\S]*\})/).group[1];
  927. html = html.trim();
  928. if(!((html.startsWith('{') && html.endsWith('}'))||(html.startsWith('[') && html.endsWith(']')))){
  929. html = '{'+html.match(/.*?\{(.*)\}/m)[1]+'}';
  930. }
  931. } catch (e) {
  932. }
  933. try {
  934. html = JSON.parse(html);
  935. }catch (e) {}
  936. // console.log(typeof(html));
  937. return html;
  938. }
  939. /**
  940. * 验证码识别逻辑,需要java实现(js没有bytes类型,无法调用后端的传递图片二进制获取验证码文本的接口)
  941. * @type {{api: string, classification: (function(*=): string)}}
  942. */
  943. var OcrApi={
  944. api:OCR_API,
  945. classification:function (img){ // img是byte类型,这里不方便搞啊
  946. let code = '';
  947. try {
  948. // let html = request(this.api,{data:{img:img},headers:{'User-Agent':PC_UA},'method':'POST'},true);
  949. // html = JSON.parse(html);
  950. // code = html.url||'';
  951. log('通过drpy_ocr验证码接口过验证...');
  952. let html = request(OCR_API,{data:{img:img},headers:{'User-Agent':PC_UA},'method':'POST'},true);
  953. code = html||'';
  954. }catch (e) {
  955. log(`OCR识别验证码发生错误:${e.message}`)
  956. }
  957. return code
  958. }
  959. };
  960. /**
  961. * 验证码识别,暂未实现
  962. * @param url 验证码图片链接
  963. * @returns {string} 验证成功后的cookie
  964. */
  965. function verifyCode(url){
  966. let cnt = 0;
  967. let host = getHome(url);
  968. let cookie = '';
  969. while (cnt < OCR_RETRY){
  970. try{
  971. // let obj = {headers:headers,timeout:timeout};
  972. let yzm_url = `${host}/index.php/verify/index.html`;
  973. console.log(`验证码链接:${yzm_url}`);
  974. let hhtml = request(yzm_url,{withHeaders:true,toBase64:true},true);
  975. let json = JSON.parse(hhtml);
  976. if(!cookie){
  977. // print(json);
  978. let setCk = Object.keys(json).find(it=>it.toLowerCase()==='set-cookie');
  979. // cookie = json['set-cookie']?json['set-cookie'].split(';')[0]:'';
  980. cookie = setCk?json[setCk].split(';')[0]:'';
  981. }
  982. // console.log(hhtml);
  983. console.log('cookie:'+cookie);
  984. let img = json.body;
  985. // console.log(img);
  986. let code = OcrApi.classification(img);
  987. console.log(`第${cnt+1}次验证码识别结果:${code}`);
  988. let submit_url = `${host}/index.php/ajax/verify_check?type=search&verify=${code}`;
  989. console.log(submit_url);
  990. let html = request(submit_url,{headers:{Cookie:cookie,'User-Agent':MOBILE_UA},'method':'POST'});
  991. // console.log(html);
  992. html = JSON.parse(html);
  993. if(html.msg === 'ok'){
  994. console.log(`第${cnt+1}次验证码提交成功`);
  995. return cookie // 需要返回cookie
  996. }else if(html.msg!=='ok'&&cnt+1>=OCR_RETRY){
  997. cookie = ''; // 需要清空返回cookie
  998. }
  999. }catch (e) {
  1000. console.log(`第${cnt+1}次验证码提交失败:${e.message}`);
  1001. if(cnt+1>=OCR_RETRY){
  1002. cookie = '';
  1003. }
  1004. }
  1005. cnt+=1
  1006. }
  1007. return cookie
  1008. }
  1009. /**
  1010. * 存在数据库配置表里, key字段对应值value,没有就新增,有就更新,调用此方法会清除key对应的内存缓存
  1011. * @param k 键
  1012. * @param v 值
  1013. */
  1014. function setItem(k,v){
  1015. local.set(RKEY,k,v);
  1016. console.log(`规则${RKEY}设置${k} => ${v}`)
  1017. }
  1018. /**
  1019. * 获取数据库配置表对应的key字段的value,没有这个key就返回value默认传参.需要有缓存,第一次获取后会存在内存里
  1020. * @param k 键
  1021. * @param v 值
  1022. * @returns {*}
  1023. */
  1024. function getItem(k,v){
  1025. return local.get(RKEY,k) || v;
  1026. }
  1027. /**
  1028. * 删除数据库key对应的一条数据,并清除此key对应的内存缓存
  1029. * @param k
  1030. */
  1031. function clearItem(k){
  1032. local.delete(RKEY,k);
  1033. }
  1034. /*** js自封装的方法 ***/
  1035. /**
  1036. * 获取链接的host(带http协议的完整链接)
  1037. * @param url 任意一个正常完整的Url,自动提取根
  1038. * @returns {string}
  1039. */
  1040. function getHome(url){
  1041. if(!url){
  1042. return ''
  1043. }
  1044. let tmp = url.split('//');
  1045. url = tmp[0] + '//' + tmp[1].split('/')[0];
  1046. try {
  1047. url = decodeURIComponent(url);
  1048. }catch (e) {}
  1049. return url
  1050. }
  1051. /**
  1052. * get参数编译链接,类似python params字典自动拼接
  1053. * @param url 访问链接
  1054. * @param obj 参数字典
  1055. * @returns {*}
  1056. */
  1057. function buildUrl(url,obj){
  1058. obj = obj||{};
  1059. if(url.indexOf('?')<0){
  1060. url += '?'
  1061. }
  1062. let param_list = [];
  1063. let keys = Object.keys(obj);
  1064. keys.forEach(it=>{
  1065. param_list.push(it+'='+obj[it])
  1066. });
  1067. let prs = param_list.join('&');
  1068. if(keys.length > 0 && !url.endsWith('?')){
  1069. url += '&'
  1070. }
  1071. url+=prs;
  1072. return url
  1073. }
  1074. /**
  1075. * 远程依赖执行函数
  1076. * @param url 远程js地址
  1077. */
  1078. function require(url){
  1079. eval(request(url));
  1080. }
  1081. /**
  1082. * 海阔网页请求函数完整封装
  1083. * @param url 请求链接
  1084. * @param obj 请求对象 {headers:{},method:'',timeout:5000,body:'',withHeaders:false}
  1085. * @param ocr_flag 标识此flag是用于请求ocr识别的,自动过滤content-type指定编码
  1086. * @returns {string|string|DocumentFragment|*}
  1087. */
  1088. function request(url,obj,ocr_flag){
  1089. ocr_flag = ocr_flag||false;
  1090. if(typeof(obj)==='undefined'||!obj||obj==={}){
  1091. if(!fetch_params||!fetch_params.headers){
  1092. let headers = {
  1093. 'User-Agent':MOBILE_UA,
  1094. };
  1095. if(rule.headers){
  1096. Object.assign(headers,rule.headers);
  1097. }
  1098. if(!fetch_params){
  1099. fetch_params = {};
  1100. }
  1101. fetch_params.headers = headers;
  1102. }
  1103. if(!fetch_params.headers.Referer){
  1104. fetch_params.headers.Referer = getHome(url)
  1105. }
  1106. obj = fetch_params;
  1107. }else{
  1108. let headers = obj.headers||{};
  1109. let keys = Object.keys(headers).map(it=>it.toLowerCase());
  1110. if(!keys.includes('user-agent')){
  1111. headers['User-Agent'] = MOBILE_UA;
  1112. }if(!keys.includes('referer')){
  1113. headers['Referer'] = getHome(url);
  1114. }
  1115. obj.headers = headers;
  1116. }
  1117. if(rule.encoding&&rule.encoding!=='utf-8'&&!ocr_flag){
  1118. if(!obj.headers.hasOwnProperty('Content-Type')&&!obj.headers.hasOwnProperty('content-type')){ // 手动指定了就不管
  1119. obj.headers["Content-Type"] = 'text/html; charset='+rule.encoding;
  1120. }
  1121. }
  1122. if(typeof(obj.body)!='undefined'&&obj.body&&typeof (obj.body)==='string'){
  1123. // let data = {};
  1124. // obj.body.split('&').forEach(it=>{
  1125. // data[it.split('=')[0]] = it.split('=')[1]
  1126. // });
  1127. // obj.data = data;
  1128. // delete obj.body
  1129. // 传body加 "Content-Type":"application/x-www-form-urlencoded;" 即可post form
  1130. if(!obj.headers.hasOwnProperty('Content-Type')&&!obj.headers.hasOwnProperty('content-type')){ // 手动指定了就不管
  1131. obj.headers["Content-Type"] = 'application/x-www-form-urlencoded; charset='+rule.encoding;
  1132. }
  1133. }else if(typeof(obj.body)!='undefined'&&obj.body&&typeof (obj.body)==='object'){
  1134. obj.data = obj.body;
  1135. delete obj.body
  1136. }
  1137. if(!url){
  1138. return obj.withHeaders?'{}':''
  1139. }
  1140. if(obj.toBase64){ // 返回base64,用于请求图片
  1141. obj.buffer = 2;
  1142. delete obj.toBase64
  1143. }
  1144. if(obj.redirect===false){
  1145. obj.redirect = 0;
  1146. }
  1147. console.log(JSON.stringify(obj.headers));
  1148. // console.log('request:'+url+' obj:'+JSON.stringify(obj));
  1149. console.log('request:'+url+`|method:${obj.method||'GET'}|body:${obj.body||''}`);
  1150. let res = req(url, obj);
  1151. let html = res.content||'';
  1152. // console.log(html);
  1153. if(obj.withHeaders){
  1154. let htmlWithHeaders = res.headers;
  1155. htmlWithHeaders.body = html;
  1156. return JSON.stringify(htmlWithHeaders);
  1157. }else{
  1158. return html
  1159. }
  1160. }
  1161. /**
  1162. * 快捷post请求
  1163. * @param url 地址
  1164. * @param obj 对象
  1165. * @returns {string|DocumentFragment|*}
  1166. */
  1167. function post(url,obj){
  1168. obj.method = 'POST';
  1169. return request(url,obj);
  1170. }
  1171. fetch = request;
  1172. print = function (data){
  1173. data = data||'';
  1174. if(typeof(data)=='object'&&Object.keys(data).length>0){
  1175. try {
  1176. data = JSON.stringify(data);
  1177. console.log(data);
  1178. }catch (e) {
  1179. // console.log('print:'+e.message);
  1180. console.log(typeof(data)+':'+data.length);
  1181. return
  1182. }
  1183. }else if(typeof(data)=='object'&&Object.keys(data).length<1){
  1184. console.log('null object');
  1185. }else{
  1186. console.log(data);
  1187. }
  1188. }
  1189. log = print;
  1190. /**
  1191. * 检查宝塔验证并自动跳过获取正确源码
  1192. * @param html 之前获取的html
  1193. * @param url 之前的来源url
  1194. * @param obj 来源obj
  1195. * @returns {string|DocumentFragment|*}
  1196. */
  1197. function checkHtml(html,url,obj){
  1198. if(/\?btwaf=/.test(html)){
  1199. let btwaf = html.match(/btwaf(.*?)"/)[1];
  1200. url = url.split('#')[0]+'?btwaf'+btwaf;
  1201. print('宝塔验证访问链接:'+url);
  1202. html = request(url,obj);
  1203. }
  1204. return html
  1205. }
  1206. /**
  1207. * 带一次宝塔验证的源码获取
  1208. * @param url 请求链接
  1209. * @param obj 请求参数
  1210. * @returns {string|DocumentFragment}
  1211. */
  1212. function getCode(url,obj){
  1213. let html = request(url,obj);
  1214. html = checkHtml(html,url,obj);
  1215. return html
  1216. }
  1217. /**
  1218. * 源rule专用的请求方法,自动注入cookie
  1219. * @param url 请求链接
  1220. * @returns {string|DocumentFragment}
  1221. */
  1222. function getHtml(url){
  1223. let obj = {};
  1224. if(rule.headers){
  1225. obj.headers = rule.headers;
  1226. }
  1227. let cookie = getItem(RULE_CK,'');
  1228. if(cookie){
  1229. // log('有cookie:'+cookie);
  1230. if(obj.headers && ! Object.keys(obj.headers).map(it=>it.toLowerCase()).includes('cookie')){
  1231. log('历史无cookie,新增过验证后的cookie');
  1232. obj.headers['Cookie'] = cookie;
  1233. }else if(obj.headers && obj.headers.cookie && obj.headers.cookie!==cookie){
  1234. obj.headers['Cookie'] = cookie;
  1235. log('历史有小写过期的cookie,更新过验证后的cookie');
  1236. }else if(obj.headers && obj.headers.Cookie && obj.headers.Cookie!==cookie){
  1237. obj.headers['Cookie'] = cookie;
  1238. log('历史有大写过期的cookie,更新过验证后的cookie');
  1239. }else if(!obj.headers){
  1240. obj.headers = {Cookie:cookie};
  1241. log('历史无headers,更新过验证后的含cookie的headers');
  1242. }
  1243. }
  1244. let html = getCode(url,obj);
  1245. return html
  1246. }
  1247. /**
  1248. * 首页分类解析,筛选暂未实现
  1249. * @param homeObj 首页传参对象
  1250. * @returns {string}
  1251. */
  1252. function homeParse(homeObj) {
  1253. fetch_params = JSON.parse(JSON.stringify(rule_fetch_params));
  1254. let classes = [];
  1255. if (homeObj.class_name && homeObj.class_url) {
  1256. let names = homeObj.class_name.split('&');
  1257. let urls = homeObj.class_url.split('&');
  1258. let cnt = Math.min(names.length, urls.length);
  1259. for (let i = 0; i < cnt; i++) {
  1260. classes.push({
  1261. 'type_id': urls[i],
  1262. 'type_name': names[i]
  1263. });
  1264. }
  1265. }
  1266. if (homeObj.class_parse) {
  1267. if(homeObj.class_parse.startsWith('js:')) {
  1268. var input = homeObj.MY_URL;
  1269. try {
  1270. eval(homeObj.class_parse.replace('js:', ''));
  1271. if (Array.isArray(input)) {
  1272. classes = input;
  1273. }
  1274. }catch(e){
  1275. log('通过js动态获取分类发生了错误:'+e.message);
  1276. }
  1277. }else {
  1278. let p = homeObj.class_parse.split(';');
  1279. let p0 = p[0];
  1280. let _ps = parseTags.getParse(p0);
  1281. let is_json = p0.startsWith('json:');
  1282. _pdfa = _ps.pdfa;
  1283. _pdfh = _ps.pdfh;
  1284. _pd = _ps.pd;
  1285. MY_URL = rule.url;
  1286. if(is_json){
  1287. try {
  1288. let cms_cate_url = homeObj.MY_URL.replace('ac=detail','ac=list');
  1289. let html = getHtml(cms_cate_url);
  1290. if (html) {
  1291. if(cms_cate_url === homeObj.MY_URL){
  1292. homeHtmlCache = html;
  1293. }
  1294. let list = _pdfa(html, p0.replace('json:',''));
  1295. if (list && list.length > 0) {
  1296. classes = list;
  1297. }
  1298. }
  1299. } catch (e) {
  1300. console.log(e.message);
  1301. }
  1302. } else if(p.length >= 3 && !is_json) { // 可以不写正则
  1303. try {
  1304. let html = getHtml(homeObj.MY_URL);
  1305. if (html) {
  1306. homeHtmlCache = html;
  1307. let list = _pdfa(html, p0);
  1308. if (list && list.length > 0) {
  1309. list.forEach((it, idex) => {
  1310. try {
  1311. let name = _pdfh(it, p[1]);
  1312. if (homeObj.cate_exclude && (new RegExp(homeObj.cate_exclude).test(name))) {
  1313. return;
  1314. }
  1315. // let url = pdfh(it, p[2]);
  1316. let url = _pd(it, p[2]);
  1317. if (p.length > 3 && p[3]) {
  1318. let exp = new RegExp(p[3]);
  1319. url = url.match(exp)[1];
  1320. }
  1321. classes.push({
  1322. 'type_id': url.trim(),
  1323. 'type_name': name.trim()
  1324. });
  1325. } catch (e) {
  1326. console.log(`分类列表定位第${idex}个元素正常报错:${e.message}`);
  1327. }
  1328. });
  1329. }
  1330. }
  1331. } catch (e) {
  1332. console.log(e.message);
  1333. }
  1334. }
  1335. }
  1336. }
  1337. // 排除分类
  1338. classes = classes.filter(it=>!homeObj.cate_exclude || !(new RegExp(homeObj.cate_exclude).test(it.type_name)));
  1339. let resp = {
  1340. 'class': classes
  1341. };
  1342. if(homeObj.filter){
  1343. resp.filters = homeObj.filter;
  1344. }
  1345. console.log(JSON.stringify(resp));
  1346. return JSON.stringify(resp);
  1347. }
  1348. /**
  1349. * 推荐和搜索单字段继承一级
  1350. * @param p 推荐或搜索的解析分割;列表
  1351. * @param pn 自身列表序号
  1352. * @param pp 一级解析分割;列表
  1353. * @param ppn 继承一级序号
  1354. * @returns {*}
  1355. */
  1356. function getPP(p, pn, pp, ppn){
  1357. try {
  1358. let ps = p[pn] === '*' && pp.length > ppn ?pp[ppn]:p[pn]
  1359. return ps
  1360. }catch (e) {
  1361. return ''
  1362. }
  1363. }
  1364. /**
  1365. * 首页推荐列表解析
  1366. * @param homeVodObj
  1367. * @returns {string}
  1368. */
  1369. function homeVodParse(homeVodObj){
  1370. fetch_params = JSON.parse(JSON.stringify(rule_fetch_params));
  1371. let d = [];
  1372. MY_URL = homeVodObj.homeUrl;
  1373. // setItem('MY_URL',MY_URL);
  1374. console.log(MY_URL);
  1375. let t1 = (new Date()).getTime();
  1376. let p = homeVodObj.推荐;
  1377. print('p:'+p);
  1378. if(p==='*' && rule.一级){
  1379. p = rule.一级;
  1380. homeVodObj.double = false;
  1381. }
  1382. if(!p||typeof(p)!=='string'){
  1383. return '{}'
  1384. }
  1385. p = p.trim();
  1386. let pp = rule.一级.split(';');
  1387. if(p.startsWith('js:')){
  1388. const TYPE = 'home';
  1389. var input = MY_URL;
  1390. HOST = rule.host;
  1391. eval(p.replace('js:',''));
  1392. d = VODS;
  1393. }else {
  1394. p = p.split(';');
  1395. if (!homeVodObj.double && p.length < 5) {
  1396. return '{}'
  1397. } else if (homeVodObj.double && p.length < 6) {
  1398. return '{}'
  1399. }
  1400. let p0 = getPP(p,0,pp,0)
  1401. let _ps = parseTags.getParse(p0);
  1402. _pdfa = _ps.pdfa;
  1403. _pdfh = _ps.pdfh;
  1404. _pd = _ps.pd;
  1405. let is_json = p0.startsWith('json:');
  1406. p0 = p0.replace(/^(jsp:|json:|jq:)/,'');
  1407. // print(p[0]);
  1408. let html = homeHtmlCache || getHtml(MY_URL);
  1409. homeHtmlCache = undefined;
  1410. if(is_json){
  1411. // print('是json,开始处理');
  1412. html = dealJson(html);
  1413. }
  1414. try {
  1415. console.log('double:' + homeVodObj.double);
  1416. if (homeVodObj.double) {
  1417. let items = _pdfa(html, p0);
  1418. // console.log(items.length);
  1419. let p1 = getPP(p,1,pp,0);
  1420. let p2 = getPP(p,2,pp,1);
  1421. let p3 = getPP(p,3,pp,2);
  1422. let p4 = getPP(p,4,pp,3);
  1423. let p5 = getPP(p,5,pp,4);
  1424. let p6 = getPP(p,6,pp,5);
  1425. for (let item of items) {
  1426. // console.log(p[1]);
  1427. let items2 = _pdfa(item, p1);
  1428. // console.log(items2.length);
  1429. for (let item2 of items2) {
  1430. try {
  1431. let title = _pdfh(item2, p2);
  1432. let img = '';
  1433. try {
  1434. img = _pd(item2, p3);
  1435. } catch (e) {}
  1436. let desc = '';
  1437. try {
  1438. desc = _pdfh(item2, p4);
  1439. }catch (e) {}
  1440. let links = [];
  1441. for (let _p5 of p5.split('+')) {
  1442. let link = !homeVodObj.detailUrl ? _pd(item2, _p5, MY_URL) : _pdfh(item2, _p5);
  1443. links.push(link);
  1444. }
  1445. let content;
  1446. if(p.length > 6 && p[6]){
  1447. content = _pdfh(item2, p6);
  1448. } else{
  1449. content = '';
  1450. }
  1451. let vid = links.join('$');
  1452. if(rule.二级==='*'){
  1453. vid = vid+'@@'+title+'@@'+img;
  1454. }
  1455. let vod = {
  1456. vod_name: title,
  1457. vod_pic: img,
  1458. vod_remarks: desc,
  1459. vod_content: content,
  1460. vod_id: vid
  1461. };
  1462. // print(vod);
  1463. d.push(vod);
  1464. } catch (e) {
  1465. console.log('首页列表双层定位处理发生错误:'+e.message);
  1466. }
  1467. }
  1468. }
  1469. } else {
  1470. let items = _pdfa(html, p0);
  1471. let p1 = getPP(p,1,pp,1);
  1472. let p2 = getPP(p,2,pp,2);
  1473. let p3 = getPP(p,3,pp,3);
  1474. let p4 = getPP(p,4,pp,4);
  1475. let p5 = getPP(p,5,pp,5);
  1476. for (let item of items) {
  1477. try {
  1478. let title = _pdfh(item, p1);
  1479. let img = '';
  1480. try {
  1481. img = _pd(item, p2, MY_URL);
  1482. } catch (e) {}
  1483. let desc = '';
  1484. try {
  1485. desc = _pdfh(item, p3);
  1486. }catch (e) {}
  1487. let links = [];
  1488. for (let _p5 of p4.split('+')) {
  1489. let link = !homeVodObj.detailUrl ? _pd(item, _p5, MY_URL) : _pdfh(item, _p5);
  1490. links.push(link);
  1491. }
  1492. let content;
  1493. if(p.length > 5 && p[5]){
  1494. content = _pdfh(item, p5);
  1495. }else{
  1496. content = ''
  1497. }
  1498. let vid = links.join('$');
  1499. if(rule.二级==='*'){
  1500. vid = vid+'@@'+title+'@@'+img;
  1501. }
  1502. let vod = {
  1503. vod_name: title,
  1504. vod_pic: img,
  1505. vod_remarks: desc,
  1506. vod_content: content,
  1507. vod_id: vid
  1508. };
  1509. d.push(vod);
  1510. } catch (e) {
  1511. console.log('首页列表单层定位处理发生错误:'+e.message);
  1512. }
  1513. }
  1514. }
  1515. } catch (e) {
  1516. }
  1517. }
  1518. let t2 = (new Date()).getTime();
  1519. console.log('加载首页推荐耗时:'+(t2-t1)+'毫秒');
  1520. // console.log(JSON.stringify(d));
  1521. if(rule.图片替换 && rule.图片替换.includes('=>')){
  1522. let replace_from = rule.图片替换.split('=>')[0];
  1523. let replace_to = rule.图片替换.split('=>')[1];
  1524. d.forEach(it=>{
  1525. if(it.vod_pic&&it.vod_pic.startsWith('http')){
  1526. it.vod_pic = it.vod_pic.replace(replace_from,replace_to);
  1527. }
  1528. });
  1529. }
  1530. if(rule.图片来源){
  1531. d.forEach(it=>{
  1532. if(it.vod_pic&&it.vod_pic.startsWith('http')){
  1533. it.vod_pic = it.vod_pic + rule.图片来源;
  1534. }
  1535. });
  1536. }
  1537. if(d.length>0){
  1538. print(d.slice(0,2));
  1539. }
  1540. return JSON.stringify({
  1541. list:d
  1542. })
  1543. }
  1544. /**
  1545. * 一级分类页数据解析
  1546. * @param cateObj
  1547. * @returns {string}
  1548. */
  1549. function categoryParse(cateObj) {
  1550. fetch_params = JSON.parse(JSON.stringify(rule_fetch_params));
  1551. let p = cateObj.一级;
  1552. if(!p||typeof(p)!=='string'){
  1553. return '{}'
  1554. }
  1555. let d = [];
  1556. // let url = cateObj.url.replaceAll('fyclass', cateObj.tid).replaceAll('fypage', cateObj.pg);
  1557. let url = cateObj.url.replaceAll('fyclass', cateObj.tid);
  1558. if(cateObj.pg === 1 && url.includes('[')&&url.includes(']')){
  1559. url = url.split('[')[1].split(']')[0];
  1560. }else if(cateObj.pg > 1 && url.includes('[')&&url.includes(']')){
  1561. url = url.split('[')[0];
  1562. }
  1563. if(rule.filter_url){
  1564. if(!/fyfilter/.test(url)){
  1565. if(!url.endsWith('&')&&!rule.filter_url.startsWith('&')){
  1566. url+='&'
  1567. }
  1568. url+=rule.filter_url;
  1569. }else{
  1570. url = url.replace('fyfilter', rule.filter_url);
  1571. }
  1572. // console.log('filter:'+cateObj.filter);
  1573. let fl = cateObj.filter?cateObj.extend:{};
  1574. // 自动合并 不同分类对应的默认筛选
  1575. if(rule.filter_def && typeof(rule.filter_def)==='object'){
  1576. try {
  1577. if(Object.keys(rule.filter_def).length>0 && rule.filter_def.hasOwnProperty(cateObj.tid)){
  1578. let self_fl_def = rule.filter_def[cateObj.tid];
  1579. if(self_fl_def && typeof(self_fl_def)==='object'){
  1580. // 引用传递转值传递,避免污染self变量
  1581. let fl_def = JSON.parse(JSON.stringify(self_fl_def));
  1582. fl = Object.assign(fl_def,fl);
  1583. }
  1584. }
  1585. }catch (e) {
  1586. print('合并不同分类对应的默认筛选出错:'+e.message);
  1587. }
  1588. }
  1589. let new_url;
  1590. new_url = cheerio.jinja2(url,{fl:fl});
  1591. // console.log('jinjia2执行后的new_url类型为:'+typeof(new_url));
  1592. url = new_url;
  1593. }
  1594. if(/fypage/.test(url)){
  1595. if(url.includes('(')&&url.includes(')')){
  1596. let url_rep = url.match(/.*?\((.*)\)/)[1];
  1597. // console.log(url_rep);
  1598. let cnt_page = url_rep.replaceAll('fypage', cateObj.pg);
  1599. // console.log(cnt_page);
  1600. let cnt_pg = eval(cnt_page);
  1601. // console.log(cnt_pg);
  1602. url = url.replaceAll(url_rep,cnt_pg).replaceAll('(','').replaceAll(')','');
  1603. }else{
  1604. url = url.replaceAll('fypage',cateObj.pg);
  1605. }
  1606. }
  1607. MY_URL = url;
  1608. // setItem('MY_URL',MY_URL);
  1609. console.log(MY_URL);
  1610. p = p.trim();
  1611. const MY_CATE = cateObj.tid;
  1612. if(p.startsWith('js:')){
  1613. var MY_FL = cateObj.extend;
  1614. const TYPE = 'cate';
  1615. var input = MY_URL;
  1616. const MY_PAGE = cateObj.pg;
  1617. var desc = '';
  1618. eval(p.trim().replace('js:',''));
  1619. d = VODS;
  1620. }else {
  1621. p = p.split(';');
  1622. if (p.length < 5) {
  1623. return '{}'
  1624. }
  1625. let _ps = parseTags.getParse(p[0]);
  1626. _pdfa = _ps.pdfa;
  1627. _pdfh = _ps.pdfh;
  1628. _pd = _ps.pd;
  1629. let is_json = p[0].startsWith('json:');
  1630. p[0] = p[0].replace(/^(jsp:|json:|jq:)/,'');
  1631. try {
  1632. let html = getHtml(MY_URL);
  1633. if (html) {
  1634. if(is_json){
  1635. html = dealJson(html);
  1636. }
  1637. let list = _pdfa(html, p[0]);
  1638. list.forEach(it => {
  1639. let links = p[4].split('+').map(p4=>{
  1640. return !rule.detailUrl?_pd(it, p4,MY_URL):_pdfh(it, p4);
  1641. });
  1642. let link = links.join('$');
  1643. let vod_id = rule.detailUrl?MY_CATE+'$'+link:link;
  1644. let vod_name = _pdfh(it, p[1]).replace(/\n|\t/g,'').trim();
  1645. let vod_pic = _pd(it, p[2],MY_URL);
  1646. if(rule.二级==='*'){
  1647. vod_id = vod_id+'@@'+vod_name+'@@'+vod_pic;
  1648. }
  1649. d.push({
  1650. 'vod_id': vod_id,
  1651. 'vod_name': vod_name,
  1652. 'vod_pic': vod_pic,
  1653. 'vod_remarks': _pdfh(it, p[3]).replace(/\n|\t/g,'').trim(),
  1654. });
  1655. });
  1656. }
  1657. } catch (e) {
  1658. console.log(e.message);
  1659. }
  1660. }
  1661. if(rule.图片替换 && rule.图片替换.includes('=>')){
  1662. let replace_from = rule.图片替换.split('=>')[0];
  1663. let replace_to = rule.图片替换.split('=>')[1];
  1664. d.forEach(it=>{
  1665. if(it.vod_pic&&it.vod_pic.startsWith('http')){
  1666. it.vod_pic = it.vod_pic.replace(replace_from,replace_to);
  1667. }
  1668. });
  1669. }
  1670. if(rule.图片来源){
  1671. d.forEach(it=>{
  1672. if(it.vod_pic&&it.vod_pic.startsWith('http')){
  1673. it.vod_pic = it.vod_pic + rule.图片来源;
  1674. }
  1675. });
  1676. }
  1677. // print(d);
  1678. if(d.length>0){
  1679. print(d.slice(0,2));
  1680. }
  1681. let pagecount = 0;
  1682. if(rule.pagecount && typeof(rule.pagecount) === 'object' && rule.pagecount.hasOwnProperty(MY_CATE)){
  1683. print(`MY_CATE:${MY_CATE},pagecount:${JSON.stringify(rule.pagecount)}`);
  1684. pagecount = parseInt(rule.pagecount[MY_CATE]);
  1685. }
  1686. let nodata = {
  1687. list:[{vod_name:'无数据,防无限请求',vod_id:'no_data',vod_remarks:'不要点,会崩的',vod_pic:'https://ghproxy.net/https://raw.githubusercontent.com/hjdhnx/dr_py/main/404.jpg'}],
  1688. total:1,pagecount:1,page:1,limit:1
  1689. };
  1690. let vod = d.length<1?JSON.stringify(nodata):JSON.stringify({
  1691. 'page': parseInt(cateObj.pg),
  1692. 'pagecount': pagecount||999,
  1693. 'limit': 20,
  1694. 'total': 999,
  1695. 'list': d,
  1696. });
  1697. // print(vod);
  1698. return vod
  1699. }
  1700. /**
  1701. * 搜索列表数据解析
  1702. * @param searchObj
  1703. * @returns {string}
  1704. */
  1705. function searchParse(searchObj) {
  1706. fetch_params = JSON.parse(JSON.stringify(rule_fetch_params));
  1707. let d = [];
  1708. if(!searchObj.searchUrl){
  1709. return '{}'
  1710. }
  1711. let p = searchObj.搜索==='*'&&rule.一级 ? rule.一级 : searchObj.搜索;
  1712. if(!p||typeof(p)!=='string'){
  1713. return '{}'
  1714. }
  1715. p = p.trim();
  1716. let pp = rule.一级.split(';');
  1717. let url = searchObj.searchUrl.replaceAll('**', searchObj.wd);
  1718. if(searchObj.pg === 1 && url.includes('[')&&url.includes(']')&&!url.includes('#')){
  1719. url = url.split('[')[1].split(']')[0];
  1720. }else if(searchObj.pg > 1 && url.includes('[')&&url.includes(']')&&!url.includes('#')){
  1721. url = url.split('[')[0];
  1722. }
  1723. if(/fypage/.test(url)){
  1724. if(url.includes('(')&&url.includes(')')){
  1725. let url_rep = url.match(/.*?\((.*)\)/)[1];
  1726. // console.log(url_rep);
  1727. let cnt_page = url_rep.replaceAll('fypage', searchObj.pg);
  1728. // console.log(cnt_page);
  1729. let cnt_pg = eval(cnt_page);
  1730. // console.log(cnt_pg);
  1731. url = url.replaceAll(url_rep,cnt_pg).replaceAll('(','').replaceAll(')','');
  1732. }else{
  1733. url = url.replaceAll('fypage',searchObj.pg);
  1734. }
  1735. }
  1736. MY_URL = url;
  1737. console.log(MY_URL);
  1738. // log(searchObj.搜索);
  1739. // setItem('MY_URL',MY_URL);
  1740. if(p.startsWith('js:')){
  1741. const TYPE = 'search';
  1742. const MY_PAGE = searchObj.pg;
  1743. const KEY = searchObj.wd;
  1744. var input = MY_URL;
  1745. var detailUrl = rule.detailUrl||'';
  1746. eval(p.trim().replace('js:',''));
  1747. d = VODS;
  1748. }else{
  1749. p = p.split(';');
  1750. if (p.length < 5) {
  1751. return '{}'
  1752. }
  1753. let p0 = getPP(p,0,pp,0);
  1754. let _ps = parseTags.getParse(p0);
  1755. _pdfa = _ps.pdfa;
  1756. _pdfh = _ps.pdfh;
  1757. _pd = _ps.pd;
  1758. let is_json = p0.startsWith('json:');
  1759. p0 = p0.replace(/^(jsp:|json:|jq:)/,'');
  1760. // print('1381 p0:'+p0);
  1761. try {
  1762. let req_method = MY_URL.split(';').length>1?MY_URL.split(';')[1].toLowerCase():'get';
  1763. let html;
  1764. if(req_method==='post'){
  1765. let rurls = MY_URL.split(';')[0].split('#')
  1766. let rurl = rurls[0]
  1767. let params = rurls.length > 1 ?rurls[1]:'';
  1768. print(`post=》rurl:${rurl},params:${params}`);
  1769. // let new_dict = {};
  1770. // let new_tmp = params.split('&');
  1771. // new_tmp.forEach(i=>{
  1772. // new_dict[i.split('=')[0]] = i.split('=')[1];
  1773. // });
  1774. // html = post(rurl,{body:new_dict});
  1775. let _fetch_params = JSON.parse(JSON.stringify(rule_fetch_params));
  1776. let postData = {body:params};
  1777. Object.assign(_fetch_params,postData);
  1778. html = post(rurl,_fetch_params);
  1779. }else if(req_method==='postjson'){
  1780. let rurls = MY_URL.split(';')[0].split('#')
  1781. let rurl = rurls[0]
  1782. let params = rurls.length > 1 ?rurls[1]:'';
  1783. print(`postjson-》rurl:${rurl},params:${params}`);
  1784. try{
  1785. params = JSON.parse(params);
  1786. }catch (e) {
  1787. params = '{}'
  1788. }
  1789. let _fetch_params = JSON.parse(JSON.stringify(rule_fetch_params));
  1790. let postData = {body:params};
  1791. Object.assign(_fetch_params,postData);
  1792. html = post(rurl,_fetch_params);
  1793. }else{
  1794. html = getHtml(MY_URL);
  1795. }
  1796. if (html) {
  1797. if(/系统安全验证|输入验证码/.test(html)){
  1798. let cookie = verifyCode(MY_URL);
  1799. if(cookie){
  1800. console.log(`本次成功过验证,cookie:${cookie}`);
  1801. setItem(RULE_CK,cookie);
  1802. }else{
  1803. console.log(`本次自动过搜索验证失败,cookie:${cookie}`);
  1804. }
  1805. // obj.headers['Cookie'] = cookie;
  1806. html = getHtml(MY_URL);
  1807. }
  1808. if(!html.includes(searchObj.wd)){
  1809. console.log('搜索结果源码未包含关键字,疑似搜索失败,正为您打印结果源码');
  1810. console.log(html);
  1811. }
  1812. if(is_json){
  1813. // console.log(html);
  1814. html = dealJson(html);
  1815. // console.log(JSON.stringify(html));
  1816. }
  1817. // console.log(html);
  1818. let list = _pdfa(html, p0);
  1819. // print(list.length);
  1820. // print(list);
  1821. let p1 = getPP(p, 1, pp, 1);
  1822. let p2 = getPP(p, 2, pp, 2);
  1823. let p3 = getPP(p, 3, pp, 3);
  1824. let p4 = getPP(p, 4, pp, 4);
  1825. let p5 = getPP(p,5,pp,5);
  1826. list.forEach(it => {
  1827. let links = p4.split('+').map(_p4=>{
  1828. return !rule.detailUrl?_pd(it, _p4,MY_URL):_pdfh(it, _p4)
  1829. });
  1830. let link = links.join('$');
  1831. let content;
  1832. if(p.length > 5 && p[5]){
  1833. content = _pdfh(it, p5);
  1834. }else{
  1835. content = '';
  1836. }
  1837. let vod_id = link;
  1838. let vod_name = _pdfh(it, p1).replace(/\n|\t/g,'').trim();
  1839. let vod_pic = _pd(it, p2,MY_URL);
  1840. if(rule.二级==='*'){
  1841. vod_id = vod_id+'@@'+vod_name+'@@'+vod_pic;
  1842. }
  1843. let ob = {
  1844. 'vod_id': vod_id,
  1845. 'vod_name': vod_name,
  1846. 'vod_pic': vod_pic,
  1847. 'vod_remarks': _pdfh(it, p3).replace(/\n|\t/g,'').trim(),
  1848. 'vod_content': content.replace(/\n|\t/g,'').trim(),
  1849. };
  1850. d.push(ob);
  1851. });
  1852. }
  1853. } catch (e) {
  1854. print('搜索发生错误:'+e.message);
  1855. return '{}'
  1856. }
  1857. }
  1858. if(rule.图片替换 && rule.图片替换.includes('=>')){
  1859. let replace_from = rule.图片替换.split('=>')[0];
  1860. let replace_to = rule.图片替换.split('=>')[1];
  1861. d.forEach(it=>{
  1862. if(it.vod_pic&&it.vod_pic.startsWith('http')){
  1863. it.vod_pic = it.vod_pic.replace(replace_from,replace_to);
  1864. }
  1865. });
  1866. }
  1867. if(rule.图片来源){
  1868. d.forEach(it=>{
  1869. if(it.vod_pic&&it.vod_pic.startsWith('http')){
  1870. it.vod_pic = it.vod_pic + rule.图片来源;
  1871. }
  1872. });
  1873. }
  1874. // print(d);
  1875. return JSON.stringify({
  1876. 'page': parseInt(searchObj.pg),
  1877. 'pagecount': 10,
  1878. 'limit': 20,
  1879. 'total': 100,
  1880. 'list': d,
  1881. });
  1882. }
  1883. /**
  1884. * 二级详情页数据解析
  1885. * @param detailObj
  1886. * @returns {string}
  1887. */
  1888. function detailParse(detailObj){
  1889. let t1 = (new Date()).getTime();
  1890. fetch_params = JSON.parse(JSON.stringify(rule_fetch_params));
  1891. let orId = detailObj.orId;
  1892. let vod_name = '片名';
  1893. let vod_pic = '';
  1894. let vod_id = orId;
  1895. if(rule.二级==='*'){
  1896. // vod_id = orId.split('@@')[0]; // 千万不能分割
  1897. let extra = orId.split('@@');
  1898. vod_name = extra.length>1?extra[1]:vod_name;
  1899. vod_pic = extra.length>2?extra[2]:vod_pic;
  1900. }
  1901. // print(vod_pic);
  1902. let vod = {
  1903. vod_id: vod_id, //"id",
  1904. vod_name: vod_name,
  1905. vod_pic: vod_pic,
  1906. type_name: "类型",
  1907. vod_year: "年份",
  1908. vod_area: "地区",
  1909. vod_remarks: "更新信息",
  1910. vod_actor: "主演",
  1911. vod_director: "导演",
  1912. vod_content: "简介"
  1913. };
  1914. let p = detailObj.二级;
  1915. let url = detailObj.url;
  1916. let detailUrl = detailObj.detailUrl;
  1917. let fyclass = detailObj.fyclass;
  1918. let tab_exclude = detailObj.tab_exclude;
  1919. let html = detailObj.html||'';
  1920. MY_URL = url;
  1921. if(detailObj.二级访问前){
  1922. try {
  1923. print(`尝试在二级访问前执行代码:${detailObj.二级访问前}`);
  1924. eval(detailObj.二级访问前.trim().replace('js:',''));
  1925. }catch (e) {
  1926. print(`二级访问前执行代码出现错误:${e.message}`)
  1927. }
  1928. }
  1929. // console.log(MY_URL);
  1930. // setItem('MY_URL',MY_URL);
  1931. if(p==='*'){
  1932. vod.vod_play_from = '道长在线';
  1933. vod.vod_remarks = detailUrl;
  1934. vod.vod_actor = '没有二级,只有一级链接直接嗅探播放';
  1935. vod.vod_content = MY_URL;
  1936. vod.vod_play_url = '嗅探播放$' + MY_URL.split('@@')[0];
  1937. }else if(typeof(p)==='string'&&p.trim().startsWith('js:')){
  1938. const TYPE = 'detail';
  1939. var input = MY_URL;
  1940. var play_url = '';
  1941. eval(p.trim().replace('js:',''));
  1942. vod = VOD;
  1943. console.log(JSON.stringify(vod));
  1944. }else if(p&&typeof(p)==='object'){
  1945. let tt1 = (new Date()).getTime();
  1946. if(!html){
  1947. html = getHtml(MY_URL);
  1948. }
  1949. print(`二级${MY_URL}仅获取源码耗时:${(new Date()).getTime()-tt1}毫秒`);
  1950. let _ps;
  1951. if(p.is_json){
  1952. print('二级是json');
  1953. _ps = parseTags.json;
  1954. html = dealJson(html);
  1955. }else if(p.is_jsp){
  1956. print('二级是jsp');
  1957. _ps = parseTags.jsp;
  1958. }else if(p.is_jq){
  1959. print('二级是jq');
  1960. _ps = parseTags.jq;
  1961. }else{
  1962. print('二级默认jq');
  1963. _ps = parseTags.jq;
  1964. // print('二级默认jsp');
  1965. // _ps = parseTags.jsp;
  1966. }
  1967. let tt2 = (new Date()).getTime();
  1968. print(`二级${MY_URL}获取并装载源码耗时:${tt2-tt1}毫秒`);
  1969. _pdfa = _ps.pdfa;
  1970. _pdfh = _ps.pdfh;
  1971. _pd = _ps.pd;
  1972. if(p.title){
  1973. let p1 = p.title.split(';');
  1974. vod.vod_name = _pdfh(html, p1[0]).replace(/\n|\t/g,'').trim();
  1975. let type_name = p1.length > 1 ? _pdfh(html, p1[1]).replace(/\n|\t/g,'').replace(/ /g,'').trim():'';
  1976. vod.type_name = type_name||vod.type_name;
  1977. }
  1978. if(p.desc){
  1979. try{
  1980. let p1 = p.desc.split(';');
  1981. vod.vod_remarks = _pdfh(html, p1[0]).replace(/\n|\t/g,'').trim();
  1982. vod.vod_year = p1.length > 1 ? _pdfh(html, p1[1]).replace(/\n|\t/g,'').trim():'';
  1983. vod.vod_area = p1.length > 2 ? _pdfh(html, p1[2]).replace(/\n|\t/g,'').trim():'';
  1984. // vod.vod_actor = p1.length > 3 ? _pdfh(html, p1[3]).replaceAll('\n', ' ').trim():'';
  1985. vod.vod_actor = p1.length > 3 ? _pdfh(html, p1[3]).replace(/\n|\t/g,'').trim():'';
  1986. vod.vod_director = p1.length > 4 ? _pdfh(html, p1[4]).replace(/\n|\t/g,'').trim():'';
  1987. }
  1988. catch (e) {
  1989. }
  1990. }
  1991. if(p.content){
  1992. try{
  1993. let p1 = p.content.split(';');
  1994. vod.vod_content = _pdfh(html, p1[0]).replace(/\n|\t/g,'').trim();
  1995. }
  1996. catch (e) {}
  1997. }
  1998. if(p.img){
  1999. try{
  2000. let p1 = p.img.split(';');
  2001. vod.vod_pic = _pd(html, p1[0],MY_URL);
  2002. }
  2003. catch (e) {}
  2004. }
  2005. let vod_play_from = '$$$';
  2006. let playFrom = [];
  2007. if(p.重定向&&p.重定向.startsWith('js:')){
  2008. print('开始执行重定向代码:'+p.重定向);
  2009. html = eval(p.重定向.replace('js:',''));
  2010. }
  2011. // console.log(2);
  2012. if(p.tabs){
  2013. if(p.tabs.startsWith('js:')){
  2014. print('开始执行tabs代码:'+p.tabs);
  2015. var input = MY_URL;
  2016. eval(p.tabs.replace('js:',''));
  2017. playFrom = TABS;
  2018. }else{
  2019. let p_tab = p.tabs.split(';')[0];
  2020. // console.log(p_tab);
  2021. let vHeader = _pdfa(html, p_tab);
  2022. console.log(vHeader.length);
  2023. let tab_text = p.tab_text||'body&&Text';
  2024. // print('tab_text:'+tab_text);
  2025. let new_map = {};
  2026. for(let v of vHeader){
  2027. let v_title = _pdfh(v,tab_text).trim();
  2028. if(!v_title){
  2029. v_title = '线路空'
  2030. }
  2031. console.log(v_title);
  2032. if(tab_exclude&& (new RegExp(tab_exclude)).test(v_title)){
  2033. continue;
  2034. }
  2035. if(!new_map.hasOwnProperty(v_title)){
  2036. new_map[v_title] = 1;
  2037. }else{
  2038. new_map[v_title] += 1;
  2039. }
  2040. if(new_map[v_title]>1){
  2041. v_title+=Number(new_map[v_title]-1);
  2042. }
  2043. playFrom.push(v_title);
  2044. }
  2045. }
  2046. console.log(JSON.stringify(playFrom));
  2047. }else{
  2048. playFrom = ['道长在线']
  2049. }
  2050. vod.vod_play_from = playFrom.join(vod_play_from);
  2051. // console.log(3);
  2052. let vod_play_url = '$$$';
  2053. let vod_tab_list = [];
  2054. if(p.lists){
  2055. if(p.lists.startsWith('js:')){
  2056. print('开始执行lists代码:'+p.lists);
  2057. try {
  2058. var input = MY_URL;
  2059. var play_url = '';
  2060. eval(p.lists.replace('js:',''));
  2061. for(let i in LISTS){
  2062. if(LISTS.hasOwnProperty(i)){
  2063. // print(i);
  2064. try {
  2065. LISTS[i] = LISTS[i].map(it=>it.split('$').slice(0,2).join('$'));
  2066. }catch (e) {
  2067. print('格式化LISTS发生错误:'+e.message);
  2068. }
  2069. }
  2070. }
  2071. vod_play_url = LISTS.map(it=>it.join('#')).join(vod_play_url);
  2072. }catch (e) {
  2073. print('js执行lists: 发生错误:'+e.message);
  2074. }
  2075. }else{
  2076. let list_text = p.list_text||'body&&Text';
  2077. let list_url = p.list_url||'a&&href';
  2078. // print('list_text:'+list_text);
  2079. // print('list_url:'+list_url);
  2080. // print('list_parse:'+p.lists);
  2081. let is_tab_js = p.tabs.trim().startsWith('js:');
  2082. for(let i=0;i<playFrom.length;i++){
  2083. let tab_name = playFrom[i];
  2084. let tab_ext = p.tabs.split(';').length > 1 && !is_tab_js ? p.tabs.split(';')[1] : '';
  2085. let p1 = p.lists.replaceAll('#idv', tab_name).replaceAll('#id', i);
  2086. tab_ext = tab_ext.replaceAll('#idv', tab_name).replaceAll('#id', i);
  2087. let tabName = tab_ext?_pdfh(html, tab_ext):tab_name;
  2088. console.log(tabName);
  2089. // print('tab_ext:'+tab_ext);
  2090. let new_vod_list = [];
  2091. let tt1 = (new Date()).getTime();
  2092. // print('pdfl:'+typeof (pdfl));
  2093. if(typeof (pdfl) ==='function'){
  2094. new_vod_list = pdfl(html, p1, list_text, list_url, MY_URL);
  2095. }else {
  2096. let vodList = [];
  2097. try {
  2098. vodList = _pdfa(html, p1);
  2099. console.log('len(vodList):'+vodList.length);
  2100. }catch (e) {
  2101. // console.log(e.message);
  2102. }
  2103. for (let i = 0; i < vodList.length; i++) {
  2104. let it = vodList[i];
  2105. new_vod_list.push(_pdfh(it, list_text).trim() + '$' + _pd(it, list_url, MY_URL));
  2106. }
  2107. }
  2108. if(new_vod_list.length>0){
  2109. new_vod_list = forceOrder(new_vod_list,'',x=>x.split('$')[0]);
  2110. console.log(`drpy影响性能代码共计列表数循环次数:${new_vod_list.length},耗时:${(new Date()).getTime()-tt1}毫秒`);
  2111. }
  2112. // print(new_vod_list);
  2113. let vlist = new_vod_list.join('#');
  2114. vod_tab_list.push(vlist);
  2115. }
  2116. vod_play_url = vod_tab_list.join(vod_play_url);
  2117. }
  2118. }
  2119. vod.vod_play_url = vod_play_url;
  2120. }
  2121. if(rule.图片替换 && rule.图片替换.includes('=>')){
  2122. let replace_from = rule.图片替换.split('=>')[0];
  2123. let replace_to = rule.图片替换.split('=>')[1];
  2124. vod.vod_pic = vod.vod_pic.replace(replace_from,replace_to);
  2125. }
  2126. if(rule.图片来源 && vod.vod_pic && vod.vod_pic.startsWith('http')){
  2127. vod.vod_pic = vod.vod_pic + rule.图片来源;
  2128. }
  2129. if(!vod.vod_id||(vod_id.includes('$')&&vod.vod_id!==vod_id)){
  2130. vod.vod_id = vod_id;
  2131. }
  2132. let t2 = (new Date()).getTime();
  2133. console.log(`加载二级界面${MY_URL}耗时:${t2-t1}毫秒`);
  2134. // print(vod);
  2135. vod = vodDeal(vod);
  2136. // print(vod);
  2137. return JSON.stringify({
  2138. list: [vod]
  2139. })
  2140. }
  2141. /**
  2142. * 获取二级待返回的播放线路没处理时的索引关系
  2143. * @param vod
  2144. * @returns {{}}
  2145. */
  2146. function get_tab_index(vod){
  2147. let obj = {};
  2148. vod.vod_play_from.split('$$$').forEach((it,index)=>{
  2149. obj[it] = index;
  2150. });
  2151. return obj
  2152. }
  2153. /**
  2154. * 处理待返回的vod数据|线路去除,排序,重命名
  2155. * @param vod
  2156. * @returns {*}
  2157. */
  2158. function vodDeal(vod){
  2159. let vod_play_from = vod.vod_play_from.split('$$$');
  2160. let vod_play_url = vod.vod_play_url.split('$$$');
  2161. // 移除指定线路后的列表
  2162. let tab_removed_list = vod_play_from;
  2163. // 排序后的线路列表
  2164. let tab_ordered_list = vod_play_from;
  2165. // 线路重命名后的列表
  2166. let tab_renamed_list = vod_play_from;
  2167. // 定义实际要返回线路
  2168. let tab_list = vod_play_from;
  2169. // 选集列表根据线路排序
  2170. let play_ordered_list = vod_play_url;
  2171. // 判断有移除线路或者线路排序
  2172. if((rule.tab_remove&&rule.tab_remove.length>0)||(rule.tab_order&&rule.tab_order.length>0)){
  2173. // 获取原来线路的索引下标
  2174. let tab_index_dict = get_tab_index(vod);
  2175. if(rule.tab_remove&&rule.tab_remove.length>0){
  2176. tab_removed_list = vod_play_from.filter(it=>!rule.tab_remove.includes(it));
  2177. tab_list = tab_removed_list;
  2178. }
  2179. if(rule.tab_order&&rule.tab_order.length>0){
  2180. let tab_order = rule.tab_order;
  2181. tab_ordered_list = tab_removed_list.sort((a, b) => {
  2182. return (tab_order.indexOf(a)===-1?9999:tab_order.indexOf(a)) - (tab_order.indexOf(b)===-1?9999:tab_order.indexOf(b))
  2183. });
  2184. tab_list = tab_ordered_list;
  2185. }
  2186. play_ordered_list = tab_list.map(it=>vod_play_url[tab_index_dict[it]]);
  2187. }
  2188. if(rule.tab_rename&&typeof(rule.tab_rename)==='object'&Object.keys(rule.tab_rename).length>0){
  2189. tab_renamed_list = tab_list.map(it=>rule.tab_rename[it]||it);
  2190. tab_list = tab_renamed_list;
  2191. }
  2192. vod.vod_play_from = tab_list.join('$$$');
  2193. vod.vod_play_url = play_ordered_list.join('$$$');
  2194. return vod
  2195. }
  2196. /**
  2197. * 判断是否需要解析
  2198. * @param url
  2199. * @returns {number|number}
  2200. */
  2201. function tellIsJx(url){
  2202. try {
  2203. let is_vip = !/\.(m3u8|mp4|m4a)$/.test(url.split('?')[0]) && 是否正版(url);
  2204. return is_vip?1:0
  2205. }catch (e) {
  2206. return 1
  2207. }
  2208. }
  2209. /**
  2210. * 选集播放点击事件解析
  2211. * @param playObj
  2212. * @returns {string}
  2213. */
  2214. function playParse(playObj){
  2215. fetch_params = JSON.parse(JSON.stringify(rule_fetch_params));
  2216. MY_URL = playObj.url;
  2217. var MY_FLAG = playObj.flag;
  2218. if(!/http/.test(MY_URL)){
  2219. try {
  2220. MY_URL = base64Decode(MY_URL);
  2221. }catch (e) {}
  2222. }
  2223. MY_URL = decodeURIComponent(MY_URL);
  2224. var input = MY_URL;//注入给免嗅js
  2225. var flag = MY_FLAG;//注入播放线路名称给免嗅js
  2226. let common_play = {
  2227. parse:1,
  2228. url:input,
  2229. flag:flag,
  2230. // url:urlencode(input),
  2231. jx:tellIsJx(input)
  2232. };
  2233. let lazy_play;
  2234. if(!rule.play_parse||!rule.lazy){
  2235. lazy_play = common_play;
  2236. }else if(rule.play_parse&&rule.lazy&&typeof(rule.lazy)==='string'){
  2237. try {
  2238. let lazy_code = rule.lazy.replace('js:','').trim();
  2239. print('开始执行js免嗅=>'+lazy_code);
  2240. eval(lazy_code);
  2241. lazy_play = typeof(input) === 'object'?input:{
  2242. parse:1,
  2243. jx:tellIsJx(input),
  2244. url:input
  2245. };
  2246. }catch (e) {
  2247. print('js免嗅错误:'+e.message);
  2248. lazy_play = common_play;
  2249. }
  2250. }else{
  2251. lazy_play = common_play;
  2252. }
  2253. // print('play_json:'+typeof(rule.play_json));
  2254. // console.log(Array.isArray(rule.play_json));
  2255. if(Array.isArray(rule.play_json) && rule.play_json.length >0){ // 数组情况判断长度大于0
  2256. let web_url = lazy_play.url;
  2257. for(let pjson of rule.play_json){
  2258. if(pjson.re && (pjson.re==='*'||web_url.match(new RegExp(pjson.re)))){
  2259. if(pjson.json && typeof(pjson.json)==='object'){
  2260. let base_json = pjson.json;
  2261. // print('开始合并:');
  2262. // print(base_json);
  2263. lazy_play = Object.assign(lazy_play,base_json);
  2264. break;
  2265. }
  2266. }
  2267. }
  2268. }else if(rule.play_json && !Array.isArray(rule.play_json)){ // 其他情况 非[] 判断true/false
  2269. let base_json = {
  2270. jx:1,
  2271. parse:1,
  2272. };
  2273. lazy_play = Object.assign(lazy_play,base_json);
  2274. }else if(!rule.play_json){ // 不解析传0
  2275. let base_json = {
  2276. jx:0,
  2277. parse:1,
  2278. };
  2279. lazy_play = Object.assign(lazy_play,base_json);
  2280. }
  2281. console.log(JSON.stringify(lazy_play));
  2282. return JSON.stringify(lazy_play);
  2283. }
  2284. /**
  2285. * 本地代理解析规则
  2286. * @param params
  2287. */
  2288. function proxyParse(proxyObj){
  2289. var input = proxyObj.params;
  2290. if(proxyObj.proxy_rule){
  2291. log('准备执行本地代理规则:\n'+proxyObj.proxy_rule);
  2292. try {
  2293. eval(proxyObj.proxy_rule);
  2294. if(input && input!== proxyObj.params && Array.isArray(input) &&input.length===3){
  2295. return input
  2296. }else{
  2297. return [404,'text/plain','Not Found']
  2298. }
  2299. }catch (e) {
  2300. return [500,'text/plain','代理规则错误:'+e.message]
  2301. }
  2302. }else{
  2303. return [404,'text/plain','Not Found']
  2304. }
  2305. }
  2306. /**
  2307. * 辅助嗅探解析规则
  2308. * @param isVideoObj
  2309. * @returns {boolean}
  2310. */
  2311. function isVideoParse(isVideoObj){
  2312. var input = isVideoObj.url;
  2313. if(!isVideoObj.t){ // t为假代表默认传的正则字符串
  2314. let re_matcher = new RegExp(isVideoObj.isVideo,'i'); // /g匹配多个,/i不区分大小写,/m匹配多行
  2315. return re_matcher.test(input);
  2316. }else{
  2317. // 执行js
  2318. try {
  2319. eval(isVideoObj.isVideo);
  2320. if(typeof(input)==='boolean'){
  2321. return input
  2322. }else{
  2323. return false
  2324. }
  2325. }catch (e) {
  2326. log('执行嗅探规则发生错误:'+e.message);
  2327. return false
  2328. }
  2329. }
  2330. }
  2331. /**
  2332. * js源预处理特定返回对象中的函数
  2333. * @param ext
  2334. */
  2335. function init(ext) {
  2336. console.log('init');
  2337. try {
  2338. // make shared jsContext happy muban不能import,不然会造成换源继承后变量被篡改
  2339. // if (typeof (globalThis.mubanJs) === 'undefined') {
  2340. // let mubanJs = request('https://ghproxy.net/https://raw.githubusercontent.com/hjdhnx/dr_py/main/js/模板.js', { 'User-Agent': MOBILE_UA });
  2341. // mubanJs = mubanJs.replace('export default', '(function() {return muban;}()) // export default');
  2342. // // console.log(mubanJs);
  2343. // globalThis.mubanJs = mubanJs;
  2344. // }
  2345. // let muban = eval(globalThis.mubanJs);
  2346. let muban = 模板.getMubans();
  2347. // print(typeof (muban));
  2348. // print(muban);
  2349. if (typeof ext == 'object'){
  2350. rule = ext;
  2351. } else if (typeof ext == 'string') {
  2352. if (ext.startsWith('http')) {
  2353. let js = request(ext,{'method':'GET'});
  2354. if (js){
  2355. eval(js.replace('var rule', 'rule'));
  2356. }
  2357. } else {
  2358. eval(ext.replace('var rule', 'rule'));
  2359. }
  2360. }
  2361. if (rule.模板 && muban.hasOwnProperty(rule.模板)) {
  2362. print('继承模板:'+rule.模板);
  2363. rule = Object.assign(muban[rule.模板], rule);
  2364. }
  2365. /** 处理一下 rule规则关键字段没传递的情况 **/
  2366. let rule_cate_excludes = (rule.cate_exclude||'').split('|').filter(it=>it.trim());
  2367. let rule_tab_excludes = (rule.tab_exclude||'').split('|').filter(it=>it.trim());
  2368. rule_cate_excludes = rule_cate_excludes.concat(CATE_EXCLUDE.split('|').filter(it=>it.trim()));
  2369. rule_tab_excludes = rule_tab_excludes.concat(TAB_EXCLUDE.split('|').filter(it=>it.trim()));
  2370. rule.cate_exclude = rule_cate_excludes.join('|');
  2371. rule.tab_exclude = rule_tab_excludes.join('|');
  2372. rule.host = (rule.host||'').rstrip('/');
  2373. HOST = rule.host;
  2374. if(rule.hostJs){
  2375. console.log(`检测到hostJs,准备执行...`);
  2376. try {
  2377. eval(rule.hostJs);
  2378. rule.host = HOST.rstrip('/');
  2379. }catch (e) {
  2380. console.log(`执行${rule.hostJs}获取host发生错误:`+e.message);
  2381. }
  2382. }
  2383. rule.url = rule.url||'';
  2384. rule.double = rule.double||false;
  2385. rule.homeUrl = rule.homeUrl||'';
  2386. rule.detailUrl = rule.detailUrl||'';
  2387. rule.searchUrl = rule.searchUrl||'';
  2388. rule.homeUrl = rule.host&&rule.homeUrl?urljoin(rule.host,rule.homeUrl):(rule.homeUrl||rule.host);
  2389. rule.homeUrl = cheerio.jinja2(rule.homeUrl,{rule:rule});
  2390. rule.detailUrl = rule.host&&rule.detailUrl?urljoin(rule.host,rule.detailUrl):rule.detailUrl;
  2391. rule.二级访问前 = rule.二级访问前||'';
  2392. if(rule.url.includes('[')&&rule.url.includes(']')){
  2393. let u1 = rule.url.split('[')[0]
  2394. let u2 = rule.url.split('[')[1].split(']')[0]
  2395. rule.url = rule.host && rule.url?urljoin(rule.host,u1)+'['+urljoin(rule.host,u2)+']':rule.url;
  2396. }else{
  2397. rule.url = rule.host && rule.url ? urljoin(rule.host,rule.url) : rule.url;
  2398. }
  2399. if(rule.searchUrl.includes('[')&&rule.searchUrl.includes(']')&&!rule.searchUrl.includes('#')){
  2400. let u1 = rule.searchUrl.split('[')[0]
  2401. let u2 = rule.searchUrl.split('[')[1].split(']')[0]
  2402. rule.searchUrl = rule.host && rule.searchUrl?urljoin(rule.host,u1)+'['+urljoin(rule.host,u2)+']':rule.searchUrl;
  2403. }else{
  2404. rule.searchUrl = rule.host && rule.searchUrl ? urljoin(rule.host,rule.searchUrl) : rule.searchUrl;
  2405. }
  2406. rule.timeout = rule.timeout||5000;
  2407. rule.encoding = rule.编码||rule.encoding||'utf-8';
  2408. rule.search_encoding = rule.搜索编码||rule.search_encoding||'';
  2409. rule.图片来源 = rule.图片来源||'';
  2410. rule.图片替换 = rule.图片替换||'';
  2411. rule.play_json = rule.hasOwnProperty('play_json')?rule.play_json:[];
  2412. rule.pagecount = rule.hasOwnProperty('pagecount')?rule.pagecount:{};
  2413. rule.proxy_rule = rule.hasOwnProperty('proxy_rule')?rule.proxy_rule:'';
  2414. rule.sniffer = rule.hasOwnProperty('sniffer')?rule.sniffer:'';
  2415. rule.sniffer = !!(rule.sniffer && rule.sniffer!=='0' && rule.sniffer!=='false');
  2416. rule.isVideo = rule.hasOwnProperty('isVideo')?rule.isVideo:'';
  2417. rule.tab_remove = rule.hasOwnProperty('tab_remove')?rule.tab_remove:[];
  2418. rule.tab_order = rule.hasOwnProperty('tab_order')?rule.tab_order:[];
  2419. rule.tab_rename = rule.hasOwnProperty('tab_rename')?rule.tab_rename:{};
  2420. if(rule.headers && typeof(rule.headers) === 'object'){
  2421. try {
  2422. let header_keys = Object.keys(rule.headers);
  2423. for(let k of header_keys){
  2424. if(k.toLowerCase() === 'user-agent'){
  2425. let v = rule.headers[k];
  2426. console.log(v);
  2427. if(['MOBILE_UA','PC_UA','UC_UA','IOS_UA','UA'].includes(v)){
  2428. rule.headers[k] = eval(v);
  2429. }
  2430. }else if(k.toLowerCase() === 'cookie'){
  2431. let v = rule.headers[k];
  2432. if(v && v.startsWith('http')){
  2433. console.log(v);
  2434. try {
  2435. v = fetch(v);
  2436. console.log(v);
  2437. rule.headers[k] = v;
  2438. }catch (e) {
  2439. console.log(`从${v}获取cookie发生错误:`+e.message);
  2440. }
  2441. }
  2442. }
  2443. }
  2444. }catch (e) {
  2445. console.log('处理headers发生错误:'+e.message);
  2446. }
  2447. }
  2448. // print(rule.headers);
  2449. rule_fetch_params = {'headers': rule.headers||false, 'timeout': rule.timeout, 'encoding': rule.encoding};
  2450. oheaders = rule.headers||{};
  2451. RKEY = typeof(key)!=='undefined'&&key?key:'drpy_' + (rule.title || rule.host);
  2452. pre(); // 预处理
  2453. init_test();
  2454. }catch (e) {
  2455. console.log('init_test发生错误:'+e.message);
  2456. }
  2457. }
  2458. let homeHtmlCache = undefined;
  2459. /**
  2460. * js源获取首页分类和筛选特定返回对象中的函数
  2461. * @param filter 筛选条件字典对象
  2462. * @returns {string}
  2463. */
  2464. function home(filter) {
  2465. console.log("home");
  2466. let homeObj = {
  2467. filter:rule.filter||false,
  2468. MY_URL: rule.homeUrl,
  2469. class_name: rule.class_name || '',
  2470. class_url: rule.class_url || '',
  2471. class_parse: rule.class_parse || '',
  2472. cate_exclude: rule.cate_exclude,
  2473. };
  2474. return homeParse(homeObj);
  2475. }
  2476. /**
  2477. * js源获取首页推荐数据列表特定返回对象中的函数
  2478. * @param params
  2479. * @returns {string}
  2480. */
  2481. function homeVod(params) {
  2482. console.log("homeVod");
  2483. let homeVodObj = {
  2484. 推荐:rule.推荐,
  2485. double:rule.double,
  2486. homeUrl:rule.homeUrl,
  2487. detailUrl:rule.detailUrl
  2488. };
  2489. return homeVodParse(homeVodObj)
  2490. // return "{}";
  2491. }
  2492. /**
  2493. * js源获取分类页一级数据列表特定返回对象中的函数
  2494. * @param tid 分类id
  2495. * @param pg 页数
  2496. * @param filter 当前选中的筛选条件
  2497. * @param extend 扩展
  2498. * @returns {string}
  2499. */
  2500. function category(tid, pg, filter, extend) {
  2501. let cateObj = {
  2502. url: rule.url,
  2503. 一级: rule.一级,
  2504. tid: tid,
  2505. pg: parseInt(pg),
  2506. filter: filter,
  2507. extend: extend
  2508. };
  2509. // console.log(JSON.stringify(extend));
  2510. return categoryParse(cateObj)
  2511. }
  2512. /**
  2513. * js源获取二级详情页数据特定返回对象中的函数
  2514. * @param vod_url 一级列表中的vod_id或者是带分类的自拼接 vod_id 如 fyclass$vod_id
  2515. * @returns {string}
  2516. */
  2517. function detail(vod_url) {
  2518. let orId = vod_url;
  2519. let fyclass = '';
  2520. log('orId:'+orId);
  2521. if(vod_url.indexOf('$')>-1){
  2522. let tmp = vod_url.split('$');
  2523. fyclass = tmp[0];
  2524. vod_url = tmp[1];
  2525. }
  2526. let detailUrl = vod_url.split('@@')[0];
  2527. let url;
  2528. if(!detailUrl.startsWith('http')&&!detailUrl.includes('/')){
  2529. url = rule.detailUrl.replaceAll('fyid', detailUrl).replaceAll('fyclass',fyclass);
  2530. }else if(detailUrl.includes('/')){
  2531. url = urljoin(rule.homeUrl,detailUrl);
  2532. }else{
  2533. url = detailUrl
  2534. }
  2535. let detailObj = {
  2536. orId: orId,
  2537. url:url,
  2538. 二级:rule.二级,
  2539. 二级访问前:rule.二级访问前,
  2540. detailUrl:detailUrl,
  2541. fyclass:fyclass,
  2542. tab_exclude:rule.tab_exclude,
  2543. }
  2544. return detailParse(detailObj)
  2545. }
  2546. /**
  2547. * js源选集按钮播放点击事件特定返回对象中的函数
  2548. * @param flag 线路名
  2549. * @param id 播放按钮的链接
  2550. * @param flags 全局配置的flags是否需要解析的标识列表
  2551. * @returns {string}
  2552. */
  2553. function play(flag, id, flags) {
  2554. let playObj = {
  2555. url:id,
  2556. flag:flag,
  2557. flags:flags
  2558. }
  2559. return playParse(playObj);
  2560. }
  2561. /**
  2562. * js源搜索返回的数据列表特定返回对象中的函数
  2563. * @param wd 搜索关键字
  2564. * @param quick 是否来自快速搜索
  2565. * @returns {string}
  2566. */
  2567. function search(wd, quick, pg) {
  2568. if(rule.search_encoding){
  2569. if(rule.search_encoding.toLowerCase()!=='utf-8'){
  2570. // 按搜索编码进行编码
  2571. wd = encodeStr(wd,rule.search_encoding);
  2572. }
  2573. }else if(rule.encoding && rule.encoding.toLowerCase()!=='utf-8'){
  2574. // 按全局编码进行编码
  2575. wd = encodeStr(wd,rule.encoding);
  2576. }
  2577. let searchObj = {
  2578. searchUrl: rule.searchUrl,
  2579. 搜索: rule.搜索,
  2580. wd: wd,
  2581. //pg: pg,
  2582. pg: pg||1,
  2583. quick: quick,
  2584. };
  2585. // console.log(JSON.stringify(searchObj));
  2586. return searchParse(searchObj)
  2587. }
  2588. /**
  2589. * js源本地代理返回的数据列表特定返回对象中的函数
  2590. * @param params 代理链接参数比如 /proxy?do=js&url=https://wwww.baidu.com => params就是 {do:'js','url':'https://wwww.baidu.com'}
  2591. * @returns {*}
  2592. */
  2593. function proxy(params){
  2594. if(rule.proxy_rule&&rule.proxy_rule.trim()){
  2595. rule.proxy_rule = rule.proxy_rule.trim();
  2596. }
  2597. if(rule.proxy_rule.startsWith('js:')){
  2598. rule.proxy_rule = rule.proxy_rule.replace('js:','');
  2599. }
  2600. let proxyObj = {
  2601. params:params,
  2602. proxy_rule:rule.proxy_rule
  2603. };
  2604. return proxyParse(proxyObj)
  2605. }
  2606. /**
  2607. * 是否启用辅助嗅探功能,启用后可以根据isVideo函数进行手动识别为视频的链接地址。默认为false
  2608. * @returns {*|boolean|boolean}
  2609. */
  2610. function sniffer(){
  2611. let enable_sniffer = rule.sniffer || false;
  2612. if(enable_sniffer){
  2613. // log('准备执行辅助嗅探代理规则:\n'+rule.isVideo);
  2614. log('开始执行辅助嗅探代理规则...');
  2615. }
  2616. return enable_sniffer
  2617. }
  2618. /**
  2619. * 启用辅助嗅探功能后根据次函数返回的值识别地址是否为视频,返回true/false
  2620. * @param url
  2621. */
  2622. function isVideo(url){
  2623. let t = 0;
  2624. let is_video;
  2625. if(rule.isVideo &&rule.isVideo.trim()){
  2626. is_video = rule.isVideo.trim();
  2627. }
  2628. if(is_video.startsWith('js:')){
  2629. is_video = is_video.replace('js:','');
  2630. t = 1;
  2631. }
  2632. let isVideoObj = {
  2633. url:url,
  2634. isVideo:is_video,
  2635. t:t,
  2636. };
  2637. let result = isVideoParse(isVideoObj);
  2638. if(result){
  2639. log('成功执行辅助嗅探规则并检测到视频地址:\n'+rule.isVideo);
  2640. }
  2641. return result
  2642. }
  2643. function DRPY(){//导出函数
  2644. return {
  2645. init: init,
  2646. home: home,
  2647. homeVod: homeVod,
  2648. category: category,
  2649. detail: detail,
  2650. play: play,
  2651. search: search,
  2652. proxy:proxy,
  2653. sniffer:sniffer,
  2654. isVideo:isVideo
  2655. }
  2656. }
  2657. /**
  2658. * 导出函数无法简写成下面的形式:
  2659. export default {
  2660. ...DRPY,
  2661. DRPY
  2662. }
  2663. */
  2664. // 导出函数对象
  2665. export default {
  2666. init,
  2667. home,
  2668. homeVod,
  2669. category,
  2670. detail,
  2671. play,
  2672. search,
  2673. proxy,
  2674. sniffer,
  2675. isVideo,
  2676. DRPY,
  2677. }