saohuo_open.js 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. import { load, _ } from 'assets://js/lib/cat.js';
  2. //发布地址:http://shapp.us/
  3. let key = 'saohuo';
  4. let HOST = 'https://saohuo.us';
  5. let PARSE_URL = 'https://hhjx.hhplayer.com/api.php';
  6. var charStr = 'abacdefghjklmnopqrstuvwxyzABCDEFGHJKLMNOPQRSTUVWXYZ0123456789';
  7. let COOKIE = 'PHPSESSID=' + randStr(26, true);
  8. let validCheckUrl = '';
  9. let siteKey = '';
  10. let siteType = 0;
  11. 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';
  12. async function request(reqUrl, method, data) {
  13. const res = await req(reqUrl, {
  14. method: method || 'get',
  15. headers: {
  16. 'User-Agent': UA,
  17. 'Referer': HOST,
  18. 'Cookie': COOKIE
  19. },
  20. data: data,
  21. postType: method === 'post' ? 'form' : '',
  22. });
  23. return res.content;
  24. }
  25. // cfg = {skey: siteKey, ext: extend}
  26. async function init(cfg) {
  27. siteKey = cfg.skey;
  28. siteType = cfg.stype;
  29. }
  30. async function home(filter) {
  31. let classes = [{'type_id':'1','type_name':'电影'},{'type_id':'2','type_name':'电视'}];
  32. let filterObj = {
  33. '1':[{'key':'class','name':'类型','init':'1','value':[{'n':'全部','v':'1'},{'n':'喜剧','v':'6'},{'n':'爱情','v':'7'},{'n':'恐怖','v':'8'},{'n':'动作','v':'9'},{'n':'科幻','v':'10'},{'n':'战争','v':'11'},{'n':'犯罪','v':'12'},{'n':'动画','v':'13'},{'n':'奇幻','v':'14'},{'n':'剧情','v':'15'},{'n':'冒险','v':'16'},{'n':'悬疑','v':'17'},{'n':'惊悚','v':'18'},{'n':'其它','v':'19'}]}],
  34. '2':[{'key':'class','name':'类型','init':'2','value':[{'n':'全部','v':'2'},{'n':'大陆','v':'20'},{'n':'TVB','v':'21'},{'n':'韩剧','v':'22'},{'n':'美剧','v':'23'},{'n':'日剧','v':'24'},{'n':'英剧','v':'25'},{'n':'台剧','v':'26'},{'n':'其它','v':'27'}]}],
  35. };
  36. return JSON.stringify({
  37. class: classes,
  38. filters: filterObj,
  39. });
  40. }
  41. async function homeVod() {
  42. const videos = await getVideos(HOST);
  43. return JSON.stringify({
  44. list: videos,
  45. })
  46. }
  47. async function category(tid, pg, filter, extend) {
  48. if (pg <= 0) pg = 1;
  49. const clazz = extend['class'] || tid;
  50. const link = HOST + `/list/${clazz}-${pg}.html`;
  51. const videos = await getVideos(link);
  52. return JSON.stringify({
  53. page: parseInt(pg),
  54. list: videos,
  55. });
  56. }
  57. async function detail(id) {
  58. const html = await request(HOST + id);
  59. const $ = load(html);
  60. const parseUrl = $('iframe').attr('src');
  61. const remarks = $('section.grid_box.v_info_box > p').text().split('/');
  62. const playFroms = _.map($('ul.from_list > li'), item => {
  63. return $(item).text();
  64. }).join('$$$');
  65. const playUrls = _.map($('ul#play_link > li'), list => {
  66. return _.map($(list).find('a'), item => {
  67. return $(item).text() + '$' + $(item).attr('href');
  68. }).join('#');
  69. }).join('$$$');
  70. const vod = {
  71. vod_id: id,
  72. vod_name: $('h1.v_title').text(),
  73. vod_director: remarks[remarks.length-2].replace('导演:', '').trim(),
  74. vod_actor: remarks[remarks.length-1].replace('主演:', '').trim(),
  75. vod_content: $('p.p_txt.show_part').text(),
  76. vod_play_from: playFroms,
  77. vod_play_url: playUrls,
  78. };
  79. return JSON.stringify({
  80. list: [vod],
  81. });
  82. }
  83. async function play(flag, id, flags) {
  84. const html = await request(HOST + id);
  85. const $ = load(html);
  86. const parseUrl = $('iframe').attr('src');
  87. const url = await getRealUrl(parseUrl);
  88. return JSON.stringify({
  89. parse: 0,
  90. url: url,
  91. });
  92. }
  93. async function search(wd, quick, pg) {
  94. try {
  95. let page = pg || 1;
  96. if (page == 0) page = 1;
  97. let searchURL = `${HOST}/search.php?searchword=${encodeURIComponent(wd)}`;
  98. let html = await request(searchURL);
  99. if (html.includes("请输入正确的验证码继续访问")) {
  100. for (let i = 0; i < 2; i++) {
  101. html = await validCode(`${HOST}/include/vdimgck.php`, wd);
  102. if (!html.includes("请输入正确的验证码继续访问")) {
  103. break;
  104. }
  105. }
  106. }
  107. //console.log('html', html);
  108. const $ = load(html);
  109. const items = $('ul.v_list > li > div');
  110. let videos = _.map(items, (it) => {
  111. const img = $(it).find('img:first')[0];
  112. const remarks = $(it).find('div.v_note').text().trim();
  113. return {
  114. vod_id: $(it).find('a:first')[0].attribs['href'],
  115. vod_name: $(it).find('a:first')[0].attribs.title,
  116. vod_pic: img.attribs['data-original'],
  117. vod_remarks: remarks || '',
  118. };
  119. });
  120. return JSON.stringify({
  121. list: videos,
  122. });
  123. } catch (err) {
  124. }
  125. }
  126. async function getVideos(link) {
  127. const html = await request(link);
  128. const $ = load(html);
  129. const items = $('ul.v_list > li > div');
  130. let videos = _.map(items, (it) => {
  131. const img = $(it).find('img:first')[0];
  132. const remarks = $(it).find('div.v_note').text().trim();
  133. return {
  134. vod_id: $(it).find('a:first')[0].attribs['href'],
  135. vod_name: $(it).find('a:first')[0].attribs.title,
  136. vod_pic: img.attribs['data-original'],
  137. vod_remarks: remarks || '',
  138. };
  139. });
  140. return videos;
  141. }
  142. async function getRealUrl(link) {
  143. const html = await request(link);
  144. // const rand = response.match(/<iframe src="(.*?)"/);
  145. const url = html.match(/var url = "(.*?)";/)[1];
  146. const t = html.match(/var t = "(.*?)";/)[1];
  147. const key = html.match(/var key = "(.*?)";/)[1];
  148. const act = html.match(/var act = "(.*?)";/)[1];
  149. const play = html.match(/var play = "(.*?)";/)[1];
  150. const res = await req(PARSE_URL, {
  151. method: 'post',
  152. headers: {
  153. 'User-Agent': UA,
  154. 'Referer': link,
  155. },
  156. data: {
  157. url,
  158. t,
  159. key,
  160. act,
  161. play,
  162. },
  163. postType: 'form',
  164. });
  165. const video = JSON.parse(res.content);
  166. return video.url;
  167. }
  168. async function validCode(url, wd) {
  169. try {
  170. //获取验证码的base64
  171. const res = await req(url, {
  172. buffer: 2,
  173. headers: {
  174. 'User-Agent': UA,
  175. 'Referer': HOST,
  176. 'Cookie': COOKIE
  177. }
  178. });
  179. const response = await req('https://api.nn.ci/ocr/b64/text', {
  180. method: 'post',
  181. data: res.content,
  182. headers: {
  183. 'Content-Type': 'text/plain',
  184. },
  185. });
  186. if(response['code'] === 200) {
  187. let checkRes = await request(`${HOST}/search.php?scheckAC=check&page=&searchtype=&order=&tid=&area=&year=&letter=&yuyan=&state=&money=&ver=&jq`, 'post', {
  188. validate: response.content,
  189. searchword: wd
  190. });
  191. return checkRes;
  192. }
  193. } catch (error) {
  194. console.error(error);
  195. }
  196. }
  197. function randStr(len, withNum) {
  198. var _str = '';
  199. let containsNum = withNum === undefined ? true : withNum;
  200. for (var i = 0; i < len; i++) {
  201. let idx = _.random(0, containsNum ? charStr.length - 1 : charStr.length - 11);
  202. _str += charStr[idx];
  203. }
  204. return _str;
  205. }
  206. export function __jsEvalReturn() {
  207. return {
  208. init: init,
  209. home: home,
  210. homeVod: homeVod,
  211. category: category,
  212. detail: detail,
  213. play: play,
  214. search: search,
  215. };
  216. }