qrtzcode
HomeDocsAPILeaderboardChangelog
Contribute
Docs

qrtzcode

Kumpulan gist & snippet pribadi — anime, AI tools, scraper, dan randomness.

Navigate

HomeDocsAPI Reference

Links

© 2026 qrtz. All snippets welcome.

ESC

Navigate

Links

Comic

mgkomik

scraper mgkomik lengkap.

Creator

qrtz

Language

javascript

Views

16

Copies

3

Base

https://web1.mgkomik.cc

Updated

13 Agu 2026

#comic#manga#manhua#manwha

Code

163
mgkomik.js
const axios = require('axios');
const cheerio = require('cheerio');

const BASE_URL = 'https://web1.mgkomik.cc';

const USER_AGENTS = [
  'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
  'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
  'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
  'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/119.0',
  'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:109.0) Gecko/20100101 Firefox/119.0',
  'Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/119.0',
  'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36 Edg/119.0.0.0',
  'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.1 Safari/605.1.15',
  'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36',
  'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36',
];

function getRandomUserAgent() {
  return USER_AGENTS[Math.floor(Math.random() * USER_AGENTS.length)];
}

function getRandomIP() {
  const octet = () => Math.floor(Math.random() * 256);
  return `${octet()}.${octet()}.${octet()}.${octet()}`;
}

function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

async function fetchPage(url, retries = 3) {
  for (let i = 0; i < retries; i++) {
    try {
      const response = await axios.get(url, {
        headers: {
          'User-Agent': getRandomUserAgent(),
          'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8',
          'Accept-Language': 'en-US,en;q=0.5',
          'Accept-Encoding': 'gzip, deflate, br',
          'Connection': 'keep-alive',
          'Upgrade-Insecure-Requests': '1',
          'Sec-Fetch-Dest': 'document',
          'Sec-Fetch-Mode': 'navigate',
          'Sec-Fetch-Site': 'none',
          'Sec-Fetch-User': '?1',
          'Cache-Control': 'max-age=0',
          'X-Forwarded-For': getRandomIP(),
          'Client-IP': getRandomIP(),
        },
        timeout: 30000,
      });
      await sleep(500 + Math.random() * 1000);
      return response.data;
    } catch (e) {
      if (i === retries - 1) throw e;
      await sleep(1000 * (i + 1));
    }
  }
}

function cleanText(text) {
  return text.replace(/\s+/g, ' ').trim();
}

function parseListPage(html) {
  const $ = cheerio.load(html);
  const items = [];
  $('.manga-card').each(function() {
    const $el = $(this);
    const $cover = $el.find('.card-cover a');
    const $info = $el.find('.card-info');
    const $title = $info.find('.manga-title');
    const $chapterCapsule = $info.find('.chapter-capsule');
    const $chapterDate = $info.find('.chapter-date');
    const $status = $el.find('.manga-status-badge');
    const $flag = $el.find('.flag-badge');
    const $img = $cover.find('img.manga-cover');
    const thumbnail = $img.attr('src') || '';
    const url = $cover.attr('href') || '';
    const title = cleanText($title.text());
    const status = cleanText($status.text());
    const flagTitle = cleanText($flag.attr('title') || '');
    const chapterText = cleanText($chapterCapsule.text());
    const chapterLink = $chapterCapsule.attr('href') || '';
    const chapterDate = cleanText($chapterDate.text());
    if (title || url) {
      items.push({
        title,
        url: url.startsWith('http') ? url : BASE_URL + url,
        thumbnail,
        status,
        flag: flagTitle,
        latestChapter: {
          title: chapterText,
          url: chapterLink.startsWith('http') ? chapterLink : BASE_URL + chapterLink,
          date: chapterDate,
        },
      });
    }
  });
  return items;
}

