天悦小说

https://www.xtyxsw.org

ethereal-essence (13554) 16小时前 下载:452

小说 小说 天悦 xtyxsw
天悦小说网
二维码导入(APP尚未完成该功能)
// @uuid        019e1214-edbb-7f54-aea5-5678bd343263
// @name        天悦小说
// @version     1.0.0
// @author      Ethereal
// @url         https://www.xtyxsw.org
// @type        novel
// @logo        https://www.xtyxsw.org/favicon.ico
// @enabled     true
// @tags        小说,天悦,xtyxsw
// @description 天悦小说网

async function TEST(type) {
  if (type === '__list__') return ['search', 'explore', 'flow'];

  if (type === 'search') {
    var r = await search('跳龙门', 1);
    if (!r || !r.length) return { passed: false, message: '搜索无结果(若服务端拦截自动化请求,请在设置中打开浏览器探测调试)' };
    return { passed: true, message: '搜索返回 ' + r.length + ' 条' };
  }

  if (type === 'explore') {
    var b = await explore(1, '玄幻');
    if (!b || !b.length) return { passed: false, message: '分类页为空' };
    return { passed: true, message: '分类「玄幻」' + b.length + ' 本' };
  }

  if (type === 'flow') {
    var list = await search('跳龙门', 1);
    if (!list || !list.length) return { passed: false, message: '搜索为空' };
    var info = await bookInfo(list[0].bookUrl);
    if (!info || !info.name) return { passed: false, message: '详情失败' };
    var ch = await chapterList(info.tocUrl);
    if (!ch || !ch.length) return { passed: false, message: '目录为空' };
    var txt = await chapterContent(ch[0].url);
    if (!txt || txt.length < 30) return { passed: false, message: '正文过短,可能需探测模式' };
    return { passed: true, message: info.name + ' / ' + ch.length + ' 章 / 正文 ' + txt.length + ' 字' };
  }

  return { passed: false, message: '未知测试: ' + type };
}

var PC_BASE = 'https://www.xtyxsw.org';

var HTTP_HEADERS = {
  'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
  'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
  'Accept-Language': 'zh-CN,zh;q=0.9',
};

var EXPLORE_META = [
  { name: '玄幻', path: '/sort/1_' },
  { name: '奇幻', path: '/sort/2_' },
  { name: '武侠', path: '/sort/3_' },
  { name: '都市', path: '/sort/4_' },
  { name: '历史', path: '/sort/5_' },
  { name: '军事', path: '/sort/6_' },
  { name: '悬疑', path: '/sort/7_' },
  { name: '游戏', path: '/sort/8_' },
  { name: '科幻', path: '/sort/9_' },
  { name: '体育', path: '/sort/10_' },
  { name: '古言', path: '/sort/11_' },
  { name: '现言', path: '/sort/12_' },
  { name: '幻言', path: '/sort/13_' },
  { name: '仙侠', path: '/sort/14_' },
  { name: '青春', path: '/sort/15_' },
  { name: '穿越', path: '/sort/16_' },
  { name: '女生', path: '/sort/17_' },
  { name: '其他', path: '/sort/18_' },
  { name: '点击榜', path: '/allvisit/' },
  { name: '推荐榜', path: '/allvote/' },
  { name: '收藏榜', path: '/goodnum/' },
  { name: '新书入库', path: '/postdate/' },
];

function absUrl(href, base) {
  if (!href) return '';
  if (href.indexOf('http://') === 0 || href.indexOf('https://') === 0) return href;
  if (href.charAt(0) === '/') return base + href;
  return base + '/' + href;
}

function selectAttrSafe(root, sel, attr) {
  var el = legado.dom.select(root, sel);
  if (!el) return '';
  return legado.dom.attr(el, attr) || '';
}

function bookIdFromUrl(url) {
  var m = url.match(/\/(?:book|read)\/(\d+)/);
  return m ? m[1] : '';
}

function pcBookUrl(id) {
  return PC_BASE + '/book/' + id + '.html';
}

function readTocUrl(id) {
  return PC_BASE + '/read/' + id + '/';
}

async function httpGetSafe(url) {
  try {
    return await legado.http.get(url, HTTP_HEADERS);
  } catch (e) {
    legado.log('[http] GET failed ' + url + ' : ' + e);
    return '';
  }
}

