Update server.js
Browse files
server.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
| 1 |
-
// server.js (Complete Playwright Version with CF Bypass)
|
| 2 |
|
| 3 |
import express, { json } from "express";
|
| 4 |
import cors from "cors";
|
|
@@ -24,7 +24,7 @@ let browserPool;
|
|
| 24 |
const cache = new LRUCache({ max: 500, ttl: 15 * 60 * 1000 });
|
| 25 |
const limit = pLimit(2);
|
| 26 |
|
| 27 |
-
//
|
| 28 |
async function handleSpecificTurnstile(page, domain) {
|
| 29 |
try {
|
| 30 |
// Wait for the page to fully load
|
|
@@ -37,6 +37,7 @@ async function handleSpecificTurnstile(page, domain) {
|
|
| 37 |
console.log(`[${domain}] No Turnstile detected`);
|
| 38 |
return;
|
| 39 |
}
|
|
|
|
| 40 |
console.log(`[${domain}] Turnstile detected - bypassing...`);
|
| 41 |
|
| 42 |
// Wait for the turnstile to be interactive
|
|
@@ -66,6 +67,7 @@ async function handleSpecificTurnstile(page, domain) {
|
|
| 66 |
form.submit();
|
| 67 |
});
|
| 68 |
});
|
|
|
|
| 69 |
// Wait for navigation or network idle
|
| 70 |
try {
|
| 71 |
await Promise.race([
|
|
@@ -77,17 +79,21 @@ async function handleSpecificTurnstile(page, domain) {
|
|
| 77 |
}
|
| 78 |
|
| 79 |
console.log(`[${domain}] Turnstile bypass completed`);
|
|
|
|
| 80 |
} catch (error) {
|
| 81 |
console.warn(`[${domain}] Turnstile bypass warning: ${error.message}`);
|
| 82 |
}
|
| 83 |
}
|
|
|
|
| 84 |
async function extractFirstIframeSrc(page, domain) {
|
| 85 |
try {
|
|
|
|
| 86 |
await page.waitForSelector('#player_iframe', {
|
| 87 |
state: 'attached',
|
| 88 |
timeout: 15000
|
| 89 |
});
|
| 90 |
|
|
|
|
| 91 |
const frame = await page.frame('#player_iframe');
|
| 92 |
return frame ? frame.url() : null;
|
| 93 |
} catch (error) {
|
|
@@ -98,13 +104,15 @@ async function extractFirstIframeSrc(page, domain) {
|
|
| 98 |
|
| 99 |
async function extractFinalIframeSrc(page, domain) {
|
| 100 |
try {
|
|
|
|
| 101 |
await page.waitForFunction(() => {
|
| 102 |
return document.querySelectorAll('script, iframe').length > 0;
|
| 103 |
}, { timeout: 15000 });
|
| 104 |
|
|
|
|
| 105 |
const frames = await page.frames();
|
| 106 |
const visibleFrame = frames.find(frame => {
|
| 107 |
-
return !frame.$('iframe[style*="display:none"]');
|
| 108 |
});
|
| 109 |
|
| 110 |
return visibleFrame?.url();
|
|
@@ -173,7 +181,8 @@ async function scrapeProvider(domain, url, signal) {
|
|
| 173 |
userAgent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36",
|
| 174 |
ignoreHTTPSErrors: true,
|
| 175 |
javaScriptEnabled: true,
|
| 176 |
-
bypassCSP: true
|
|
|
|
| 177 |
});
|
| 178 |
|
| 179 |
await context.addInitScript(() => {
|
|
@@ -203,10 +212,14 @@ async function scrapeProvider(domain, url, signal) {
|
|
| 203 |
// Stage 1: Initial page
|
| 204 |
console.log(`[${domain}] Navigating and waiting for network to be idle...`);
|
| 205 |
await page.goto(url, {
|
| 206 |
-
waitUntil: '
|
| 207 |
timeout: 60000
|
| 208 |
});
|
| 209 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 210 |
await handleSpecificTurnstile(page, domain);
|
| 211 |
|
| 212 |
const firstIframeSrc = await extractFirstIframeSrc(page, domain);
|
|
@@ -216,9 +229,14 @@ async function scrapeProvider(domain, url, signal) {
|
|
| 216 |
// Stage 2: First iframe
|
| 217 |
const iframePage = await context.newPage();
|
| 218 |
await iframePage.goto(firstIframeSrc, {
|
| 219 |
-
waitUntil: '
|
| 220 |
timeout: 60000
|
| 221 |
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 222 |
await handleSpecificTurnstile(iframePage, domain);
|
| 223 |
|
| 224 |
const finalIframeSrc = await extractFinalIframeSrc(iframePage, domain);
|
|
|
|
| 1 |
+
// server.js (Complete Playwright Version with CF Bypass - Updated)
|
| 2 |
|
| 3 |
import express, { json } from "express";
|
| 4 |
import cors from "cors";
|
|
|
|
| 24 |
const cache = new LRUCache({ max: 500, ttl: 15 * 60 * 1000 });
|
| 25 |
const limit = pLimit(2);
|
| 26 |
|
| 27 |
+
// Updated Turnstile bypass function
|
| 28 |
async function handleSpecificTurnstile(page, domain) {
|
| 29 |
try {
|
| 30 |
// Wait for the page to fully load
|
|
|
|
| 37 |
console.log(`[${domain}] No Turnstile detected`);
|
| 38 |
return;
|
| 39 |
}
|
| 40 |
+
|
| 41 |
console.log(`[${domain}] Turnstile detected - bypassing...`);
|
| 42 |
|
| 43 |
// Wait for the turnstile to be interactive
|
|
|
|
| 67 |
form.submit();
|
| 68 |
});
|
| 69 |
});
|
| 70 |
+
|
| 71 |
// Wait for navigation or network idle
|
| 72 |
try {
|
| 73 |
await Promise.race([
|
|
|
|
| 79 |
}
|
| 80 |
|
| 81 |
console.log(`[${domain}] Turnstile bypass completed`);
|
| 82 |
+
|
| 83 |
} catch (error) {
|
| 84 |
console.warn(`[${domain}] Turnstile bypass warning: ${error.message}`);
|
| 85 |
}
|
| 86 |
}
|
| 87 |
+
|
| 88 |
async function extractFirstIframeSrc(page, domain) {
|
| 89 |
try {
|
| 90 |
+
// Wait for iframe to be available
|
| 91 |
await page.waitForSelector('#player_iframe', {
|
| 92 |
state: 'attached',
|
| 93 |
timeout: 15000
|
| 94 |
});
|
| 95 |
|
| 96 |
+
// Get the iframe URL
|
| 97 |
const frame = await page.frame('#player_iframe');
|
| 98 |
return frame ? frame.url() : null;
|
| 99 |
} catch (error) {
|
|
|
|
| 104 |
|
| 105 |
async function extractFinalIframeSrc(page, domain) {
|
| 106 |
try {
|
| 107 |
+
// Wait for content to load
|
| 108 |
await page.waitForFunction(() => {
|
| 109 |
return document.querySelectorAll('script, iframe').length > 0;
|
| 110 |
}, { timeout: 15000 });
|
| 111 |
|
| 112 |
+
// Get all frames and find the visible one
|
| 113 |
const frames = await page.frames();
|
| 114 |
const visibleFrame = frames.find(frame => {
|
| 115 |
+
return !await frame.$('iframe[style*="display:none"]');
|
| 116 |
});
|
| 117 |
|
| 118 |
return visibleFrame?.url();
|
|
|
|
| 181 |
userAgent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36",
|
| 182 |
ignoreHTTPSErrors: true,
|
| 183 |
javaScriptEnabled: true,
|
| 184 |
+
bypassCSP: true,
|
| 185 |
+
viewport: { width: 1920, height: 1080 }
|
| 186 |
});
|
| 187 |
|
| 188 |
await context.addInitScript(() => {
|
|
|
|
| 212 |
// Stage 1: Initial page
|
| 213 |
console.log(`[${domain}] Navigating and waiting for network to be idle...`);
|
| 214 |
await page.goto(url, {
|
| 215 |
+
waitUntil: 'domcontentloaded',
|
| 216 |
timeout: 60000
|
| 217 |
});
|
| 218 |
|
| 219 |
+
// Wait a bit more for any dynamic content
|
| 220 |
+
await page.waitForTimeout(5000);
|
| 221 |
+
|
| 222 |
+
// Handle turnstile
|
| 223 |
await handleSpecificTurnstile(page, domain);
|
| 224 |
|
| 225 |
const firstIframeSrc = await extractFirstIframeSrc(page, domain);
|
|
|
|
| 229 |
// Stage 2: First iframe
|
| 230 |
const iframePage = await context.newPage();
|
| 231 |
await iframePage.goto(firstIframeSrc, {
|
| 232 |
+
waitUntil: 'domcontentloaded',
|
| 233 |
timeout: 60000
|
| 234 |
});
|
| 235 |
+
|
| 236 |
+
// Wait a bit more for any dynamic content
|
| 237 |
+
await iframePage.waitForTimeout(5000);
|
| 238 |
+
|
| 239 |
+
// Handle turnstile in iframe
|
| 240 |
await handleSpecificTurnstile(iframePage, domain);
|
| 241 |
|
| 242 |
const finalIframeSrc = await extractFinalIframeSrc(iframePage, domain);
|