ikanbot.js 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. import { Crypto, load, _ } from './lib/cat.js';
  2. let key = 'ikanbot';
  3. let url = 'https://www.ikanbot.com';
  4. let siteKey = '';
  5. let siteType = 0;
  6. const 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';
  7. async function request(reqUrl, agentSp) {
  8. let res = await req(reqUrl, {
  9. method: 'get',
  10. headers: {
  11. 'User-Agent': agentSp || UA,
  12. 'referer': url
  13. },
  14. });
  15. return res.content;
  16. }
  17. // cfg = {skey: siteKey, ext: extend}
  18. async function init(cfg) {
  19. siteKey = cfg.skey;
  20. siteType = cfg.stype;
  21. }
  22. function getClass($) {
  23. const nav = $('ul.nav-pills:eq(1) > li > a');
  24. let tags = {
  25. key: 'tag',
  26. name: '标签',
  27. value: _.map(nav, (n) => {
  28. return { n: n.children[0].data, v: n.attribs.href };
  29. }),
  30. };
  31. tags['init'] = tags.value[0].v;
  32. const title = $('title:first').text().split('-')[0].substring(2);
  33. return { cls: { type_id: tags.value[0].v, type_name: title }, tags: [tags] };
  34. }
  35. async function home(filter) {
  36. let classes = [];
  37. let filterObj = {};
  38. for (const cate of ['/hot/index-movie-热门.html', '/hot/index-tv-热门.html']) {
  39. const html = await request(url + cate);
  40. const $ = load(html);
  41. const { cls, tags } = getClass($);
  42. classes.push(cls);
  43. filterObj[cls.type_id] = tags;
  44. }
  45. return JSON.stringify({
  46. class: classes,
  47. filters: filterObj,
  48. });
  49. }
  50. async function homeVod() {
  51. const html = await request(url);
  52. const $ = load(html);
  53. const items = $('div.v-list a.item');
  54. var jsBase = await js2Proxy(true, siteType, siteKey, 'img/', {});
  55. let videos = _.map(items, (item) => {
  56. const img = $(item).find('img:first')[0];
  57. return {
  58. vod_id: item.attribs.href,
  59. vod_name: img.attribs.alt,
  60. vod_pic: jsBase + base64Encode(img.attribs['data-src']),
  61. vod_remarks: '',
  62. };
  63. });
  64. return JSON.stringify({
  65. list: videos,
  66. });
  67. }
  68. async function category(tid, pg, filter, extend) {
  69. if (pg <= 0) pg = 1;
  70. const link = url + (extend.tag || tid).replace('.html', pg > 1 ? `-p-${pg}.html` : '.html');
  71. const html = await request(link);
  72. const $ = load(html);
  73. const items = $('div.v-list a.item');
  74. var jsBase = await js2Proxy(true, siteType, siteKey, 'img/', {});
  75. let videos = _.map(items, (item) => {
  76. const img = $(item).find('img:first')[0];
  77. return {
  78. vod_id: item.attribs.href,
  79. vod_name: img.attribs.alt,
  80. vod_pic: jsBase + base64Encode(img.attribs['data-src']),
  81. vod_remarks: '',
  82. };
  83. });
  84. const hasMore = $('div.page-more > a:contains(下一页)').length > 0;
  85. const pgCount = hasMore ? parseInt(pg) + 1 : parseInt(pg);
  86. return JSON.stringify({
  87. page: parseInt(pg),
  88. pagecount: pgCount,
  89. limit: 24,
  90. total: 24 * pgCount,
  91. list: videos,
  92. });
  93. }
  94. async function detail(id) {
  95. const html = await request(url + id);
  96. const $ = load(html);
  97. var jsBase = await js2Proxy(true, siteType, siteKey, 'img/', {});
  98. const detail = $('div.detail');
  99. const remarks = $('span#line-tips').text();
  100. let vod = {
  101. vod_id: id,
  102. vod_pic: jsBase + base64Encode($('div.item-root > img')[0].attribs['data-src']),
  103. vod_remarks: '',
  104. vod_content: remarks || '',
  105. vod_name: $(detail).find('h2').text().trim(),
  106. vod_year: $(detail).find('h3:nth-child(3)').text(),
  107. vod_area: $(detail).find('h3:nth-child(4)').text(),
  108. vod_actor: $(detail).find('h3:nth-child(5)').text(),
  109. };
  110. const res = await req(url + '/api/getResN?videoId=' + id.substring(id.lastIndexOf('/') + 1) + '&mtype=2&token=9109590b194731fde643ce27924fcf6f', {
  111. headers: {
  112. Referer: 'play',
  113. 'User-Agent': UA,
  114. },
  115. });
  116. const list = JSON.parse(res.content).data.list;
  117. let playlist = {};
  118. let arr = []
  119. for (const l of list) {
  120. const flagData = JSON.parse(l.resData);
  121. for (const f of flagData) {
  122. const from = f.flag;
  123. const urls = f.url;
  124. if (!from || !urls) continue;
  125. if (playlist[from]) continue;
  126. playlist[from] = urls;
  127. }
  128. }
  129. for (var key in playlist) {
  130. if ('kuaikan' == key) {
  131. arr.push({
  132. flag: '快看',
  133. url: playlist[key],
  134. sort: 1
  135. })
  136. } else if ('bfzym3u8' == key) {
  137. arr.push({
  138. flag: '暴风',
  139. url: playlist[key],
  140. sort: 2
  141. })
  142. } else if ('ffm3u8' == key) {
  143. arr.push({
  144. flag: '非凡',
  145. url: playlist[key],
  146. sort: 3
  147. })
  148. } else if ('lzm3u8' == key) {
  149. arr.push({
  150. flag: '量子',
  151. url: playlist[key],
  152. sort: 4
  153. })
  154. } else {
  155. arr.push({
  156. flag: key,
  157. url: playlist[key],
  158. sort: 5
  159. })
  160. }
  161. }
  162. arr.sort((a, b) => a.sort - b.sort);
  163. let playFrom = [];
  164. let playList = [];
  165. arr.map(val => {
  166. playFrom.push(val.flag);
  167. playList.push(val.url);
  168. })
  169. vod.vod_play_from = playFrom.join("$$$");
  170. vod.vod_play_url = playList.join("$$$");
  171. return JSON.stringify({
  172. list: [vod],
  173. });
  174. }
  175. function base64Encode(text) {
  176. return Crypto.enc.Base64.stringify(Crypto.enc.Utf8.parse(text));
  177. }
  178. function base64Decode(text) {
  179. return Crypto.enc.Utf8.stringify(Crypto.enc.Base64.parse(text));
  180. }
  181. async function proxy(segments, headers) {
  182. let what = segments[0];
  183. let url = base64Decode(segments[1]);
  184. if (what == 'img') {
  185. var resp = await req(url, {
  186. buffer: 2,
  187. headers: {
  188. Referer: url,
  189. 'User-Agent': UA,
  190. },
  191. });
  192. return JSON.stringify({
  193. code: resp.code,
  194. buffer: 2,
  195. content: resp.content,
  196. headers: resp.headers,
  197. });
  198. }
  199. return JSON.stringify({
  200. code: 500,
  201. content: '',
  202. });
  203. }
  204. async function play(flag, id, flags) {
  205. return JSON.stringify({
  206. parse: 0,
  207. url: id,
  208. });
  209. }
  210. async function search(wd, quick, pg) {
  211. if (pg <= 0 || typeof(pg) == 'undefined') pg = 1;
  212. const html = await request(url + '/search?q=' + wd + '&p=' + pg);
  213. const $ = load(html);
  214. const items = $('div.media');
  215. var jsBase = await js2Proxy(true, siteType, siteKey, 'img/', {});
  216. let videos = _.map(items, (item) => {
  217. const a = $(item).find('a:first')[0];
  218. const img = $(item).find('img:first')[0];
  219. const remarks = $($(item).find('span.label')[0]).text().trim();
  220. return {
  221. vod_id: a.attribs.href,
  222. vod_name: img.attribs.alt,
  223. vod_pic: jsBase + base64Encode(img.attribs['data-src']),
  224. vod_remarks: remarks || '',
  225. };
  226. });
  227. const hasMore = $('div.page-more > a:contains(下一页)').length > 0;
  228. const pgCount = hasMore ? parseInt(pg) + 1 : parseInt(pg);
  229. return JSON.stringify({
  230. page: parseInt(pg),
  231. pagecount: pgCount,
  232. list: videos,
  233. });
  234. }
  235. export function __jsEvalReturn() {
  236. return {
  237. init: init,
  238. home: home,
  239. homeVod: homeVod,
  240. category: category,
  241. detail: detail,
  242. play: play,
  243. proxy: proxy,
  244. search: search,
  245. };
  246. }