xbato.js

by JazxCode
70 Raw
const axios = require('axios');
const cheerio = require('cheerio');

async function getSeriesDetail(url) {
  try {
    const baseUrl = 'https://xbato.com';
    const response = await axios.get(url);
    const $ = cheerio.load(response.data);
    const container = $('.container-max-width-xl');
    const title = container.find('.title-set h3.item-title a').text().trim();
    const aliases = container.find('.alias-set').text().trim()
      .split('/').map(a => a.trim()).filter(Boolean);
    const thumbnail = container.find('.attr-cover img').attr('src');
    const authors = [];
    container.find('.attr-item b:contains("Authors:")').next().find('a').each((i, el) => {
      authors.push($(el).text().trim());
    });
    const artists = [];
    container.find('.attr-item b:contains("Artists:")').next().find('a').each((i, el) => {
      artists.push($(el).text().trim());
    });
    const genres = [];
    container.find('.attr-item b:contains("Genres:")').next().children().each((i, el) => {
      genres.push($(el).text().trim());
    });
    const language = container.find('.attr-item b:contains("Original language:")').next().text().trim();
    const translated = container.find('.attr-item b:contains("Translated language:")').next().text().trim();
    const status = container.find('.attr-item b:contains("Original work:")').next().text().trim();
    const uploadStatus = container.find('.attr-item b:contains("Upload status:")').next().text().trim();
    const year = container.find('.attr-item b:contains("Year of Release:")').next().text().trim();
    const summary = container.find('.limit-html').text().trim();
    const chapters = [];
    $('.item').each((i, el) => {
      const chapterEl = $(el);
      const chapterPath = chapterEl.find('a.visited.chapt').attr('href');
      const chapterUrl = baseUrl + chapterPath;
      const chapterTitle = chapterEl.find('a.visited.chapt b').text().trim();
      const uploaderEl = chapterEl.find('.extra a.ps-3');
      const uploaderName = uploaderEl.find('span').text().trim();
      const uploaderPath = uploaderEl.attr('href');
      const uploaderUrl = baseUrl + uploaderPath;
      const uploaderAvatar = uploaderEl.find('img').attr('src');
      const viewsRaw = chapterEl.find('.extra span.ps-3 i').map((i, el) => $(el).text().trim()).get();
      const views = viewsRaw.join(' ');
      const uploadDate = chapterEl.find('.extra i.ps-3').text().trim();

      chapters.push({
        title: chapterTitle,
        url: chapterUrl,
        views,
        uploadDate
      });
    });

    return {
      title,
      aliases,
      thumbnail,
      authors,
      artists,
      genres,
      language,
      translated,
      status,
      uploadStatus,
      year,
      summary,
      chapters
    };
  } catch (err) {
    console.error('Error saat mengambil detail seri:', err.message);
    return null;
  }
}
async function getChapterImages(url) {
  try {
    const response = await axios.get(url);
    const $ = cheerio.load(response.data);
    const scriptContent = $('script')
      .map((_, el) => $(el).html())
      .get()
      .find(text => text.includes('const imgHttps'));
    const imgRegex = /const imgHttps\s*=\s*(\[[^\]]+\])/;
    const match = imgRegex.exec(scriptContent);
    if (!match) throw new Error('imgHttps not found');
    const imageArray = eval(match[1]);
    return imageArray;
  } catch (err) {
    console.error('Gagal scrape:', err.message);
    return [];
  }
}
// contoh getSeriesDetail detail
getSeriesDetail("https://xbato.com/series/99300/can-we-become-family-official")
// contoh penggunaan getChapterImages
getChapterImages("https://xbato.com/chapter/3259300")