@boboiboyturuu_nih/kiryuu-scraper
Version:
Scraper API for Kiryuu manga site
147 lines (130 loc) • 5.47 kB
JavaScript
const axios = require('axios');
const cheerio = require('cheerio');
const fs = require('fs');
const path = require('path');
const { URL } = require('url');
const __filename = new URL(import.meta.url).pathname;
const __dirname = path.dirname(__filename);
/**
* Mengambil detail dari manga berdasarkan URL spesifik.
* @param {string} url - URL dari halaman manga di Kiryuu.
* @returns {object} - Objek berisi detail manga.
*/
async function mangadetails(url) {
try {
const { data } = await axios.get(url);
const $ = cheerio.load(data);
const title = $('.seriestuheader .entry-title').text().trim();
const altTitle = $('.seriestualt').text().trim();
const thumbnail = $('.seriestucontl .thumb img').attr('src');
const rating = $('.num[itemprop="ratingValue"]').text().trim();
const description = $('.entry-content-single p').text().trim();
const latestChapter = $('.epcurlast').text().trim();
const latestChapterUrl = $('.epcurlast').closest('a').attr('href');
const status = $('tr:contains("Status") td:nth-child(2)').text().trim();
const type = $('tr:contains("Type") td:nth-child(2)').text().trim();
const released = $('tr:contains("Released") td:nth-child(2)').text().trim();
const author = $('tr:contains("Author") td:nth-child(2)').text().trim();
const artist = $('tr:contains("Artist") td:nth-child(2)').text().trim();
const serialization = $('tr:contains("Serialization") td:nth-child(2)').text().trim();
const postedBy = $('tr:contains("Posted By") td:nth-child(2) i').text().trim();
const postedOn = $('tr:contains("Posted On") time').text().trim();
const updatedOn = $('tr:contains("Updated On") time').text().trim();
const views = $('tr:contains("Views") td:nth-child(2) .ts-views-count').text().trim();
return {
title,
altTitle,
thumbnail,
rating,
description,
latestChapter,
latestChapterUrl,
status,
type,
released,
author,
artist,
serialization,
postedBy,
postedOn,
updatedOn,
views,
url,
};
} catch (error) {
console.error('Error fetching manga details from URL:', url);
console.error('Detailed error message:', error.message);
throw new Error(`Failed to fetch manga details: ${error.message}`);
}
}
/**
* Mencari manga berdasarkan query.
* @param {string} query - Kata kunci pencarian.
* @returns {array} - Daftar hasil pencarian manga.
*/
async function mangasearch(query) {
const url = `https://kiryuu.org/?s=${encodeURIComponent(query)}`;
try {
const { data } = await axios.get(url);
const $ = cheerio.load(data);
const results = [];
$('.bs').each((index, element) => {
const title = $(element).find('.bsx > a').attr('title');
const link = $(element).find('.bsx > a').attr('href');
const thumbnail = $(element).find('.bsx img').attr('src');
const chapter = $(element).find('.adds .epxs').text().trim();
const rating = $(element).find('.numscore').text().trim();
results.push({ title, link, thumbnail, chapter, rating });
});
return results.length > 0 ? results : null;
} catch (error) {
console.error('Error searching manga with query:', query);
console.error('Error URL:', url);
console.error('Detailed error message:', error.message);
throw new Error(`Failed to search manga: ${error.message}`);
}
}
/**
* Mengunduh file manga dari URL spesifik.
* @param {string} url - URL dari halaman manga atau chapter di Kiryuu.
* @returns {string} - Path dari file yang telah diunduh.
*/
async function mangadownload(url) {
try {
const { data } = await axios.get(url);
const $ = cheerio.load(data);
const downloadLink = $('span.dlx.r > a').attr('href');
if (downloadLink) {
const parsedUrl = new URL(url);
const rawFileName = parsedUrl.pathname.slice(1).replace(/[^a-zA-Z0-9]/g, '');
const fileName = `${rawFileName}.zip`;
const filePath = path.resolve(__dirname, fileName);
const response = await axios({
url: downloadLink,
method: 'GET',
responseType: 'stream'
});
const writer = fs.createWriteStream(filePath);
response.data.pipe(writer);
return new Promise((resolve, reject) => {
writer.on('finish', () => resolve(filePath));
writer.on('error', (err) => {
console.error('Error writing file to disk:', filePath);
console.error('Detailed error message:', err.message);
reject(new Error(`Failed to download file: ${err.message}`));
});
});
} else {
throw new Error('Download link not found.');
}
} catch (error) {
console.error('Error downloading manga from URL:', url);
console.error('Detailed error message:', error.message);
throw new Error(`Failed to download manga: ${error.message}`);
}
}
module.exports = {
mangadetails,
mangasearch,
mangadownload,
};