230ts_open.js 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. // 网站搜索异常
  2. import { load, _ } from './lib/cat.js';
  3. let key = '爱上你听书网';
  4. let HOST = 'https://wap.230ts.net';
  5. let siteKey = '';
  6. let siteType = 0;
  7. 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';
  8. async function request(reqUrl, agentSp) {
  9. let res = await req(reqUrl, {
  10. method: 'get',
  11. headers: {
  12. 'User-Agent': agentSp || MOBILE_UA,
  13. 'Referer': HOST
  14. },
  15. });
  16. return res.content;
  17. }
  18. // cfg = {skey: siteKey, ext: extend}
  19. async function init(cfg) {
  20. siteKey = cfg.skey;
  21. siteType = cfg.stype;
  22. }
  23. async function home(filter) {
  24. const html = await request(HOST + '/sort/');
  25. const $ = load(html);
  26. let filterObj = {};
  27. const class_parse = $('dl.pd-class:first > dd > a[href*=sort]');
  28. let classes = [];
  29. classes = _.map(class_parse, (cls) => {
  30. let typeId = cls.attribs['href'];
  31. typeId = typeId.replace(/.*?\/sort\/(.*).html/g, '$1');
  32. return {
  33. type_id: typeId,
  34. type_name: cls.children[0].data,
  35. };
  36. });
  37. const sortName = ['玄幻有声', '灵异有声', '综艺娱乐', '长篇评书', '都市有声', '军事有声', '职场有声', '其他有声'];
  38. classes = _.sortBy(classes, (c) => {
  39. const index = sortName.indexOf(c.type_name);
  40. return index === -1 ? sortName.length : index;
  41. });
  42. return JSON.stringify({
  43. class: classes,
  44. filters: filterObj,
  45. });
  46. }
  47. async function homeVod() {
  48. const link = HOST + '/top/lastupdate/1.html';
  49. const html = await request(link);
  50. const $ = load(html);
  51. const items = $('ul.list-ul > li');
  52. let videos = _.map(items, (item) => {
  53. const it = $(item).find('a:first')[0];
  54. const img = $(item).find('img:first')[0];
  55. const remarks = $($(item).find('p.module-slide-author')[0]).text().trim();
  56. return {
  57. vod_id: it.attribs.href.replace(/.*?\/tingshu\/(.*)/g, '$1'),
  58. vod_name: it.attribs.title.replace('有声小说',''),
  59. vod_pic: HOST + img.attribs['data-original'],
  60. vod_remarks: remarks || '',
  61. };
  62. });
  63. return JSON.stringify({
  64. list: videos,
  65. });
  66. }
  67. async function category(tid, pg, filter, extend) {
  68. if (pg <= 0) pg = 1;
  69. const link = HOST + '/sort/' + tid +'/' + (`${pg}`) + '.html';
  70. const html = await request(link);
  71. const $ = load(html);
  72. const items = $('ul.book-ol > li');
  73. let videos = _.map(items, (item) => {
  74. const it = $(item).find('a:first')[0];
  75. const img = $(item).find('img:first')[0];
  76. const remarks = $($(item).find('div.book-meta')[0]).text().trim();
  77. return {
  78. vod_id: it.attribs.href.replace(/.*?\/tingshu\/(.*)/g, '$1'),
  79. vod_name: it.attribs.title.replace('有声小说',''),
  80. vod_pic: HOST + img.attribs['data-original'],
  81. vod_remarks: remarks.replace('佚名(著)','').replace('佚名(播)','').replace('未知(著)','').replace('未知(播)','') || '',
  82. };
  83. });
  84. const hasMore = $('div.paging > 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(HOST + '/tingshu/' + id);
  96. const $ = load(html);
  97. const detail = $('div.book-cell:first > div');
  98. let vod = {
  99. vod_id: id,
  100. vod_name: $('h1:first').text().trim().replace('有声小说',''),
  101. vod_pic: HOST + $('div.myui-content__thumb img:first').attr('data-original'),
  102. vod_content: $('div.ellipsis').text().trim(),
  103. };
  104. for (const info of detail) {
  105. const i = $(info).text().trim();
  106. if (i.startsWith('类型:')) {
  107. vod.vod_type = _.map($(info).find('a'), (a) => {
  108. return a.children[0].data;
  109. }).join('/');
  110. } else if (i.startsWith('作者:')) {
  111. vod.vod_director = _.map($(info).find('a'), (a) => {
  112. return a.children[0].data;
  113. }).join('/');
  114. } else if (i.startsWith('演播:')) {
  115. vod.vod_actor = _.map($(info).find('a'), (a) => {
  116. return a.children[0].data;
  117. }).join('/');
  118. } else if (i.startsWith('连载中')) {
  119. vod.vod_remarks = i.substring(3);
  120. }
  121. }
  122. const playlist = _.map($('#playlist > ul > li > a'), (it) => {
  123. return it.children[0].data + '$' + it.attribs.href.replace(/\/mp3\/(.*).html/g, '$1');
  124. });
  125. vod.vod_play_from = '道长在线';
  126. vod.vod_play_url = playlist.join('#');
  127. return JSON.stringify({
  128. list: [vod],
  129. });
  130. }
  131. async function play(flag, id, flags) {
  132. const link = HOST + '/mp3/' + id + '.html';
  133. const html = await request(link);
  134. const $ = load(html);
  135. const iframe = $('body iframe[src*=player]');
  136. const iframeHtml = (
  137. await req(HOST + iframe[0].attribs.src, {
  138. headers: {
  139. 'Referer': link,
  140. 'User-Agent': MOBILE_UA,
  141. },
  142. })
  143. ).content;
  144. const playUrl = iframeHtml.match(/mp3:'(.*?)'/)[1];
  145. if (playUrl.indexOf('m4a') >= 0 || playUrl.indexOf('mp3') >= 0 ) {
  146. return JSON.stringify({
  147. parse: 0,
  148. url: playUrl,
  149. });
  150. } else {
  151. try {
  152. const iframeHtml = (
  153. await req(HOST + iframe[0].attribs.src, {
  154. headers: {
  155. 'Referer': link,
  156. 'User-Agent': MOBILE_UA,
  157. },
  158. })
  159. ).content;
  160. const playUrl = playUrl + '.m4a' + iframeHtml.match(/(\?.*?)'/)[1];
  161. if (playUrl.indexOf('http') >= 0) {
  162. return JSON.stringify({
  163. parse: 0,
  164. url: playUrl,
  165. });
  166. } else {
  167. const iframeHtml = (
  168. await req(HOST + iframe[0].attribs.src, {
  169. headers: {
  170. 'Referer': link,
  171. 'User-Agent': MOBILE_UA,
  172. },
  173. })
  174. ).content;
  175. const playUrl2 = iframeHtml.match(/url[\s\S]*?(http.*?)'/)[1];
  176. if (playUrl2.indexOf('\?') >= 0) {
  177. return JSON.stringify({
  178. parse: 0,
  179. url: playUrl2,
  180. });
  181. } else {
  182. const playUrl3 = playUrl2 + playUrl
  183. return JSON.stringify({
  184. parse: 0,
  185. url: playUrl3,
  186. });
  187. }
  188. }
  189. } catch (e) {}
  190. if (playUrl.indexOf('http') >= 0) {
  191. const playUrl = playUrl + '.m4a';
  192. return JSON.stringify({
  193. parse: 0,
  194. url: playUrl,
  195. });
  196. } else {
  197. const iframeHtml = (
  198. await req(HOST + iframe[0].attribs.src, {
  199. headers: {
  200. 'Referer': link,
  201. 'User-Agent': MOBILE_UA,
  202. },
  203. })
  204. ).content;
  205. const playUrl4 = iframeHtml.match(/url[\s\S]*?(http.*?)'/)[1];
  206. return JSON.stringify({
  207. parse: 0,
  208. url: playUrl4 + '.m4a',
  209. });
  210. }
  211. }
  212. }
  213. async function search(wd, quick) {
  214. const link = HOST + '/search.html?searchtype=name&searchword=' + wd +'&page=1';
  215. const html = await request(link);
  216. const $ = load(html);
  217. const items = $('ul.book-ol > li');
  218. let videos = _.map(items, (item) => {
  219. const it = $(item).find('a:first')[0];
  220. const img = $(item).find('img:first')[0];
  221. const remarks = $($(item).find('div.book-meta')[0]).text().trim();
  222. return {
  223. vod_id: it.attribs.href.replace(/.*?\/tingshu\/(.*)/g, '$1'),
  224. vod_name: it.attribs.title.replace('有声小说',''),
  225. vod_pic: img.attribs['data-original'],
  226. vod_remarks: remarks.replace('佚名(著)','').replace('佚名(播)','').replace('未知(著)','').replace('未知(播)','') || '',
  227. };
  228. });
  229. return JSON.stringify({
  230. list: videos,
  231. });
  232. }
  233. export function __jsEvalReturn() {
  234. return {
  235. init: init,
  236. home: home,
  237. homeVod: homeVod,
  238. category: category,
  239. detail: detail,
  240. play: play,
  241. search: search,
  242. };
  243. }