const express = require('express'); const puppeteer = require('puppeteer-extra'); const StealthPlugin = require('puppeteer-extra-plugin-stealth'); puppeteer.use(StealthPlugin()); const app = express(); const PORT = 7860; // Reusable launch options const launchOptions = { headless: 'new', args: [ '--no-sandbox', '--disable-setuid-sandbox', '--disable-blink-features=AutomationControlled', ], }; const userAgent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36'; /** * GET /get-image?url= * Scrapes the main pin image (736x if available) */ app.get('/get-image', async (req, res) => { const pinUrl = req.query.url; if (!pinUrl) return res.status(400).json({ error: 'Missing ?url=' }); let browser; try { browser = await puppeteer.launch(launchOptions); const page = await browser.newPage(); await page.setUserAgent(userAgent); await page.setViewport({ width: 1280, height: 800 }); await page.goto(pinUrl, { waitUntil: 'networkidle2' }); await page.evaluate(() => window.scrollBy(0, 200)); // lazy loading const imageUrl = await page.evaluate(() => { const images = Array.from(document.querySelectorAll('img')); const target = images.find(img => img.src.includes('pinimg.com/736x') ); return target ? target.src : null; }); if (!imageUrl) throw new Error('Main image not found'); res.json({ imageUrl }); } catch (err) { console.error('Error:', err.message); res.status(500).json({ error: err.message }); } finally { if (browser) await browser.close(); } }); /** * GET /search-images?q=sanji * Scrapes first 5 Pinterest search result images (736x best quality) */ app.get('/search-images', async (req, res) => { const query = req.query.q; if (!query) return res.status(400).json({ error: 'Missing ?q=' }); const searchUrl = `https://www.pinterest.com/search/pins/?q=${encodeURIComponent(query)}`; let browser; try { browser = await puppeteer.launch(launchOptions); const page = await browser.newPage(); await page.setUserAgent(userAgent); await page.setViewport({ width: 1280, height: 1000 }); await page.goto(searchUrl, { waitUntil: 'networkidle2' }); // Scroll to force lazy-loading await page.evaluate(() => window.scrollBy(0, 3000)); // Use native delay await new Promise(resolve => setTimeout(resolve, 2000)); const imageUrls = await page.evaluate(() => { const images = Array.from(document.querySelectorAll('img')); const urls = []; for (let img of images) { if (img.srcset) { const match = img.srcset.match(/https:\/\/i\.pinimg\.com\/736x\/[^ ]+/); if (match && !urls.includes(match[0])) { urls.push(match[0]); } } if (urls.length >= 5) break; } return urls; }); if (imageUrls.length === 0) throw new Error('No high-quality images found'); res.json({ images: imageUrls }); } catch (err) { console.error('Search Error:', err.message); res.status(500).json({ error: err.message }); } finally { if (browser) await browser.close(); } }); app.listen(PORT, () => { console.log(`Server running at http://localhost:${PORT}`); });