async function httpPostSafe(url, body, headers) {
  try {
    return await legado.http.post(url, body, headers);
  } catch (e) {
    legado.log('[http] POST failed ' + url + ' : ' + e);
    return '';
  }
}

function parseListLiBooks(html, kindLabel) {
  if (!html || html.indexOf('找不到您要搜索的内容') !== -1) return [];
  var doc = legado.dom.parse(html);
  var lis = legado.dom.selectAll(doc, 'ul.list li');
  var books = [];
  var seen = {};
  for (var i = 0; i < lis.length; i++) {
    var li = lis[i];
    var name = legado.dom.selectText(li, 'p.bookname a');
    var readHref = selectAttrSafe(li, 'p.bookname a', 'href');
    if (!name || !readHref) continue;
    var id = bookIdFromUrl(absUrl(readHref, PC_BASE));
    if (!id || seen[id]) continue;
    seen[id] = true;
    var author = legado.dom.selectText(li, 'p.data a.layui-btn');
    var cover = selectAttrSafe(li, 'a img', 'src') || selectAttrSafe(li, 'img', 'src');
    var latest = legado.dom.selectText(li, 'p.data a');
    if (latest === author) latest = '';
    books.push({
      name: name,
      author: author || '',
      bookUrl: pcBookUrl(id),
      coverUrl: absUrl(cover, PC_BASE),
      intro: '',
      lastChapter: latest || '',
      kind: kindLabel || '',
    });
  }
  legado.dom.free(doc);
  return books;
}

function parsePcExploreBooks(html, kindLabel) {
  if (!html) return [];
  var doc = legado.dom.parse(html);
  var boxes = legado.dom.selectAll(doc, 'div[id=alistbox]');
  var books = [];
  var seen = {};
  for (var i = 0; i < boxes.length; i++) {
    var box = boxes[i];
    var name = legado.dom.selectText(box, 'div.info div.title h2 a');
    var readHref = selectAttrSafe(box, 'div.info div.title h2 a', 'href');
    if (!readHref) readHref = selectAttrSafe(box, 'div.pic a', 'href');
    if (!name || !readHref) continue;
    var id = bookIdFromUrl(absUrl(readHref, PC_BASE));
    if (!id || seen[id]) continue;
    seen[id] = true;
    var author = legado.dom.selectText(box, 'div.info span a');
    if (!author) author = legado.dom.selectText(box, 'div.info span');
    author = (author || '').replace(/^作者[::]\s*/, '').trim();
    var cover = selectAttrSafe(box, 'div.pic a img', 'src') || selectAttrSafe(box, 'div.pic img', 'src');
    var latest = legado.dom.selectText(box, 'div.sys a');
    books.push({
      name: name,
      author: author || '',
      bookUrl: pcBookUrl(id),
      coverUrl: absUrl(cover, PC_BASE),
      intro: legado.dom.selectText(box, 'div.intro') || '',
      lastChapter: latest || '',
      kind: kindLabel || '',
    });
  }
  legado.dom.free(doc);
  return books;
}

function parseExploreOrSearchHtml(html, kindLabel) {
  var a = parseListLiBooks(html, kindLabel);
  if (a.length) return a;
  return parsePcExploreBooks(html, kindLabel);
}

async function searchHttp(keyword, page) {
  var body = 'searchkey=' + encodeURIComponent(keyword);
  var postHeaders = {
    'User-Agent': HTTP_HEADERS['User-Agent'],
    'Accept': HTTP_HEADERS['Accept'],
    'Accept-Language': HTTP_HEADERS['Accept-Language'],
    'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
    'Origin': PC_BASE,
    'Referer': PC_BASE + '/',
  };
  var html = await httpPostSafe(PC_BASE + '/search.html', body, postHeaders);
  if (!html) return [];
  return parseExploreOrSearchHtml(html, '');
}

