UNPKG

@cifumo/scraper-node

Version:

Sebuah Module Scraper yang dibuat oleh Sxyz dan SuzakuTeam untuk memudahkan penggunaan scraper di project ESM maupun CJS.

184 lines (158 loc) 5.25 kB
const axios = require("axios"); const cheerio = require("cheerio"); const anime = { animeIndo: async (type, opt) => { if (type === "latest") { const { data } = await axios.get("https://anime-indo.lol/"); const $ = cheerio.load(data); const result = []; $("div.menu a").each((_, el) => { const element = $(el); const img = element.find("img.lazy").attr("data-original"); const title = element.find("p").text().trim(); const episode = element.find("span.eps").text().trim(); const link = "https://anime-indo.lol" + element.attr("href"); if (!title || !episode || !img) return; result.push({ title, episode, img, link, }); }); return result; } else if (type === "search") { const query = opt?.query; if (!query) return { error: "Query kosong. Masukkan `query`." }; const formattedQuery = query.replace(/\s+/g, "-").toLowerCase(); const { data: Search } = await axios.get( `https://anime-indo.lol/search/${formattedQuery}/`, ); const $$ = cheerio.load(Search); const results = []; $$(".menu table.otable").each((_, el) => { const element = $$(el); const linkPart = element.find("td.vithumb a").attr("href"); const link = "https://anime-indo.lol" + linkPart; const img = "https://anime-indo.lol" + element.find("td.vithumb img").attr("src"); const title = element.find("td.videsc a").first().text().trim(); const description = element.find("td.videsc p.des").text().trim(); results.push({ title, img, link, description, }); }); return results; } return { msg: "Type Tidak Di Kenali!", availableType: "latest, search", availableOptions: { query: "Pakai Jika Type Anda Adalah Search", }, }; }, quotes: async () => { let { data } = await axios.get(`https://otakotaku.com/quote/feed`); let $ = cheerio.load(data); let quotes = []; $(".kotodama-list").each((i, el) => { let character = $(el).find(".char-name").text().trim(); let anime = $(el).find(".anime-title").text().trim(); let episode = $(el).find(".meta").text().trim(); let quote = $(el).find(".quote").text().trim(); let image = $(el).find(".char-img img").attr("data-src"); let link = $(el).find("a.kuroi").attr("href"); quotes.push({ character, anime, episode, quote, image, link: `https://otakotaku.com${link}`, }); }); return quotes.length > 0 ? quotes[Math.floor(Math.random() * quotes.length)] : null; }, anime9Search: async (anime) => { const { data: dataa } = await axios.get( `https://9animetv.to/search?keyword=${anime}`, ); const $ = cheerio.load(dataa); const result = []; $(".flw-item").each((i, element) => { const title = $(element).find(".film-name a").attr("title"); const url = "https://9animetv.to" + $(element).find(".film-name a").attr("href"); const imgSrc = $(element).find(".film-poster-img").attr("data-src"); const quality = $(element).find(".tick-quality").text(); const subOrDub = $(element).find(".tick-sub").text() || $(element).find(".tick-dub").text(); const episode = $(element) .find(".tick-eps") .text() .replace(/\s+/g, " ") .trim(); result.push({ title, url, imgSrc, quality, subOrDub, episode, }); }); return result; }, anime9Details: async (url) => { try { let { data } = await axios.get(url); let $ = cheerio.load(data); let title = $(".film-name").text().trim(); let image = $(".film-poster img").attr("src"); let alias = $(".alias").text().trim(); let description = $(".film-description p").text().trim(); let type = $(".item-title:contains('Type:')").next().text().trim(); let studio = $(".item-title:contains('Studios:')").next().text().trim(); let aired = $(".item-title:contains('Date aired:')").next().text().trim(); let status = $(".item-title:contains('Status:')").next().text().trim(); let score = $(".item-title:contains('Scores:')").next().text().trim(); let duration = $(".item-title:contains('Duration:')") .next() .text() .trim(); let quality = $(".item-title:contains('Quality:')").next().text().trim(); let views = $(".item-title:contains('Views:')").next().text().trim(); let genres = []; $(".item-title:contains('Genre:')") .next() .find("a") .each((_, el) => genres.push($(el).text().trim())); return { title, image, alias, description, type, studio, aired, status, score, duration, quality, views, genres, }; } catch (error) { console.error("Error fetching details:", error); return null; } }, }; module.exports = anime;