Spaces:
Running
Running
Update index.js
Browse files
index.js
CHANGED
@@ -1203,19 +1203,26 @@ async function scrapeHAnime(query) {
|
|
1203 |
}
|
1204 |
}
|
1205 |
|
|
|
|
|
|
|
|
|
1206 |
async function scrapeHAnimeDetails(url) {
|
1207 |
const browser = await puppeteer.launch({
|
1208 |
headless: true, // Set ke false untuk debugging
|
1209 |
args: ["--no-sandbox", "--disable-setuid-sandbox"],
|
1210 |
});
|
1211 |
-
const page = await browser.newPage();
|
1212 |
-
await page.setUserAgent(
|
1213 |
-
"Mozilla/5.0 (Linux; Android 10; SM-G965U Build/QP1A.190711.020; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/114.0.5735.141 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/420.0.0.32.61;]"
|
1214 |
-
);
|
1215 |
|
1216 |
try {
|
|
|
|
|
|
|
|
|
|
|
|
|
1217 |
await page.goto(url, { waitUntil: "domcontentloaded" });
|
1218 |
|
|
|
1219 |
const result = await page.evaluate(() => {
|
1220 |
const getText = (selector) => {
|
1221 |
const element = document.querySelector(selector);
|
@@ -1223,8 +1230,8 @@ async function scrapeHAnimeDetails(url) {
|
|
1223 |
};
|
1224 |
|
1225 |
const getGenre = () => {
|
1226 |
-
return [...document.querySelectorAll("body > main > article > aside.anime-cn.clb > div.genres.mgt.df.fww.por > a")].map(
|
1227 |
-
genre.textContent.trim()
|
1228 |
);
|
1229 |
};
|
1230 |
|
@@ -1240,46 +1247,79 @@ async function scrapeHAnimeDetails(url) {
|
|
1240 |
});
|
1241 |
|
1242 |
console.log("Result Metadata:", result);
|
1243 |
-
|
1244 |
-
await page.waitForSelector("body > main > div.player.mgt.mgb2 > div.vdplbx.c-df > aside.vdpl.fg1 > div > iframe", { timeout: 20000 });
|
1245 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1246 |
const iframeSrc = await page.evaluate(() => {
|
1247 |
-
const iframe = document.querySelector(
|
|
|
|
|
1248 |
return iframe ? iframe.src : null;
|
1249 |
});
|
1250 |
|
1251 |
console.log("Iframe Source:", iframeSrc);
|
1252 |
|
|
|
|
|
|
|
1253 |
let video = null;
|
|
|
1254 |
if (iframeSrc) {
|
1255 |
-
const
|
1256 |
-
|
1257 |
-
|
1258 |
-
|
1259 |
-
|
1260 |
-
const
|
1261 |
-
|
1262 |
-
const match = scriptContent.match(/file:\s*"(https?:\/\/[^"]+\.mp4)"/);
|
1263 |
-
if (match && match[1]) {
|
1264 |
-
video = match[1];
|
1265 |
-
}
|
1266 |
-
}
|
1267 |
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1268 |
}
|
1269 |
|
|
|
1270 |
result.video = video;
|
1271 |
|
|
|
1272 |
await browser.close();
|
|
|
1273 |
return result;
|
1274 |
} catch (error) {
|
1275 |
console.error("Error scraping details:", error);
|
|
|
|
|
1276 |
await browser.close();
|
1277 |
-
return error;
|
1278 |
}
|
1279 |
}
|
1280 |
|
1281 |
|
1282 |
|
|
|
1283 |
app.get('/hanime/search', async (req, res) => {
|
1284 |
const { query } = req.query;
|
1285 |
if (!query) {
|
|
|
1203 |
}
|
1204 |
}
|
1205 |
|
1206 |
+
const puppeteer = require("puppeteer");
|
1207 |
+
const axios = require("axios");
|
1208 |
+
const cheerio = require("cheerio");
|
1209 |
+
|
1210 |
async function scrapeHAnimeDetails(url) {
|
1211 |
const browser = await puppeteer.launch({
|
1212 |
headless: true, // Set ke false untuk debugging
|
1213 |
args: ["--no-sandbox", "--disable-setuid-sandbox"],
|
1214 |
});
|
|
|
|
|
|
|
|
|
1215 |
|
1216 |
try {
|
1217 |
+
const page = await browser.newPage();
|
1218 |
+
await page.setUserAgent(
|
1219 |
+
"Mozilla/5.0 (Linux; Android 10; SM-G965U Build/QP1A.190711.020; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/114.0.5735.141 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/420.0.0.32.61;]"
|
1220 |
+
);
|
1221 |
+
|
1222 |
+
// Buka halaman utama
|
1223 |
await page.goto(url, { waitUntil: "domcontentloaded" });
|
1224 |
|
1225 |
+
// Ambil metadata dari halaman
|
1226 |
const result = await page.evaluate(() => {
|
1227 |
const getText = (selector) => {
|
1228 |
const element = document.querySelector(selector);
|
|
|
1230 |
};
|
1231 |
|
1232 |
const getGenre = () => {
|
1233 |
+
return [...document.querySelectorAll("body > main > article > aside.anime-cn.clb > div.genres.mgt.df.fww.por > a")].map(
|
1234 |
+
(genre) => genre.textContent.trim()
|
1235 |
);
|
1236 |
};
|
1237 |
|
|
|
1247 |
});
|
1248 |
|
1249 |
console.log("Result Metadata:", result);
|
|
|
|
|
1250 |
|
1251 |
+
// Tunggu iframe muncul
|
1252 |
+
await page.waitForSelector(
|
1253 |
+
"body > main > div.player.mgt.mgb2 > div.vdplbx.c-df > aside.vdpl.fg1 > div > iframe",
|
1254 |
+
{ timeout: 20000 }
|
1255 |
+
);
|
1256 |
+
|
1257 |
+
// Ambil URL iframe
|
1258 |
const iframeSrc = await page.evaluate(() => {
|
1259 |
+
const iframe = document.querySelector(
|
1260 |
+
"body > main > div.player.mgt.mgb2 > div.vdplbx.c-df > aside.vdpl.fg1 > div > iframe"
|
1261 |
+
);
|
1262 |
return iframe ? iframe.src : null;
|
1263 |
});
|
1264 |
|
1265 |
console.log("Iframe Source:", iframeSrc);
|
1266 |
|
1267 |
+
// Tutup tab pertama
|
1268 |
+
await page.close();
|
1269 |
+
|
1270 |
let video = null;
|
1271 |
+
|
1272 |
if (iframeSrc) {
|
1273 |
+
const newPage = await browser.newPage();
|
1274 |
+
await newPage.goto(iframeSrc, { waitUntil: "domcontentloaded" });
|
1275 |
+
|
1276 |
+
// Ambil data-id dari elemen <li>
|
1277 |
+
const dataId = await newPage.evaluate(() => {
|
1278 |
+
const element = document.querySelector(".servers ul li");
|
1279 |
+
return element ? "https://nhplayer.com" + element.getAttribute("data-id") : null;
|
|
|
|
|
|
|
|
|
|
|
1280 |
});
|
1281 |
+
|
1282 |
+
console.log("Data-ID URL:", dataId);
|
1283 |
+
|
1284 |
+
if (dataId) {
|
1285 |
+
// Ambil data video dari URL data-id
|
1286 |
+
const { data: html } = await axios.get(dataId);
|
1287 |
+
const $ = cheerio.load(html);
|
1288 |
+
const scripts = $("script");
|
1289 |
+
|
1290 |
+
scripts.each((i, script) => {
|
1291 |
+
const scriptContent = $(script).html();
|
1292 |
+
if (scriptContent && scriptContent.includes("jwplayer.setup")) {
|
1293 |
+
const match = scriptContent.match(/file:\s*"(https?:\/\/[^"]+\.mp4)"/);
|
1294 |
+
if (match && match[1]) {
|
1295 |
+
video = match[1];
|
1296 |
+
}
|
1297 |
+
}
|
1298 |
+
});
|
1299 |
+
}
|
1300 |
+
|
1301 |
+
await newPage.close();
|
1302 |
}
|
1303 |
|
1304 |
+
// Tambahkan video ke hasil metadata
|
1305 |
result.video = video;
|
1306 |
|
1307 |
+
// Tutup browser
|
1308 |
await browser.close();
|
1309 |
+
|
1310 |
return result;
|
1311 |
} catch (error) {
|
1312 |
console.error("Error scraping details:", error);
|
1313 |
+
|
1314 |
+
// Tutup browser jika ada kesalahan
|
1315 |
await browser.close();
|
1316 |
+
return { error: error.message };
|
1317 |
}
|
1318 |
}
|
1319 |
|
1320 |
|
1321 |
|
1322 |
+
|
1323 |
app.get('/hanime/search', async (req, res) => {
|
1324 |
const { query } = req.query;
|
1325 |
if (!query) {
|