function searchBrowserFetch(keyword) {
  var kw = JSON.stringify(keyword);
  var code = [
    '(function(){',
    '  var kw = ' + kw + ';',
    '  var xhr = new XMLHttpRequest();',
    '  xhr.open("POST", "/search.html", false);',
    "  xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');",
    "  xhr.send('searchkey=' + encodeURIComponent(kw));",
    '  var html = xhr.responseText || "";',
    '  try {',
    '    var p = new DOMParser();',
    '    var doc = p.parseFromString(html, "text/html");',
    '    var lis = doc.querySelectorAll("ul.list li");',
    '    var books = [];',
    '    var seen = {};',
    '    for (var i = 0; i < lis.length; i++) {',
    '      var li = lis[i];',
    '      var na = li.querySelector("p.bookname a");',
    '      if (!na) continue;',
    '      var name = (na.textContent || "").trim();',
    '      var readHref = na.getAttribute("href") || "";',
    '      var idm = readHref.match(/\\/read\\/(\\d+)/);',
    '      if (!idm) continue;',
    '      var id = idm[1];',
    '      if (seen[id]) continue;',
    '      seen[id] = true;',
    '      var authEl = li.querySelector("p.data a.layui-btn");',
    '      var author = authEl ? (authEl.textContent || "").trim() : "";',
    '      var img = li.querySelector("a img");',
    '      var cover = img ? (img.getAttribute("src") || "") : "";',
    '      var latest = "";',
    '      var pdata = li.querySelectorAll("p.data");',
    '      if (pdata.length > 1) {',
    '        var la = pdata[pdata.length - 1].querySelector("a");',
    '        if (la) latest = (la.textContent || "").trim();',
    '      }',
    '      books.push({ name: name, author: author, id: id, coverUrl: cover, lastChapter: latest });',
    '    }',
    '    return JSON.stringify(books);',
    '  } catch (e) { return "[]"; }',
    '})()',
  ].join('\n');

  try {
    var ret = legado.browser.run(PC_BASE + '/', code, {
      visible: false,
      waitUntil: 'load',
      timeoutSecs: 60,
    });
    var arr = JSON.parse(ret || '[]');
    var out = [];
    for (var j = 0; j < arr.length; j++) {
      var b = arr[j];
      if (!b.id) continue;
      out.push({
        name: b.name,
        author: b.author || '',
        bookUrl: pcBookUrl(b.id),
        coverUrl: absUrl(b.coverUrl || '', PC_BASE),
        intro: '',
        lastChapter: b.lastChapter || '',
        kind: '',
      });
    }
    return out;
  } catch (e2) {
    legado.log('[search] browser fetch failed: ' + e2);
    return [];
  }
}

async function search(keyword, page) {
  legado.log('[search] keyword=' + keyword + ' page=' + page);
  if (!keyword) return [];
  var books = await searchHttp(keyword, page);
  if (!books.length) books = searchBrowserFetch(keyword);
  legado.log('[search] total=' + books.length);
  return books;
}

async function bookInfo(bookUrl) {
  legado.log('[bookInfo] url=' + bookUrl);
  var id = bookIdFromUrl(bookUrl);
  if (!id) return { name: '', author: '', bookUrl: bookUrl, tocUrl: bookUrl, coverUrl: '', intro: '', lastChapter: '', kind: '' };

  var fetchUrl = bookUrl.indexOf('/book/') !== -1 ? bookUrl : pcBookUrl(id);
  var html = await httpGetSafe(fetchUrl);
  if (!html) {
    return {
      name: '',
      author: '',
      bookUrl: pcBookUrl(id),
      tocUrl: readTocUrl(id),
      coverUrl: '',
      intro: '',
      lastChapter: '',
      kind: '',
    };
  }
  var doc = legado.dom.parse(html);

  var name = legado.dom.selectText(doc, 'div.bookname h1');
  if (name) {
    name = name.replace(/作者:[\s\S]*$/, '').replace(/作者:.*/, '').trim();
  }
  if (!name) name = selectAttrSafe(doc, '[property="og:novel:book_name"]', 'content');

  var author = selectAttrSafe(doc, '[property="og:novel:author"]', 'content');
  if (!author) {
    var em = legado.dom.selectText(doc, 'div.bookname h1 em');
    if (em) {
      var am = em.match(/作者[::]\s*(\S+)/);
      author = am ? am[1] : em.replace(/^作者[::]\s*/, '').trim();
    }
  }

  var coverUrl = selectAttrSafe(doc, 'div.box_intro div.pic img', 'src');
  if (!coverUrl) coverUrl = selectAttrSafe(doc, '[property="og:image"]', 'content');

  var intro = legado.dom.selectText(doc, 'div.box_info div.intro');
  if (!intro) intro = selectAttrSafe(doc, '[property="og:description"]', 'content');

  var latestChapter = selectAttrSafe(doc, '[property="og:novel:latest_chapter_name"]', 'content');
  if (!latestChapter) {
    latestChapter = legado.dom.selectText(doc, 'div.book_newchap div.con p.ti a');
  }

  var kind = selectAttrSafe(doc, '[property="og:novel:category"]', 'content');
  if (!kind) {
    var tb = legado.dom.selectText(doc, 'div.box_info table');
    if (tb && tb.indexOf('小说分类') !== -1) {
      // 站点 table 文本常被压成一行,需截断到下一个字段标题
      var km = tb.match(/小说分类[::]\s*([\s\S]*?)(?:首发状态|小说状态|收藏总数|$)/);
      if (km && km[1]) kind = km[1].replace(/[||]/g, '').trim();
    }
  }

  legado.dom.free(doc);

  return {
    name: name || '',
    author: author || '',
    bookUrl: pcBookUrl(id),
    tocUrl: readTocUrl(id),
    coverUrl: coverUrl || '',
    intro: intro || '',
    lastChapter: latestChapter || '',
    kind: kind || '',
  };
}

