fix: KöPi - Bilder via Node+Cookies, NEU Badge weg, Prospekt URLs
This commit is contained in:
@@ -89,27 +89,32 @@ async function scrapeMarktguru() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Bilder als Base64 laden (cdn.marktguru.de blockt externe Requests)
|
// Bilder über Node https laden mit Cookies aus dem Browser
|
||||||
for (const offer of offers) {
|
const cookies = await page.cookies('https://cdn.marktguru.de');
|
||||||
if (!offer.image) continue;
|
const cookieStr = cookies.map(c => `${c.name}=${c.value}`).join('; ');
|
||||||
try {
|
|
||||||
const imgData = await page.evaluate(async (url) => {
|
await Promise.all(offers.map(offer => new Promise(resolve => {
|
||||||
try {
|
if (!offer.image) return resolve();
|
||||||
const resp = await fetch(url, {credentials:'include'});
|
const req = require('https').get(offer.image, {
|
||||||
if (!resp.ok) return null;
|
headers: {
|
||||||
const blob = await resp.blob();
|
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
|
||||||
return new Promise(resolve => {
|
'Referer': 'https://www.marktguru.de/',
|
||||||
const reader = new FileReader();
|
'Cookie': cookieStr,
|
||||||
reader.onloadend = () => resolve(reader.result);
|
}
|
||||||
reader.onerror = () => resolve(null);
|
}, res => {
|
||||||
reader.readAsDataURL(blob);
|
if (res.statusCode !== 200) { offer.image = null; return resolve(); }
|
||||||
});
|
const chunks = [];
|
||||||
} catch { return null; }
|
res.on('data', c => chunks.push(c));
|
||||||
}, offer.image);
|
res.on('end', () => {
|
||||||
if (imgData) offer.image = imgData;
|
const b64 = Buffer.concat(chunks).toString('base64');
|
||||||
else offer.image = null;
|
const mime = res.headers['content-type'] || 'image/webp';
|
||||||
} catch { offer.image = null; }
|
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
|
// Filtern auf Ziel-Händler + nur König Pilsener
|
||||||
const filtered = offers.filter(o => {
|
const filtered = offers.filter(o => {
|
||||||
@@ -209,7 +214,7 @@ async function scrapeProspekte() {
|
|||||||
validFrom: c.validFrom || null,
|
validFrom: c.validFrom || null,
|
||||||
validTo: c.validUntil || null,
|
validTo: c.validUntil || null,
|
||||||
pageCount: c.pageCount || null,
|
pageCount: c.pageCount || null,
|
||||||
url: `https://www.kaufda.de/webapp/brochure/${id}`,
|
url: `https://www.kaufda.de/Prospekte/${encodeURIComponent(pub.replace(/\s+/g,'-'))}?brochureId=${id}`,
|
||||||
isTarget: isTargetRetailer(pub),
|
isTarget: isTargetRetailer(pub),
|
||||||
badges: c.contentBadges?.map(b => b.name) || [],
|
badges: c.contentBadges?.map(b => b.name) || [],
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -128,10 +128,11 @@ function ProspektCard({ b }) {
|
|||||||
onError={e => { e.target.style.display='none'; }}
|
onError={e => { e.target.style.display='none'; }}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<div style={{ position:'absolute', top:6, left:6, display:'flex', gap:4 }}>
|
{expiring && (
|
||||||
{isNew && <span style={{ background:'#4ecdc4', color:'#000', borderRadius:4, padding:'2px 6px', fontSize:9, fontFamily:'monospace', fontWeight:700 }}>NEU</span>}
|
<div style={{ position:'absolute', top:6, left:6 }}>
|
||||||
{expiring && <span style={{ background:'#ef4444', color:'#fff', borderRadius:4, padding:'2px 6px', fontSize:9, fontFamily:'monospace', fontWeight:700 }}>ENDET BALD</span>}
|
<span style={{ background:'#ef4444', color:'#fff', borderRadius:4, padding:'2px 6px', fontSize:9, fontFamily:'monospace', fontWeight:700 }}>ENDET BALD</span>
|
||||||
</div>
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div style={{ padding:'10px 12px' }}>
|
<div style={{ padding:'10px 12px' }}>
|
||||||
<div style={{ display:'inline-block', background:`${color}22`, border:`1px solid ${color}44`,
|
<div style={{ display:'inline-block', background:`${color}22`, border:`1px solid ${color}44`,
|
||||||
|
|||||||
Reference in New Issue
Block a user