tester-scraper
Version:
Sebuah Module Scraper yang dibuat oleh Sxyz dan SuzakuTeam untuk memudahkan penggunaan scraper di project ESM maupun CJS.
198 lines (178 loc) • 6.21 kB
JavaScript
/* Thanks To Nazir! */
import axios from "axios";
import * as cheerio from "cheerio";
import { Success, ErrorResponse } from "./lib/function.js";
const game = {
mlHeroDetails: async (heroName = "Layla") => {
const url = `https://mobile-legends.fandom.com/wiki/${encodeURIComponent(heroName)}`;
try {
const { data } = await axios.get(url);
const $ = cheerio.load(data);
const title = $("h1.page-header__title").text().trim();
const role = $('div[data-source="role"] .pi-data-value').text().trim();
const speciality = $('div[data-source="specialty"] .pi-data-value')
.text()
.trim();
const lane = $('div[data-source="lane"] .pi-data-value').text().trim();
return {
thanksTo: "Nazir",
title,
role,
speciality,
lane,
};
} catch (error) {
console.error("Gagal mengambil data:", error.message);
return null;
}
},
mlHeroes: async (heroNames) => {
try {
let response = await axios.get(
`https://mobile-legends.fandom.com/wiki/${heroNames}`,
);
let $ = cheerio.load(response.data);
let releaseDate = $('[data-source="release_date"] .pi-data-value')
.text()
.trim();
let role = $('[data-source="role"] .pi-data-value a').text().trim();
let specialty = $('[data-source="specialty"] .pi-data-value')
.text()
.trim();
let lane = $('[data-source="lane"] .pi-data-value a').text().trim();
let priceBP = $('[data-source="price"] .pi-data-value span')
.first()
.text()
.trim();
let priceDiamond = $('[data-source="price"] .pi-data-value span')
.last()
.text()
.trim();
let skillResource = $('[data-source="resource"] .pi-data-value a')
.text()
.trim();
let damageType = $('[data-source="dmg_type"] .pi-data-value a')
.text()
.trim();
let attackType = $('[data-source="atk_type"] .pi-data-value a')
.text()
.trim();
let durability = $('[data-source="durability"] .bar').text().trim();
let offense = $('[data-source="offense"] .bar').text().trim();
let controlEffects = $('[data-source="control effect"] .bar')
.text()
.trim();
let difficulty = $('[data-source="difficulty"] .bar').text().trim();
let heroNumber = $('[data-source="current_hero"]').text().trim();
let heroName = $('[data-source="current_hero"] b').text().trim();
let spotlight = $(".pi-item.pi-image a").attr("href");
let image = $(".pi-item.pi-image a img").attr("src");
return {
heroName,
heroNumber,
releaseDate,
role,
specialty,
lane,
price: { battlePoints: priceBP, diamonds: priceDiamond },
skillResource,
damageType,
attackType,
ratings: {
durability,
offense,
controlEffects,
difficulty,
},
image,
};
} catch (error) {
if (error.response?.status === 404) {
throw "Tidak Ada Hero Bernama " + heroNames + " Di Mobile Legends";
} else {
throw "Terjadi Kesalahan: " + error.message;
}
}
},
ffChar: async (charName) => {
try {
const { data } = await axios.get(`${BASE_URL}/wiki/Characters`);
const $ = cheerio.load(data);
const results = [];
$("table tbody tr").each((_, el) => {
const linkEl = $(el).find("td").first().find("a");
const name = linkEl.text().trim();
const href = linkEl.attr("href");
const imgEl = $(el).find("img");
let image = imgEl.attr("data-src") || imgEl.attr("src");
if (image?.startsWith("data:image")) {
image = imgEl.attr("data-src");
}
if (name && href && image) {
results.push({
name,
image: image.replace(/scale-to-width-down\/\d+/, "revision/latest"),
page: BASE_URL + href,
});
}
});
const filtered =
results.find((x) => x.name.toLowerCase() === charName.toLowerCase()) ||
results.find((x) =>
x.name.toLowerCase().includes(charName.toLowerCase()),
);
return filtered || null;
} catch (err) {
console.error("Error while searching character:", err.message);
return null;
}
},
growGardenStock: async () => {
const { data } = await axios.get("https://vulcanvalues.com/grow-a-garden/stock");
const $ = cheerio.load(data);
const result = {
gear: [],
egg: [],
seeds: []
};
// Extract Gear Stock
$('div:has(h2:contains("GEAR STOCK")) ul li').each((i, el) => {
const name = $(el).find('span').first().text().split(' x')[0].trim();
const quantity = parseInt($(el).find('.text-gray-400').text().replace('x', '').trim());
const image = $(el).find('img').attr('src');
result.gear.push({
name,
quantity,
image: "https://vulcanvalues.com" + image
});
});
// Extract Egg Stock
$('div:has(h2:contains("EGG STOCK")) ul li').each((i, el) => {
const name = $(el).find('span').first().text().split(' x')[0].trim();
const quantity = parseInt($(el).find('.text-gray-400').text().replace('x', '').trim());
const image = $(el).find('img').attr('src');
result.egg.push({
name,
quantity,
image: "https://vulcanvalues.com" + image
});
});
// Extract Seeds Stock
$('div:has(h2:contains("SEEDS STOCK")) ul li').each((i, el) => {
const name = $(el).find('span').first().text().split(' x')[0].trim();
const quantity = parseInt($(el).find('.text-gray-400').text().replace('x', '').trim());
const image = $(el).find('img').attr('src');
result.seeds.push({
name,
quantity,
image: "https://vulcanvalues.com" + image
});
});
try {
return result;
} catch (errorStack) {
return new ErrorResponse(errorStack)
}
}
};
export default game;