UNPKG

@boboiboyturuu_nih/kiryuu-scraper

Version:

Scraper API for Kiryuu manga site

147 lines (130 loc) 5.47 kB
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, };