function parseDetailPage(html) {
  const $ = cheerio.load(html);
  
  const title = cleanText($('.manga-title').text());
  const thumbnail = $('.manga-cover-large').attr('src') || '';
  const type = cleanText($('.meta-item:first-child').text());
  const status = cleanText($('.status-badge').text());
  
  const genres = [];
  $('.genre-tag').each(function() {
    genres.push(cleanText($(this).text()));
  });
  
  const synopsis = cleanText($('.manga-description p').text());
  const author = cleanText($('.meta-item:contains("Author:")').text().replace('Author:', '').trim());
  const artist = cleanText($('.meta-item:contains("Artist:")').text().replace('Artist:', '').trim());
  const release = cleanText($('.meta-item:contains("Release:")').text().replace('Release:', '').trim());
  
  const chapters = [];
  $('.chapter-list-item').each(function() {
    const $el = $(this);
    const $link = $el.find('.chapter-link');
    const number = cleanText($el.find('.chapter-number').text());
    const date = cleanText($el.find('.chapter-date').text());
    const url = $link.attr('href') || '';
    chapters.push({
      number,
      date,
      url: url.startsWith('http') ? url : BASE_URL + url,
    });
  });

  let prevChapter = null;
  let nextChapter = null;
  
  $('.nav-row .nav-btn').each(function() {
    const $el = $(this);
    const text = cleanText($el.text());
    const href = $el.attr('href');
    if (text.includes('Prev') && href && href !== '#') {
      prevChapter = {
        title: cleanText(text),
        url: href.startsWith('http') ? href : BASE_URL + href,
      };
    }
    if (text.includes('Next') && href && href !== '#') {
      nextChapter = {
        title: cleanText(text),
        url: href.startsWith('http') ? href : BASE_URL + href,
      };
    }
  });

  return {
    title,
    thumbnail,
    type,
    status,
    genres,
    synopsis,
    author,
    artist,
    release,
    totalChapters: chapters.length,
    chapters,
    prevChapter,
    nextChapter,
  };
}

function parseChapterPage(html) {
  const $ = cheerio.load(html);
  const images = [];
  $('.reading-content img').each(function() {
    const src = $(this).attr('src');
    if (src) images.push(src);
  });
  
  let prevChapter = null;
  let nextChapter = null;
  
  $('.nav-row .nav-btn').each(function() {
    const $el = $(this);
    const text = cleanText($el.text());
    const href = $el.attr('href');
    if (text.includes('Prev') && href && href !== '#') {
      prevChapter = {
        title: cleanText(text),
        url: href.startsWith('http') ? href : BASE_URL + href,
      };
    }
    if (text.includes('Next') && href && href !== '#') {
      nextChapter = {
        title: cleanText(text),
        url: href.startsWith('http') ? href : BASE_URL + href,
      };
    }
  });

  return {
    totalPages: images.length,
    images,
    prevChapter,
    nextChapter,
  };
}

function buildListUrl(opts) {
  const { type, genre, order, page, status } = opts;
  const params = new URLSearchParams();
  if (page) params.set('page', page);
  if (order) params.set('order_by', order);

  if (status) {
    params.set('status', status);
    if (type) params.append('types[]', type);
    if (genre) params.append('genres[]', genre);
    return `/search/?${params.toString()}`;
  }

  if (type) params.set('filter', type);
  else if (genre) params.set('filter', genre);

  return `/komik/?${params.toString()}`;
}

function extractSlug(input) {
  if (input.startsWith('http')) {
    const urlObj = new URL(input);
    const pathParts = urlObj.pathname.split('/').filter(p => p);
    return pathParts[pathParts.length - 1] || pathParts[0];
  }
  return input;
}

async function fetchList(opts) {
  const url = buildListUrl(opts);
  const fullUrl = BASE_URL + url;
  const html = await fetchPage(fullUrl);
  return parseListPage(html);
}

async function fetchDetail(slugOrUrl) {
  const slug = extractSlug(slugOrUrl);
  const fullUrl = `${BASE_URL}/komik/${slug}/`;
  const html = await fetchPage(fullUrl);
  return parseDetailPage(html);
}

