Spaces:
Running
Running
Update index.js
Browse files
index.js
CHANGED
@@ -1147,6 +1147,73 @@ app.get("/process-pixiv/:illustId", async (req, res) => {
|
|
1147 |
});
|
1148 |
|
1149 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1150 |
|
1151 |
// Fungsi untuk ping website
|
1152 |
async function pingWebsite() {
|
|
|
1147 |
});
|
1148 |
|
1149 |
|
1150 |
+
async function scrapeHAnime(query) {
|
1151 |
+
const baseUrl = "https://animeidhentai.com";
|
1152 |
+
const searchUrl = `${baseUrl}/?s=${encodeURIComponent(query)}`;
|
1153 |
+
const browser = await puppeteer.launch({
|
1154 |
+
headless: true,
|
1155 |
+
args: ['--no-sandbox', '--disable-setuid-sandbox']
|
1156 |
+
});
|
1157 |
+
const page = await browser.newPage();
|
1158 |
+
await page.goto(searchUrl, { waitUntil: 'domcontentloaded' });
|
1159 |
+
|
1160 |
+
try {
|
1161 |
+
// Ambil data video
|
1162 |
+
const videos = await page.evaluate(() => {
|
1163 |
+
return [...document.querySelectorAll("body > main > section > div.anime-list.dg.gt2.gg1.mgt1.a-gtf.v-grid > article")].map(article => {
|
1164 |
+
const urlElement = article.querySelector("a");
|
1165 |
+
const titleElement = article.querySelector("header > div");
|
1166 |
+
const descElement = article.querySelector("div.description.dn > p");
|
1167 |
+
const thumbnailElement = article.querySelector("div.anime-tb.pctr.rad1.por > figure > img");
|
1168 |
+
|
1169 |
+
return {
|
1170 |
+
url: urlElement ? urlElement.href : null,
|
1171 |
+
title: titleElement ? titleElement.textContent.trim() : null,
|
1172 |
+
description: descElement ? descElement.textContent.trim() : null,
|
1173 |
+
thumbnail: thumbnailElement ? thumbnailElement.src : null
|
1174 |
+
};
|
1175 |
+
});
|
1176 |
+
});
|
1177 |
+
|
1178 |
+
// Hitung halaman berikutnya
|
1179 |
+
const nextPage = await page.evaluate(() => {
|
1180 |
+
const nextButton = document.querySelector("body > main > section > div.pagination-wrapper > a.next.page-numbers.ljoptimizer");
|
1181 |
+
if (nextButton) {
|
1182 |
+
const currentUrl = window.location.href;
|
1183 |
+
const currentPageMatch = currentUrl.match(/page\/(\d+)/);
|
1184 |
+
const currentPage = currentPageMatch ? parseInt(currentPageMatch[1], 10) : 1;
|
1185 |
+
return currentPage + 1;
|
1186 |
+
}
|
1187 |
+
return null;
|
1188 |
+
});
|
1189 |
+
|
1190 |
+
const result = {
|
1191 |
+
next: nextPage ? `${baseUrl}/page/${nextPage}/?s=${encodeURIComponent(query)}` : null,
|
1192 |
+
videos
|
1193 |
+
};
|
1194 |
+
|
1195 |
+
await browser.close();
|
1196 |
+
return result;
|
1197 |
+
|
1198 |
+
} catch (error) {
|
1199 |
+
console.error("Error scraping data:", error);
|
1200 |
+
await browser.close();
|
1201 |
+
return { next: null, videos: [] };
|
1202 |
+
}
|
1203 |
+
}
|
1204 |
+
|
1205 |
+
app.get('/hanime/search', async (req, res) => {
|
1206 |
+
const { query } = req.query;
|
1207 |
+
if (!query) {
|
1208 |
+
return res.status(400).send('query is required');
|
1209 |
+
}
|
1210 |
+
try {
|
1211 |
+
const result = await scrapeHAnime(query);
|
1212 |
+
res.json(result);
|
1213 |
+
} catch (error) {
|
1214 |
+
res.status(500).send('Error processing request');
|
1215 |
+
}
|
1216 |
+
});
|
1217 |
|
1218 |
// Fungsi untuk ping website
|
1219 |
async function pingWebsite() {
|