fix: KöPi - alle Bilder im Browser-Kontext laden, dunkler Hintergrund
This commit is contained in:
@@ -89,33 +89,35 @@ async function scrapeMarktguru() {
|
||||
});
|
||||
});
|
||||
|
||||
// Bilder über Node https laden mit Cookies aus dem Browser
|
||||
const cookies = await page.cookies('https://cdn.marktguru.de');
|
||||
const cookieStr = cookies.map(c => `${c.name}=${c.value}`).join('; ');
|
||||
// Bilder alle auf einmal im Browser-Kontext laden (hat Zugriff auf CDN)
|
||||
const imageUrls = offers.map(o => o.image).filter(Boolean);
|
||||
if (imageUrls.length > 0) {
|
||||
const b64Images = await page.evaluate(async (urls) => {
|
||||
const results = {};
|
||||
await Promise.all(urls.map(async url => {
|
||||
try {
|
||||
const resp = await fetch(url);
|
||||
if (!resp.ok) { results[url] = null; return; }
|
||||
const blob = await resp.blob();
|
||||
results[url] = await new Promise(res => {
|
||||
const r = new FileReader();
|
||||
r.onloadend = () => res(r.result);
|
||||
r.onerror = () => res(null);
|
||||
r.readAsDataURL(blob);
|
||||
});
|
||||
} catch { results[url] = null; }
|
||||
}));
|
||||
return results;
|
||||
}, imageUrls);
|
||||
|
||||
// Sequenziell laden damit Cookie-Session stabil bleibt
|
||||
for (const offer of offers) { await new Promise(resolve => {
|
||||
if (!offer.image || !offer.image.startsWith('https://')) return resolve();
|
||||
const req = require('https').get(offer.image, {
|
||||
headers: {
|
||||
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
|
||||
'Referer': 'https://www.marktguru.de/',
|
||||
'Cookie': cookieStr,
|
||||
for (const offer of offers) {
|
||||
if (offer.image && b64Images[offer.image]) {
|
||||
offer.image = b64Images[offer.image];
|
||||
} else {
|
||||
offer.image = null;
|
||||
}
|
||||
}, res => {
|
||||
if (res.statusCode !== 200) { offer.image = null; return resolve(); }
|
||||
const chunks = [];
|
||||
res.on('data', c => chunks.push(c));
|
||||
res.on('end', () => {
|
||||
const b64 = Buffer.concat(chunks).toString('base64');
|
||||
const mime = res.headers['content-type'] || 'image/webp';
|
||||
offer.image = `data:${mime};base64,${b64}`;
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
req.on('error', () => { offer.image = null; resolve(); });
|
||||
req.setTimeout(8000, () => { req.destroy(); offer.image = null; resolve(); });
|
||||
}); }
|
||||
}
|
||||
}
|
||||
|
||||
// Filtern auf Ziel-Händler + nur König Pilsener
|
||||
const filtered = offers.filter(o => {
|
||||
|
||||
@@ -36,9 +36,9 @@ function OfferCard({ offer }) {
|
||||
}}>
|
||||
{/* Bild oben, volle Breite */}
|
||||
{offer.image && (
|
||||
<div style={{ margin:'-12px -14px 8px -14px', height:160, background:'#f0f0f0', borderRadius:'8px 8px 0 0', overflow:'hidden', display:'flex', alignItems:'center', justifyContent:'center' }}>
|
||||
<div style={{ margin:'-12px -14px 8px -14px', height:180, background:'#111', borderRadius:'8px 8px 0 0', overflow:'hidden', display:'flex', alignItems:'center', justifyContent:'center' }}>
|
||||
<img src={offer.image} alt="König Pilsener"
|
||||
style={{ width:'100%', height:'100%', objectFit:'contain' }}
|
||||
style={{ maxWidth:'100%', maxHeight:'100%', objectFit:'contain' }}
|
||||
onError={e => { e.target.parentElement.style.display='none'; }}
|
||||
/>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user