async function fetchChapter(slugOrUrl) {
  let url = slugOrUrl;
  if (!url.startsWith('http')) {
    const slug = extractSlug(url);
    url = `${BASE_URL}/komik/${slug}/chapter-01-1/`;
  }
  const html = await fetchPage(url);
  return parseChapterPage(html);
}

function formatOutput(data, halaman = 'list', page = 1) {
  return {
    creator: 'rynaqrtz',
    halaman,
    page,
    total: data.totalChapters || data.totalPages || data.length || 0,
    data,
  };
}

async function main() {
  const args = process.argv.slice(2);
  if (args.length === 0) {
    console.log(JSON.stringify({
      creator: 'rynaqrtz',
      error: 'Perintah diperlukan',
      usage: {
        list: 'node mgkomik.js list [--type manga] [--genre action] [--order latest] [--page 1] [--status on-going]',
        detail: 'node mgkomik.js detail <slug|url>',
        chapter: 'node mgkomik.js chapter <slug|url>'
      },
      example: {
        list: 'node mgkomik.js list --type manga --order latest --page 1',
        detail: 'node mgkomik.js detail gimai-seikatsu',
        chapter: 'node mgkomik.js chapter https://web1.mgkomik.cc/komik/gimai-seikatsu/chapter-39-2/'
      }
    }, null, 2));
    return;
  }

  const command = args[0];

  if (command === 'list') {
    const opts = { page: 1 };
    for (let i = 1; i < args.length; i++) {
      const arg = args[i];
      if (arg.startsWith('--')) {
        const key = arg.slice(2);
        const value = args[i + 1];
        if (['type', 'genre', 'order', 'status'].includes(key)) {
          opts[key] = value;
        } else if (key === 'page') {
          opts.page = parseInt(value) || 1;
        }
        i++;
      }
    }
    try {
      const data = await fetchList(opts);
      const output = formatOutput(data, 'list', opts.page);
      console.log(JSON.stringify(output, null, 2));
    } catch (err) {
      console.log(JSON.stringify({ creator: 'rynaqrtz', error: err.message }, null, 2));
    }
  } else if (command === 'detail') {
    const input = args[1];
    if (!input) {
      console.log(JSON.stringify({ creator: 'rynaqrtz', error: 'Slug atau URL diperlukan' }, null, 2));
      return;
    }
    try {
      const data = await fetchDetail(input);
      const output = formatOutput(data, 'detail', 1);
      console.log(JSON.stringify(output, null, 2));
    } catch (err) {
      console.log(JSON.stringify({ creator: 'rynaqrtz', error: err.message }, null, 2));
    }
  } else if (command === 'chapter') {
    const input = args[1];
    if (!input) {
      console.log(JSON.stringify({ creator: 'rynaqrtz', error: 'Slug atau URL chapter diperlukan' }, null, 2));
      return;
    }
    try {
      const data = await fetchChapter(input);
      const output = formatOutput(data, 'chapter', 1);
      console.log(JSON.stringify(output, null, 2));
    } catch (err) {
      console.log(JSON.stringify({ creator: 'rynaqrtz', error: err.message }, null, 2));
    }
  } else {
    console.log(JSON.stringify({
      creator: 'rynaqrtz',
      error: `Perintah tidak dikenal: ${command}`,
      available: ['list', 'detail', 'chapter']
    }, null, 2));
  }
}

if (require.main === module) {
  main();
}

module.exports = { fetchList, fetchDetail, fetchChapter };

Rating

—(0)

Gimana snippet ini menurutmu?

</> Embed

Embed ke website / blog

<iframe src="https://qrtzcode.vercel.app/api/embed/comic/mgkomik" style="width:100%;height:400px;border:none;border-radius:12px;"></iframe>

Related Snippets

komikindo

scraper komikindo super duper lengkap:p.

66
15

webtoon

yh.

25
8