async function parseChaptersFromReadIndex(html, bookId) {
  var doc = legado.dom.parse(html);
  var names = legado.dom.selectAllTexts(doc, 'div.link_14 dd a');
  var hrefs = legado.dom.selectAllAttrs(doc, 'div.link_14 dd a', 'href');
  if (!names || names.length === 0) {
    names = legado.dom.selectAllTexts(doc, 'ul.read li a');
    hrefs = legado.dom.selectAllAttrs(doc, 'ul.read li a', 'href');
  }
  var chapters = [];
  var seen = {};
  for (var i = 0; i < names.length; i++) {
    var u = absUrl(hrefs[i], PC_BASE);
    if (!u || seen[u]) continue;
    if (u.indexOf('/read/' + bookId + '/') === -1) continue;
    if (!/\.html$/.test(u)) continue;
    seen[u] = true;
    u = u.replace(/^https?:\/\/m\.xtyxsw\.org/i, PC_BASE);
    chapters.push({ name: names[i], url: u });
  }
  legado.dom.free(doc);

  if (chapters.length === 0) {
    var doc2 = legado.dom.parse(html);
    var vals = legado.dom.selectAllAttrs(doc2, 'div.pagelist select option', 'value');
    legado.dom.free(doc2);
    if (vals && vals.length) {
      var pageUrls = [];
      for (var vi = 0; vi < vals.length; vi++) {
        pageUrls.push(absUrl(vals[vi], PC_BASE));
      }
      var results = [];
      try {
        results = await legado.http.batchGet(pageUrls);
      } catch (eBatch) {
        legado.log('[chapterList] batchGet: ' + eBatch);
      }
      for (var p = 0; p < results.length; p++) {
        if (!results[p].ok) continue;
        var sub = parseChaptersFromMobileTocOnly(results[p].data, bookId);
        for (var j = 0; j < sub.length; j++) {
          if (!seen[sub[j].url]) {
            seen[sub[j].url] = true;
            chapters.push(sub[j]);
          }
        }
      }
    }
  }
  return chapters;
}

function parseChaptersFromMobileTocOnly(html, bookId) {
  var doc = legado.dom.parse(html);
  var names = legado.dom.selectAllTexts(doc, 'ul.read li a');
  var hrefs = legado.dom.selectAllAttrs(doc, 'ul.read li a', 'href');
  var chapters = [];
  for (var i = 0; i < names.length; i++) {
    var u = absUrl(hrefs[i], PC_BASE).replace(/^https?:\/\/m\.xtyxsw\.org/i, PC_BASE);
    if (!u || u.indexOf('/read/' + bookId + '/') === -1) continue;
    if (!/\.html$/.test(u)) continue;
    chapters.push({ name: names[i], url: u });
  }
  legado.dom.free(doc);
  return chapters;
}

async function chapterList(tocUrl) {
  legado.log('[chapterList] url=' + tocUrl);
  var id = bookIdFromUrl(tocUrl);
  if (!id) return [];

  var indexUrl = readTocUrl(id);
  if (tocUrl.indexOf('/read/') !== -1 && tocUrl.indexOf('.html') === -1) {
    indexUrl = tocUrl.split('?')[0];
    if (indexUrl.charAt(indexUrl.length - 1) !== '/') indexUrl += '/';
    indexUrl = indexUrl.replace(/^https?:\/\/m\.xtyxsw\.org/i, PC_BASE);
  }

  var html0 = await httpGetSafe(indexUrl);
  if (!html0) return [];
  var all = await parseChaptersFromReadIndex(html0, id);
  legado.log('[chapterList] count=' + all.length);
  return all;
}

