| const express = require('express'); |
| const axios = require('axios'); |
| const tough = require('tough-cookie'); |
| const { HttpsCookieAgent } = require('http-cookie-agent/http'); |
| const cheerio = require('cheerio'); |
| const https = require('https'); |
| const { randomBytes } = require('crypto'); |
|
|
| const app = express(); |
| const PORT = process.env.PORT || 3000; |
|
|
| app.use(express.json()); |
|
|
| |
| function generateFingerprint() { |
| const browsers = [ |
| { |
| name: 'Chrome', |
| version: '120.0.0.0', |
| userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', |
| secChUa: '"Not_A Brand";v="8", "Chromium";v="120", "Google Chrome";v="120"' |
| }, |
| { |
| name: 'Chrome', |
| version: '119.0.0.0', |
| userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36', |
| secChUa: '"Not_A Brand";v="8", "Chromium";v="119", "Google Chrome";v="119"' |
| }, |
| { |
| name: 'Chrome', |
| version: '121.0.0.0', |
| userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36', |
| secChUa: '"Not_A Brand";v="8", "Chromium";v="121", "Google Chrome";v="121"' |
| }, |
| { |
| name: 'Firefox', |
| version: '122.0', |
| userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:122.0) Gecko/20100101 Firefox/122.0', |
| secChUa: null |
| }, |
| { |
| name: 'Edge', |
| version: '120.0.0.0', |
| userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 Edg/120.0.0.0', |
| secChUa: '"Not_A Brand";v="8", "Chromium";v="120", "Microsoft Edge";v="120"' |
| } |
| ]; |
|
|
| return browsers[Math.floor(Math.random() * browsers.length)]; |
| } |
|
|
| |
| function randomDelay(min = 500, max = 2000) { |
| return new Promise(resolve => setTimeout(resolve, Math.floor(Math.random() * (max - min)) + min)); |
| } |
|
|
| |
| async function extractWithAdvancedAxios(url) { |
| try { |
| const fingerprint = generateFingerprint(); |
| const cookieJar = new tough.CookieJar(); |
| |
| |
| const httpsAgent = new https.Agent({ |
| rejectUnauthorized: false, |
| minVersion: 'TLSv1.2', |
| maxVersion: 'TLSv1.3', |
| ciphers: [ |
| 'TLS_AES_128_GCM_SHA256', |
| 'TLS_AES_256_GCM_SHA384', |
| 'TLS_CHACHA20_POLY1305_SHA256', |
| 'ECDHE-ECDSA-AES128-GCM-SHA256', |
| 'ECDHE-RSA-AES128-GCM-SHA256', |
| 'ECDHE-ECDSA-AES256-GCM-SHA384', |
| 'ECDHE-RSA-AES256-GCM-SHA384' |
| ].join(':'), |
| honorCipherOrder: true, |
| secureOptions: require('constants').SSL_OP_NO_SSLv2 | require('constants').SSL_OP_NO_SSLv3 |
| }); |
|
|
| const cookieAgent = new HttpsCookieAgent({ |
| cookies: { jar: cookieJar }, |
| ...httpsAgent.options |
| }); |
|
|
| const headers = { |
| 'User-Agent': fingerprint.userAgent, |
| 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7', |
| 'Accept-Language': 'en-US,en;q=0.9', |
| 'Accept-Encoding': 'gzip, deflate, br', |
| 'DNT': '1', |
| 'Connection': 'keep-alive', |
| 'Upgrade-Insecure-Requests': '1', |
| 'Sec-Fetch-Dest': 'document', |
| 'Sec-Fetch-Mode': 'navigate', |
| 'Sec-Fetch-Site': 'none', |
| 'Sec-Fetch-User': '?1', |
| 'sec-ch-ua-mobile': '?0', |
| 'sec-ch-ua-platform': '"Windows"', |
| 'Cache-Control': 'max-age=0', |
| 'Pragma': 'no-cache' |
| }; |
|
|
| if (fingerprint.secChUa) { |
| headers['sec-ch-ua'] = fingerprint.secChUa; |
| } |
|
|
| const client = axios.create({ |
| httpsAgent: cookieAgent, |
| headers: headers, |
| maxRedirects: 10, |
| validateStatus: () => true, |
| timeout: 30000, |
| decompress: true |
| }); |
|
|
| |
| await randomDelay(300, 800); |
| const response = await client.get(url); |
|
|
| if (response.status === 403) { |
| throw new Error('403 Forbidden - Access Denied'); |
| } |
|
|
| const html = response.data; |
| const $ = cheerio.load(html); |
|
|
| const iframe = $('iframe.embed-responsive-item'); |
| const iframeExists = iframe.length > 0; |
| const iframeSrc = iframe.attr('src') || null; |
|
|
| const downloadSection = $('.download-form, .message.video-details, .download'); |
| const downloadSectionExists = downloadSection.length > 0; |
|
|
| const fileName = $('strong').first().text().trim() || null; |
| const fileSize = $('abbr[title*="Bytes"]').text().trim() || null; |
| const resolution = $('.column:contains("Resolution")').text().replace('Resolution:', '').trim() || null; |
|
|
| return { |
| success: true, |
| url: url, |
| iframeExists: iframeExists, |
| iframeSrc: iframeSrc, |
| downloadSectionExists: downloadSectionExists, |
| fileDetails: { |
| fileName: fileName, |
| fileSize: fileSize, |
| resolution: resolution |
| }, |
| method: 'advanced-axios' |
| }; |
|
|
| } catch (error) { |
| console.error('advanced-axios error:', error.message); |
| return { |
| success: false, |
| error: error.message, |
| method: 'advanced-axios' |
| }; |
| } |
| } |
|
|
| |
| async function extractWithUndici(url) { |
| try { |
| const { request } = require('undici'); |
| const fingerprint = generateFingerprint(); |
|
|
| await randomDelay(300, 800); |
|
|
| const { statusCode, headers, body } = await request(url, { |
| method: 'GET', |
| headers: { |
| 'User-Agent': fingerprint.userAgent, |
| 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8', |
| 'Accept-Language': 'en-US,en;q=0.9', |
| 'Accept-Encoding': 'gzip, deflate, br', |
| 'DNT': '1', |
| 'Connection': 'keep-alive', |
| 'Upgrade-Insecure-Requests': '1', |
| 'Sec-Fetch-Dest': 'document', |
| 'Sec-Fetch-Mode': 'navigate', |
| 'Sec-Fetch-Site': 'none', |
| 'Sec-Fetch-User': '?1', |
| 'sec-ch-ua': fingerprint.secChUa || '', |
| 'sec-ch-ua-mobile': '?0', |
| 'sec-ch-ua-platform': '"Windows"', |
| 'Cache-Control': 'max-age=0' |
| }, |
| maxRedirections: 10 |
| }); |
|
|
| if (statusCode === 403) { |
| throw new Error('403 Forbidden - Access Denied'); |
| } |
|
|
| let html = ''; |
| for await (const chunk of body) { |
| html += chunk.toString(); |
| } |
|
|
| const $ = cheerio.load(html); |
|
|
| const iframe = $('iframe.embed-responsive-item'); |
| const iframeExists = iframe.length > 0; |
| const iframeSrc = iframe.attr('src') || null; |
|
|
| const downloadSection = $('.download-form, .message.video-details, .download'); |
| const downloadSectionExists = downloadSection.length > 0; |
|
|
| const fileName = $('strong').first().text().trim() || null; |
| const fileSize = $('abbr[title*="Bytes"]').text().trim() || null; |
| const resolution = $('.column:contains("Resolution")').text().replace('Resolution:', '').trim() || null; |
|
|
| return { |
| success: true, |
| url: url, |
| iframeExists: iframeExists, |
| iframeSrc: iframeSrc, |
| downloadSectionExists: downloadSectionExists, |
| fileDetails: { |
| fileName: fileName, |
| fileSize: fileSize, |
| resolution: resolution |
| }, |
| method: 'undici' |
| }; |
|
|
| } catch (error) { |
| console.error('undici error:', error.message); |
| return { |
| success: false, |
| error: error.message, |
| method: 'undici' |
| }; |
| } |
| } |
|
|
| |
| async function extractWithNodeFetch(url) { |
| try { |
| const fetch = require('node-fetch'); |
| const fingerprint = generateFingerprint(); |
|
|
| |
| const httpsAgent = new https.Agent({ |
| rejectUnauthorized: false, |
| minVersion: 'TLSv1.2', |
| maxVersion: 'TLSv1.3' |
| }); |
|
|
| await randomDelay(300, 800); |
|
|
| const response = await fetch(url, { |
| method: 'GET', |
| headers: { |
| 'User-Agent': fingerprint.userAgent, |
| 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8', |
| 'Accept-Language': 'en-US,en;q=0.9', |
| 'Accept-Encoding': 'gzip, deflate, br', |
| 'DNT': '1', |
| 'Connection': 'keep-alive', |
| 'Upgrade-Insecure-Requests': '1', |
| 'Sec-Fetch-Dest': 'document', |
| 'Sec-Fetch-Mode': 'navigate', |
| 'Sec-Fetch-Site': 'none', |
| 'Sec-Fetch-User': '?1', |
| 'sec-ch-ua': fingerprint.secChUa || '', |
| 'sec-ch-ua-mobile': '?0', |
| 'sec-ch-ua-platform': '"Windows"', |
| 'Cache-Control': 'max-age=0', |
| 'Pragma': 'no-cache' |
| }, |
| agent: httpsAgent, |
| redirect: 'follow', |
| follow: 10, |
| compress: true |
| }); |
|
|
| if (response.status === 403) { |
| throw new Error('403 Forbidden - Access Denied'); |
| } |
|
|
| const html = await response.text(); |
| const $ = cheerio.load(html); |
|
|
| const iframe = $('iframe.embed-responsive-item'); |
| const iframeExists = iframe.length > 0; |
| const iframeSrc = iframe.attr('src') || null; |
|
|
| const downloadSection = $('.download-form, .message.video-details, .download'); |
| const downloadSectionExists = downloadSection.length > 0; |
|
|
| const fileName = $('strong').first().text().trim() || null; |
| const fileSize = $('abbr[title*="Bytes"]').text().trim() || null; |
| const resolution = $('.column:contains("Resolution")').text().replace('Resolution:', '').trim() || null; |
|
|
| return { |
| success: true, |
| url: url, |
| iframeExists: iframeExists, |
| iframeSrc: iframeSrc, |
| downloadSectionExists: downloadSectionExists, |
| fileDetails: { |
| fileName: fileName, |
| fileSize: fileSize, |
| resolution: resolution |
| }, |
| method: 'node-fetch' |
| }; |
|
|
| } catch (error) { |
| console.error('node-fetch error:', error.message); |
| return { |
| success: false, |
| error: error.message, |
| method: 'node-fetch' |
| }; |
| } |
| } |
|
|
| |
| async function extractWithRequestPromise(url) { |
| try { |
| const request = require('request-promise-native'); |
| const fingerprint = generateFingerprint(); |
|
|
| await randomDelay(300, 800); |
|
|
| const options = { |
| uri: url, |
| method: 'GET', |
| headers: { |
| 'User-Agent': fingerprint.userAgent, |
| 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8', |
| 'Accept-Language': 'en-US,en;q=0.9', |
| 'Accept-Encoding': 'gzip, deflate, br', |
| 'DNT': '1', |
| 'Connection': 'keep-alive', |
| 'Upgrade-Insecure-Requests': '1', |
| 'Sec-Fetch-Dest': 'document', |
| 'Sec-Fetch-Mode': 'navigate', |
| 'Sec-Fetch-Site': 'none', |
| 'Sec-Fetch-User': '?1', |
| 'sec-ch-ua': fingerprint.secChUa || '', |
| 'sec-ch-ua-mobile': '?0', |
| 'sec-ch-ua-platform': '"Windows"', |
| 'Cache-Control': 'max-age=0' |
| }, |
| followRedirect: true, |
| maxRedirects: 10, |
| gzip: true, |
| jar: true, |
| simple: false, |
| resolveWithFullResponse: true, |
| agentOptions: { |
| rejectUnauthorized: false, |
| secureProtocol: 'TLSv1_2_method' |
| } |
| }; |
|
|
| const response = await request(options); |
|
|
| if (response.statusCode === 403) { |
| throw new Error('403 Forbidden - Access Denied'); |
| } |
|
|
| const html = response.body; |
| const $ = cheerio.load(html); |
|
|
| const iframe = $('iframe.embed-responsive-item'); |
| const iframeExists = iframe.length > 0; |
| const iframeSrc = iframe.attr('src') || null; |
|
|
| const downloadSection = $('.download-form, .message.video-details, .download'); |
| const downloadSectionExists = downloadSection.length > 0; |
|
|
| const fileName = $('strong').first().text().trim() || null; |
| const fileSize = $('abbr[title*="Bytes"]').text().trim() || null; |
| const resolution = $('.column:contains("Resolution")').text().replace('Resolution:', '').trim() || null; |
|
|
| return { |
| success: true, |
| url: url, |
| iframeExists: iframeExists, |
| iframeSrc: iframeSrc, |
| downloadSectionExists: downloadSectionExists, |
| fileDetails: { |
| fileName: fileName, |
| fileSize: fileSize, |
| resolution: resolution |
| }, |
| method: 'request-promise' |
| }; |
|
|
| } catch (error) { |
| console.error('request-promise error:', error.message); |
| return { |
| success: false, |
| error: error.message, |
| method: 'request-promise' |
| }; |
| } |
| } |
|
|
| |
| app.get('/extract', async (req, res) => { |
| const { url } = req.query; |
|
|
| if (!url) { |
| return res.status(400).json({ |
| success: false, |
| error: 'Missing "url" query parameter' |
| }); |
| } |
|
|
| if (!url.includes('kwik.cx') && !url.includes('kwik.si')) { |
| return res.status(400).json({ |
| success: false, |
| error: 'Invalid URL - must be a kwik.cx or kwik.si URL' |
| }); |
| } |
|
|
| console.log(`[REQUEST] Extracting data from: ${url}`); |
|
|
| |
| const methods = [ |
| extractWithAdvancedAxios, |
| extractWithUndici, |
| extractWithNodeFetch, |
| extractWithRequestPromise |
| ]; |
|
|
| let result = null; |
|
|
| for (const method of methods) { |
| try { |
| result = await method(url); |
| if (result.success) { |
| console.log(`[SUCCESS] Method: ${result.method}`); |
| console.log(`[SUCCESS] Iframe exists: ${result.iframeExists}`); |
| console.log(`[SUCCESS] Download section exists: ${result.downloadSectionExists}`); |
| break; |
| } else { |
| console.log(`[FAILED] Method: ${result.method} - ${result.error}`); |
| } |
| } catch (error) { |
| console.log(`[ERROR] Method failed: ${error.message}`); |
| } |
| } |
|
|
| if (!result || !result.success) { |
| return res.status(500).json({ |
| success: false, |
| error: 'All extraction methods failed', |
| lastError: result ? result.error : 'Unknown error' |
| }); |
| } |
|
|
| return res.json(result); |
| }); |
|
|
| |
| app.get('/health', (req, res) => { |
| res.json({ status: 'ok', timestamp: new Date().toISOString() }); |
| }); |
|
|
| |
| app.get('/', (req, res) => { |
| res.json({ |
| service: 'Kwik Extractor API', |
| version: '2.0.0', |
| endpoints: { |
| extract: '/extract?url=<kwik_url>', |
| health: '/health' |
| }, |
| example: '/extract?url=https://kwik.cx/f/0SoyAdDuRvy1', |
| methods: [ |
| 'advanced-axios', |
| 'undici', |
| 'node-fetch', |
| 'request-promise' |
| ] |
| }); |
| }); |
|
|
| app.listen(7860, () => { |
| console.log(`🚀 Server running on port ${PORT}`); |
| console.log(`📡 API endpoint: http://localhost:${PORT}/extract?url=<kwik_url>`); |
| }); |