"番茄短剧"

"https://www.shanhuzs.com/"

zpccool (13551) 16小时前 下载:306

视频
"感谢作者大大"
二维码导入(APP尚未完成该功能)
// @name "番茄短剧"
// @uuid "fanqieduanju"
// @version 1.0.0
// @updateUrl   http://aliyun.18638642193.cn/api/sources/user:a65fc492-08a0-44f7-a052-b9836fe7318d/download
// @author AI
// @url "https://www.shanhuzs.com/"
// @enabled true
// @description "感谢作者大大"
// @group "影视 书源"
// @type video

var BASE_URL = "https://www.shanhuzs.com/";

function absoluteUrl(u) {
    if (!u) return "";
    if (/^https?:\/\//i.test(u)) return u;
    if (u[0] === '/') u = u.substring(1);
    return BASE_URL.replace(/\/$/, '') + '/' + u;
}

// ==================== 原书源规则(供手动适配) ====================
// searchUrl        : "/fqsansc/{{key}}----------{{page}}---.html"
// search.bookList  : "class.col8"
// search.name      : "h4@a@text"
// search.author    : ""
// search.coverUrl  : "img@data-original"
// search.bookUrl   : "h4@a@href"
// info.*           : "{\"kind\": \".tag@a@text\"}"
// toc.*            : "{\"chapterList\": \"a[href^=\\\"/fqsanpy/\\\"]\", \"chapterName\": \"text\", \"chapterUrl\": \"href\"}"
// content.*        : "{\"content\": \"##\\\"url\\\":\\\"(.*)\\\",\\\"url_next\\\"##$1###@js:\\nif(book.durChapterIndex==chapter.index){\\n\\t\\tjava.startBrowser(result.replace(/\\\\\\\\/g,''),title)\\n\\t\\tjava.toast('正在加载视频\\\\n视频加载较慢,请耐心等待')\\n\\t}\\n'【刷新正文】播放\\\\n✅直链:\\\\n'+result\", \"replaceRegex\": \"##\\\\\"}"
// explore.*        : "{}"
// ================================================================

async function search(keyword, page) {
  const url = BASE_URL + '/fqsansc/' + encodeURIComponent(keyword) + '----------' + page + '---.html';
  const resp = await legado.http.get(url);
  const doc = legado.dom.parse(resp);
  const items = [];
  
  const listItems = legado.dom.selectAll(doc, '.shoutu-vodlist li.col8');
  for (var i = 0; i < listItems.length; i++) {
    var item = listItems[i];
    
    var titleEl = legado.dom.select(item, 'h4.title a');
    var name = titleEl ? legado.dom.text(titleEl) : '';
    
    var bookUrl = '';
    if (titleEl) {
      var href = legado.dom.attr(titleEl, 'href');
      bookUrl = absoluteUrl(href);
    }
    
    var coverUrl = '';
    var imgEl = legado.dom.select(item, 'img');
    if (imgEl) {
      var dataOriginal = legado.dom.attr(imgEl, 'data-original');
      coverUrl = absoluteUrl(dataOriginal);
    }
    
    if (name && bookUrl) {
      items.push({
        name: name,
        bookUrl: bookUrl,
        coverUrl: coverUrl,
        author: '',
        kind: ''
      });
    }
  }
  
  legado.dom.free(doc);
  return items;
}

async function bookInfo(bookUrl) {
  const resp = await legado.http.get(bookUrl);
  const doc = legado.dom.parse(resp);
  
  var name = '';
  var h1El = legado.dom.select(doc, '.shoutu-content h1');
  if (h1El) name = legado.dom.text(h1El);
  
  var coverUrl = '';
  
  // 方案1: 尝试从 .cover-img img 获取
  var imgEl = legado.dom.select(doc, '.cover-img img');
  if (imgEl) {
    var dataOriginal = legado.dom.attr(imgEl, 'data-original');
    if (!dataOriginal) dataOriginal = legado.dom.attr(imgEl, 'src');
    if (dataOriginal) {
      coverUrl = absoluteUrl(dataOriginal);
      legado.log('方案1获取封面: ' + coverUrl);
    }
  }
  
  // 方案2: 尝试从 img[data-original*="/upload/vod/"] 获取
  if (!coverUrl) {
    var vodPicEl = legado.dom.select(doc, 'img[data-original*="/upload/vod/"]');
    if (vodPicEl) {
      var dataOriginal = legado.dom.attr(vodPicEl, 'data-original');
      if (dataOriginal) {
        coverUrl = absoluteUrl(dataOriginal);
        legado.log('方案2获取封面: ' + coverUrl);
      }
    }
  }
  
  // 方案3: 尝试从所有带有 data-original 属性的 img 获取
  if (!coverUrl) {
    var allImgEl = legado.dom.select(doc, 'img[data-original]');
    if (allImgEl) {
      var dataOriginal = legado.dom.attr(allImgEl, 'data-original');
      if (dataOriginal) {
        coverUrl = absoluteUrl(dataOriginal);
        legado.log('方案3获取封面: ' + coverUrl);
      }
    }
  }
  
  // 方案4: 尝试从 mac_history_set 标签中获取
  if (!coverUrl) {
    var historyEl = legado.dom.select(doc, '.mac_history_set');
    if (historyEl) {
      var dataPic = legado.dom.attr(historyEl, 'data-pic');
      if (dataPic) {
        coverUrl = absoluteUrl(dataPic);
        legado.log('方案4获取封面: ' + coverUrl);
      }
    }
  }
  
  var kind = '';
  var tagEl = legado.dom.select(doc, '.tag a');
  if (tagEl) kind = legado.dom.text(tagEl);
  
  var intro = '';
  var descEl = legado.dom.select(doc, '.desc');
  if (descEl) {
    intro = legado.dom.text(descEl).replace('简介:', '').trim();
  }
  
  var latestChapter = '';
  var textEl = legado.dom.select(doc, '.text');
  if (textEl) latestChapter = legado.dom.text(textEl);
  
  legado.dom.free(doc);
  
  legado.log('最终封面URL: ' + coverUrl);
  
  return {
    name: name,
    author: '',
    bookUrl: bookUrl,
    tocUrl: bookUrl,
    coverUrl: coverUrl,
    intro: intro,
    latestChapter: latestChapter,
    kind: kind
  };
}

async function chapterList(tocUrl) {
  const resp = await legado.http.get(tocUrl);
  const doc = legado.dom.parse(resp);
  const chapters = [];
  
  const links = legado.dom.selectAll(doc, '.shoutu-playlist a');
  for (var i = 0; i < links.length; i++) {
    var link = links[i];
    var href = legado.dom.attr(link, 'href');
    
    if (href && href.startsWith('/fqsanpy/')) {
      var name = legado.dom.text(link);
      var url = absoluteUrl(href);
      chapters.push({
        name: name,
        url: url
      });
    }
  }
  
  legado.dom.free(doc);
  return chapters;
}

async function chapterContent(chapterUrl) {
  const resp = await legado.http.get(chapterUrl);
  
  // 尝试匹配 player_aaaa 对象中的 url 字段
  const match = resp.match(/var player_aaaa=\{[^}]*"url":"([^"]+)"/);
  if (match && match[1]) {
    let videoUrl = match[1];
    // 解码转义的斜杠
    videoUrl = videoUrl.replace(/\\\//g, '/');
    legado.log('提取到视频地址: ' + videoUrl);
    return videoUrl;
  }
  
  // 尝试匹配 player_aaaa 对象中的 url 字段(包含换行)
  const match2 = resp.match(/var player_aaaa=\{[\s\S]*?"url":"([^"]+)"/);
  if (match2 && match2[1]) {
    let videoUrl = match2[1];
    // 解码转义的斜杠
    videoUrl = videoUrl.replace(/\\\//g, '/');
    legado.log('提取到视频地址 (多行): ' + videoUrl);
    return videoUrl;
  }
  
  // 尝试直接匹配 m3u8 地址
  const match3 = resp.match(/https:\/\/[^"'\s]+\.m3u8/g);
  if (match3 && match3.length > 0) {
    let videoUrl = match3[0];
    // 解码转义的斜杠
    videoUrl = videoUrl.replace(/\\\//g, '/');
    legado.log('提取到视频地址 (直接): ' + videoUrl);
    return videoUrl;
  }
  
  legado.log('未找到视频地址');
  return '';
}

async function explore(page, category) {
  if (!category || category === "GETALL") {
    // 返回分类列表
    return ["短剧"];
  }
  
  const url = BASE_URL + '/fqsantp/5.html';
  const resp = await legado.http.get(url);
  const doc = legado.dom.parse(resp);
  const items = [];
  
  const listItems = legado.dom.selectAll(doc, '.shoutu-vodlist li.col8');
  for (var i = 0; i < listItems.length; i++) {
    var item = listItems[i];
    
    var titleEl = legado.dom.select(item, 'h4.title a');
    var name = titleEl ? legado.dom.text(titleEl) : '';
    
    var bookUrl = '';
    if (titleEl) {
      var href = legado.dom.attr(titleEl, 'href');
      bookUrl = absoluteUrl(href);
    }
    
    var coverUrl = '';
    var imgEl = legado.dom.select(item, 'img');
    if (imgEl) {
      var dataOriginal = legado.dom.attr(imgEl, 'data-original');
      coverUrl = absoluteUrl(dataOriginal);
    }
    
    if (name && bookUrl) {
      items.push({
        name: name,
        bookUrl: bookUrl,
        coverUrl: coverUrl,
        author: '',
        kind: ''
      });
    }
  }
  
  legado.dom.free(doc);
  return items;
}

function categories() {
    return [
        { name: '短剧', url: '/fqsantp/5.html' }
    ];
}

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

  if (type === 'explore') {
    var cats = await explore(1, '__invalid__');
    if (!cats || cats.length < 1) return { passed: false, message: '分类列表异常' };
    var books = await explore(1, cats[0]);
    if (!books || books.length < 1) return { passed: false, message: '发现页 [' + cats[0] + '] 返回为空' };
    return { passed: true, message: '发现页 [' + cats[0] + ']: ' + books.length + ' 条结果 ✓' };
  }

  if (type === 'bookInfo') {
    var info = await bookInfo('https://www.shanhuzs.com/fqsandt/73059.html');
    if (!info || !info.name) return { passed: false, message: 'bookInfo 返回为空' };
    return { passed: true, message: 'name=' + info.name + ' ✓' };
  }

  if (type === 'chapterList') {
    var chs = await chapterList('https://www.shanhuzs.com/fqsandt/73059.html');
    if (!chs || chs.length < 1) return { passed: false, message: '章节列表为空' };
    return { passed: true, message: '共 ' + chs.length + ' 集 ✓' };
  }

  if (type === 'chapterContent') {
    var url = await chapterContent('https://www.shanhuzs.com/fqsanpy/73059-1-1.html');
    if (!url) return { passed: false, message: '播放地址为空' };
    return { passed: true, message: '播放地址获取成功 ✓' };
  }

  if (type === 'search') {
    var results = await search('系统', 1);
    if (!results || results.length < 1) return { passed: false, message: '搜索结果为空' };
    return { passed: true, message: '搜索返回 ' + results.length + ' 条结果 ✓' };
  }

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