function stripNoiseLine(s) {
  if (!s) return '';
  var noise = /天悦小说网|手机阅读|无弹窗|小主,这个章节后面还有哦|请点击下一页继续阅读|请大家收藏:|更新速度全网最快|章节报错|加入书签/g;
  if (noise.test(s)) return '';
  return s;
}

function parseChapterBodyParagraphs(html, isM) {
  if (!html) return '';
  var doc = legado.dom.parse(html);
  var lines = legado.dom.selectAllTexts(doc, isM ? 'div.content p' : '#content p') || [];
  var out = [];
  for (var i = 0; i < lines.length; i++) {
    var t = (lines[i] || '').replace(/^\s+|\s+$/g, '');
    t = stripNoiseLine(t);
    if (t) out.push(t);
  }
  legado.dom.free(doc);
  return out.join('\n\n');
}

function chapterTailBaseAndPage(tail) {
  if (!tail) return { base: '', page: 1 };
  var ix = tail.lastIndexOf('_');
  if (ix <= 0 || ix >= tail.length - 1) {
    return { base: tail, page: 1 };
  }
  var suf = tail.substring(ix + 1);
  if (!/^\d+$/.test(suf)) {
    return { base: tail, page: 1 };
  }
  return { base: tail.substring(0, ix), page: parseInt(suf, 10) || 1 };
}

