采集静态.json 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. globalThis.getRandomItem = function (items) {return items[Math.random() * items.length | 0];
  2. }
  3. var rule = {
  4. title: '采集之王[合]',
  5. author: '道长',
  6. version: '20240624 beta7',
  7. update_info: `20240604:1.首页推荐取消硬控等待。增加随机推荐功能。2.首页推荐新增更新日志查看功能`,
  8. tab_remove: ['feifan', 'liangzi', 'fsyun', 'hhyun', 'jsyun'],
  9. tab_rename: {'ffm3u8':'🐷非凡','feidaozy':'🐷飞刀','lzm3u8':'🐷量子','hhm3u8':'🐷豪华','jsm3u8':'🐷极速','360zy':'🐷360','heimuer':'🐷黑木耳','hw8':'🐷华为吧','hym3u8':'虎牙','bfzym3u8':'暴风','1080zyk':'优质','kuaikan':'快看','snm3u8':'索尼','gsm3u8':'光速','okm3u8':'OK','leshi':'乐视','tkm3u8':'天空','wjm3u8':'无尽','sdm3u8':'闪电','jinyingm3u8':'金鹰','fsm3u8':'飞速','hnm3u8':'红牛','xlm3u8':'新浪','kcm3u8':'快车','qhm3u8':'奇虎'},
  10. tab_order: ['lzm3u8', 'ffm3u8', 'hhm3u8', 'jsm3u8', 'heimuer', '360zy', 'feidaozy', 'hw8'],
  11. homeTid: '',
  12. homeUrl: '/api.php/provide/vod/?ac=detail&t={{rule.homeTid}}',
  13. detailUrl: '/api.php/provide/vod/?ac=detail&ids=fyid',
  14. searchUrl: '/api.php/provide/vod/?wd=**&pg=#TruePage##page=fypage',
  15. classUrl: '/api.php/provide/vod/',
  16. url: '/api.php/provide/vod/?ac=detail&pg=fypage&t=fyfilter',
  17. filter_url: '{{fl.类型}}',
  18. headers: { 'User-Agent': 'MOBILE_UA' },
  19. timeout: 5000,
  20. search_limit: 6,
  21. play_parse: true,
  22. params: 'http://127.0.0.1:9978/file/jars/采集.json',
  23. 预处理: $js.toString(() => {
  24. function getClasses(item) {
  25. let classes = [];
  26. if (item.class_name && item.class_url) {
  27. if (!/&|电影|电视剧|综艺|动漫[\u4E00-\u9FA5]+/.test(item.class_name)) {
  28. try {
  29. item.class_name = ungzip(item.class_name)
  30. } catch (e) {
  31. log(`不识别的class_name导致gzip解码失败:${e}`)
  32. return classes
  33. }
  34. }
  35. let names = item.class_name.split('&');
  36. let urls = item.class_url.split('&');
  37. let cnt = Math.min(names.length, urls.length);
  38. for (let i = 0; i < cnt; i++) {
  39. classes.push({
  40. 'type_id': urls[i], 'type_name': names[i]
  41. });
  42. }
  43. }
  44. return classes
  45. }
  46. let _url = rule.params;
  47. if (_url && typeof(_url) === 'string' && /^(http|file)/.test(_url)) {
  48. let html = request(_url);
  49. let json = JSON.parse(html);
  50. let _classes = [];
  51. rule.filter = {};
  52. rule.filter_def = {};
  53. json.forEach(it => {
  54. let _obj = {
  55. type_name: it.name,
  56. type_id: it.url,
  57. parse_url: it.parse_url || '',
  58. api: it.api || '',
  59. cate_exclude: it.cate_exclude || '',
  60. };
  61. _classes.push(_obj);
  62. try {
  63. let json1 = [];
  64. if (it.class_name && it.class_url) {
  65. json1 = getClasses(it);
  66. } else {
  67. json1 = JSON.parse(request(urljoin(_obj.type_id, _obj.api || rule.classUrl))).class;
  68. }
  69. if (_obj.cate_exclude) {
  70. json1 = json1.filter(cl => !new RegExp(_obj.cate_exclude, 'i').test(cl.type_name));
  71. }
  72. rule.filter[_obj.type_id] = [{
  73. "key": "类型", "name": "类型", "value": json1.map(i => {
  74. return {
  75. "n": i.type_name, 'v': i.type_id
  76. }
  77. })
  78. }];
  79. if (json1.length > 0) {
  80. rule.filter_def[it.url] = {
  81. "类型": json1[0].type_id
  82. };
  83. }
  84. } catch (e) {
  85. rule.filter[it.url] = [{ "key": "类型", "name": "类型", "value": [{
  86. "n": "全部", "v": ""
  87. }]
  88. }];
  89. }
  90. });
  91. rule.classes = _classes;
  92. }
  93. }),
  94. class_parse: $js.toString(() => {
  95. input = rule.classes;
  96. }),
  97. 推荐: $js.toString(() => {
  98. let update_info = [{
  99. vod_name: '更新日志',
  100. vod_id: 'update_info',
  101. vod_remarks: `版本:${rule.version}`,
  102. vod_pic: 'https://ghproxy.net/https://raw.githubusercontent.com/hjdhnx/hipy-server/master/app/static/img/logo.png'
  103. }];
  104. VODS = [];
  105. if (rule.classes) {
  106. let randomClass = getRandomItem(rule.classes);
  107. let _url = urljoin(randomClass.type_id, input);
  108. if (randomClass.api) {
  109. _url = _url.replace('/api.php/provide/vod/', randomClass.api)
  110. }
  111. try {
  112. let html = request(_url, {timeout: rule.timeout});
  113. let json = JSON.parse(html);
  114. VODS = json.list;
  115. VODS.forEach(it => {
  116. it.vod_id = randomClass.type_id + '$' + it.vod_id;
  117. it.vod_remarks = it.vod_remarks + '|' + randomClass.type_name;
  118. });
  119. } catch (e) {
  120. }
  121. }
  122. VODS = update_info.concat(VODS);
  123. }),
  124. 一级: $js.toString(() => {
  125. VODS = [];
  126. if (rule.classes) {
  127. // log(input);
  128. let _url = urljoin(MY_CATE, input);
  129. let current_vod = rule.classes.find(item => item.type_id === MY_CATE);
  130. if (current_vod && current_vod.api) {
  131. _url = _url.replace('/api.php/provide/vod/', current_vod.api)
  132. }
  133. let html = request(_url);
  134. let json = JSON.parse(html);
  135. VODS = json.list;
  136. VODS.forEach(it => {
  137. it.vod_id = MY_CATE + '$' + it.vod_id
  138. });
  139. }
  140. }),
  141. 二级: $js.toString(() => {
  142. VOD = {};
  143. if (orId === 'update_info') {
  144. VOD = {
  145. vod_content: rule.update_info.trim(),
  146. vod_name: '更新日志',
  147. type_name: '更新日志',
  148. vod_pic: 'https://img1.doubanio.com/view/photo/m/public/p2455175550.webp',
  149. vod_remarks: `版本:${rule.version}`,
  150. vod_play_from: '道长在线',
  151. vod_play_url: '六点半$https://mvvideo10.meitudata.com/645b73b6bdacajyaroszrz3280_H264_1_623e5a7cbad9cc.mp4'
  152. };
  153. } else {
  154. if (rule.classes) {
  155. let _url = urljoin(fyclass, input);
  156. let current_vod = rule.classes.find(item => item.type_id === fyclass);
  157. if (current_vod && current_vod.api) {
  158. _url = _url.replace('/api.php/provide/vod/', current_vod.api)
  159. }
  160. let html = request(_url);
  161. let json = JSON.parse(html);
  162. let data = json.list;
  163. VOD = data[0];
  164. if (current_vod && current_vod.type_name) {
  165. VOD.vod_play_from = VOD.vod_play_from.split('$$$').map(it => it).join('$$$')
  166. }}}
  167. }),
  168. 搜索: $js.toString(() => {
  169. VODS = [];
  170. if (rule.classes) {
  171. let page = Number(MY_PAGE);
  172. page = (MY_PAGE - 1) % Math.ceil(rule.classes.length / rule.search_limit) + 1;
  173. let truePage = Math.ceil(MY_PAGE / Math.ceil(rule.classes.length / rule.search_limit));
  174. if (rule.search_limit) {
  175. let start = (page - 1) * rule.search_limit;
  176. let end = page * rule.search_limit;
  177. let t1 = new Date().getTime();
  178. log('start:' + start);
  179. log('end:' + end);
  180. if (start < rule.classes.length) {
  181. let search_classes = rule.classes.slice(start, end);
  182. let urls = [];
  183. search_classes.forEach(it => {
  184. let _url = urljoin(it.type_id, input);
  185. if (it.api) {
  186. _url = _url.replace('/api.php/provide/vod/', it.api)
  187. }
  188. _url = _url.replace("#TruePage#", "" + truePage);
  189. urls.push(_url);
  190. });
  191. let results = [];
  192. if (typeof (batchFetch) === 'function') {
  193. let reqUrls = urls.map(it => {
  194. return {
  195. url: it,
  196. options: {timeout: rule.timeout}
  197. }
  198. });
  199. let rets = batchFetch(reqUrls);
  200. rets.forEach((ret, idx) => {
  201. let it = search_classes[idx];
  202. if (ret) {
  203. try {
  204. let json = JSON.parse(ret);
  205. let data = json.list.filter(it => it.type_name !== '伦理片');
  206. data.forEach(i => {
  207. i.vod_id = it.type_id + '$' + i.vod_id;
  208. i.vod_remarks = i.vod_remarks + '✰' + it.type_name;
  209. });
  210. results = results.concat(data);
  211. } catch (e) {
  212. log(`请求:${it.type_id}发生错误:${e.message}`)
  213. }
  214. }
  215. });
  216. } else if (typeof (multiReq) === 'function') {
  217. let reqUrls = urls.map(it => {
  218. return {
  219. url:it,
  220. data:{
  221. method:'GET',
  222. headers: rule.headers,
  223. timeout: rule.timeout,
  224. buffer: 0
  225. }
  226. }
  227. });
  228. let rets = JSON.parse(multiReq(reqUrls));
  229. rets.forEach((ret, idx) => {
  230. let it = search_classes[idx];
  231. if (ret) {
  232. try {
  233. let json = JSON.parse(ret.content);
  234. let data = json.list.filter(it => it.type_name !== '伦理片');
  235. data.forEach(i => {
  236. i.vod_id = it.type_id + '$' + i.vod_id;
  237. i.vod_remarks = i.vod_remarks + '✰' + it.type_name;
  238. });
  239. results = results.concat(data);
  240. } catch (e) {
  241. log(`请求:${it.type_id}发生错误:${e.message}`)
  242. }
  243. }
  244. });
  245. } else {
  246. urls.forEach((_url, idx) => {
  247. let it = search_classes[idx];
  248. try {
  249. let html = request(_url);
  250. let json = JSON.parse(html);
  251. let data = json.list.filter(it => it.type_name !== '伦理片');
  252. data.forEach(i => {
  253. i.vod_id = it.type_id + '$' + i.vod_id;
  254. i.vod_remarks = i.vod_remarks + '✰' + it.type_name;
  255. });
  256. results = results.concat(data);
  257. } catch (e) {
  258. log(`请求:${it.type_id}发生错误:${e.message}`)
  259. }
  260. });
  261. }
  262. VODS = results;
  263. let t2 = new Date().getTime();
  264. log(`✰搜索:${urls.length}个站耗时:${(Number(t2) - Number(t1))}ms`)
  265. }
  266. }
  267. }
  268. }),
  269. lazy: $js.toString(() => {
  270. let parse_url = '';
  271. if (flag && flag.includes('|')) {
  272. let type_name = flag.split('|')[0];
  273. let current_vod = rule.classes.find(item => item.type_name === type_name);
  274. if (current_vod && current_vod.parse_url) {
  275. parse_url = current_vod.parse_url
  276. }
  277. }
  278. if (/\.(m3u8|mp4)/.test(input)) {
  279. input = {
  280. parse: 0,
  281. url: input
  282. }
  283. } else {
  284. if (parse_url.startsWith('json:')) {
  285. let purl = parse_url.replace('json:', '') + input;
  286. let html = request(purl);
  287. input = {
  288. parse: 0,
  289. url: JSON.parse(html).url
  290. }
  291. } else {
  292. input = parse_url + input;
  293. }
  294. }
  295. }),
  296. }