diff --git a/backend/src/tools/koepi/routes.js b/backend/src/tools/koepi/routes.js index 7a0f618..dc8e0b8 100644 --- a/backend/src/tools/koepi/routes.js +++ b/backend/src/tools/koepi/routes.js @@ -95,36 +95,19 @@ async function scrapeMarktguru() { }); }); - // Bilder via Puppeteer: URL direkt aus img src holen und über page.goto laden - const imgElements = await page.$$('img.offer-list-item-img'); + // Bilder: separaten Tab öffnen pro Bild-URL und screenshotten + const imgPage = await browser.newPage(); + await imgPage.setViewport({ width: 300, height: 300 }); for (let i = 0; i < offers.length; i++) { - if (!offers[i].image || !imgElements[i]) continue; + const url = offers[i].image; + if (!url || !url.startsWith('https://')) continue; try { - // Viewport auf Bildgröße setzen damit kein Zoom-Effekt entsteht - await page.evaluate(el => new Promise(res => { - if (el.complete && el.naturalWidth > 0) return res(); - el.onload = res; el.onerror = res; - setTimeout(res, 5000); - }), imgElements[i]); - - // Bounding Box prüfen - const box = await imgElements[i].boundingBox(); - if (!box || box.width < 5 || box.height < 5) { - offers[i].image = null; - continue; - } - - // Screenshot mit clip auf vernünftige Größe - const clip = { - x: box.x, - y: box.y, - width: Math.min(box.width, 300), - height: Math.min(box.height, 300), - }; - const b64 = await page.screenshot({ encoding: 'base64', clip }); + await imgPage.goto(url, { waitUntil: 'networkidle0', timeout: 10000 }); + const b64 = await imgPage.screenshot({ encoding: 'base64' }); offers[i].image = b64 ? `data:image/png;base64,${b64}` : null; } catch { offers[i].image = null; } } + await imgPage.close(); // Filtern auf Ziel-Händler + nur König Pilsener const filtered = offers.filter(o => {