function findNextChapterContentPageUrl(html, currentUrl) {
  if (!html || !currentUrl) return '';
  var u = currentUrl.replace(/^https?:\/\/m\.xtyxsw\.org/i, PC_BASE);
  u = u.split('?')[0].split('#')[0];
  var m = u.match(/\/read\/(\d+)\/([^/?#]+)\.html$/);
  if (!m) return '';
  var bookId = m[1];
  var tail = m[2];
  var fp = chapterTailBaseAndPage(tail);
  var nextPath = '/read/' + bookId + '/' + fp.base + '_' + (fp.page + 1) + '.html';
  if (html.indexOf(nextPath) !== -1) {
    return PC_BASE + nextPath;
  }
  var doc = legado.dom.parse(html);
  var names = legado.dom.selectAllTexts(doc, '#thumb a') || [];
  var hrefs = legado.dom.selectAllAttrs(doc, '#thumb a', 'href') || [];
  if (!hrefs || hrefs.length === 0) {
    names = legado.dom.selectAllTexts(doc, 'div.pager a, .pager a') || [];
    hrefs = legado.dom.selectAllAttrs(doc, 'div.pager a, .pager a', 'href') || [];
  }
  var nextUrl = '';
  for (var i = 0; i < hrefs.length; i++) {
    var label = (names[i] || '').replace(/\s+/g, '');
    if (label.indexOf('下一页') !== -1 && label.indexOf('下一章') === -1) {
      nextUrl = absUrl(hrefs[i], PC_BASE).replace(/^https?:\/\/m\.xtyxsw\.org/i, PC_BASE);
      break;
    }
  }
  legado.dom.free(doc);
  if (!nextUrl || nextUrl === u) return '';
  return nextUrl;
}

async function chapterContentHttp(chapterUrl) {
  var start = chapterUrl.replace(/^https?:\/\/m\.xtyxsw\.org/i, PC_BASE).split('?')[0].split('#')[0];
  var parts = [];
  var visited = {};
  var url = start;
  var maxPages = 120;
  for (var step = 0; step < maxPages; step++) {
    if (visited[url]) break;
    visited[url] = true;
    var html = await httpGetSafe(url);
    if (!html) break;
    var isM = url.indexOf('m.xtyxsw.org') !== -1;
    var block = parseChapterBodyParagraphs(html, isM);
    if (block) parts.push(block);
    legado.log('[chapterContent] HTTP 分页 ' + (step + 1) + ' url=' + url + ' len=' + block.length);
    var nextU = findNextChapterContentPageUrl(html, url);
    if (!nextU) break;
    url = nextU;
  }
  return parts.join('\n\n');
}

function needsContentProbe(text, html) {
  if (!text || text.length < 40) return true;
  if (html && (html.indexOf('eval(') !== -1 || html.indexOf('unescape(') !== -1 || html.indexOf('document.write') !== -1))
    return true;
  return false;
}

function chapterContentMultiBrowser(startUrl) {
  var parts = [];
  var url = startUrl;
  for (var step = 0; step < 120; step++) {
    var chunk = legado.browser.run(url, [
      'function abs(h){ if(!h)return""; try{return new URL(h,location.href).href}catch(e){return"";} }',
      'function tailBasePage(t){',
      '  if(!t)return{base:"",page:1};',
      '  var ix=t.lastIndexOf("_");',
      '  if(ix<=0||ix>=t.length-1)return{base:t,page:1};',
      '  var suf=t.slice(ix+1);',
      '  if(!/^\\d+$/.test(suf))return{base:t,page:1};',
      '  return{base:t.slice(0,ix),page:parseInt(suf,10)||1};',
      '}',
      'var noise=/天悦小说网|小主,这个章节后面还有哦|请点击下一页|请大家收藏:|更新速度全网最快/;',
      'var root=document.querySelector("div.content")||document.querySelector("#content");',
      'if(!root)return JSON.stringify({text:"",next:""});',
      'var ps=root.querySelectorAll("p");var out=[];',
      'for(var i=0;i<ps.length;i++){var t=(ps[i].textContent||"").trim();if(t&&!noise.test(t))out.push(t);}',
      'var next="";',
      'var pm=location.pathname.match(/^\\/read\\/(\\d+)\\/([^/]+)\\.html$/);',
      'if(pm){',
      '  var fp=tailBasePage(pm[2]);',
      '  var np="/read/"+pm[1]+"/"+fp.base+"_"+(fp.page+1)+".html";',
      '  if(document.documentElement.innerHTML.indexOf(np)!==-1)next=abs(np);',
      '}',
      'if(!next){',
      '  var as=document.querySelectorAll("#thumb a, .pager a, div.pager a");',
      '  for(var j=0;j<as.length;j++){var tx=((as[j].textContent||"").replace(/\\s+/g,""));if(tx.indexOf("下一页")!==-1&&tx.indexOf("下一章")===-1){next=abs(as[j].getAttribute("href"));break;}}',
      '}',
      'return JSON.stringify({text:out.join("\\n\\n"),next:next});',
    ].join(''), { visible: false, waitUntil: 'load', timeoutSecs: 40 });
    var data = JSON.parse(chunk || '{"text":"","next":""}');
    if (data.text) parts.push(data.text);
    if (!data.next || data.next === url) break;
    url = data.next;
  }
  return parts.join('\n\n');
}

async function chapterContent(chapterUrl) {
  legado.log('[chapterContent] url=' + chapterUrl);
  var htmlQuick = '';
  try {
    htmlQuick = await httpGetSafe(chapterUrl);
  } catch (e0) {
    legado.log('[chapterContent] http get failed: ' + e0);
  }

  var text = await chapterContentHttp(chapterUrl);
  if (needsContentProbe(text, htmlQuick)) {
    legado.log('[chapterContent] switch to browser probe');
    var bt = chapterContentMultiBrowser(chapterUrl);
    if (bt && bt.length > text.length) text = bt;
    else if (!text) text = bt || '';
  }
  return text;
}

async function explore(page, category) {
  if (!category || category === 'GETALL') {
    var names = [];
    for (var i = 0; i < EXPLORE_META.length; i++) names.push(EXPLORE_META[i].name);
    return names;
  }

  var meta = null;
  for (var j = 0; j < EXPLORE_META.length; j++) {
    if (EXPLORE_META[j].name === category) {
      meta = EXPLORE_META[j];
      break;
    }
  }
  if (!meta) return [];

  var p = page || 1;
  var url;
  if (meta.path.indexOf('/sort/') === 0) {
    url = PC_BASE + meta.path + p + '/';
  } else {
    url = p === 1 ? PC_BASE + meta.path : PC_BASE + meta.path.replace(/\/$/, '') + '/' + p + '.html';
  }

  legado.log('[explore] category=' + category + ' page=' + p + ' url=' + url);
  var html = await httpGetSafe(url);
  return parseExploreOrSearchHtml(html, category);
}
广告