@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
JavaScript
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;