feat: KöPi - 11er Kasten mit kasten_front.png
This commit is contained in:
@@ -99,41 +99,37 @@ async function scrapeMarktguru() {
|
|||||||
const description = descEl?.textContent?.trim() || '';
|
const description = descEl?.textContent?.trim() || '';
|
||||||
const img = card.querySelector('img.offer-list-item-img');
|
const img = card.querySelector('img.offer-list-item-img');
|
||||||
const badge = card.querySelector('.badge, .discount-badge')?.textContent?.trim() || '';
|
const badge = card.querySelector('.badge, .discount-badge')?.textContent?.trim() || '';
|
||||||
const imgSrc = img?.src || null;
|
const imgSrc = img?.src?.replace('/medium.webp', '/large.webp') || img?.src || null;
|
||||||
return { name, brand, price, oldPrice, retailer, dateRange, validity, description, badge, address: '', image: imgSrc };
|
return { name, brand, price, oldPrice, retailer, dateRange, validity, description, badge, address: '', image: imgSrc };
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Bilder via Node https mit exakten Browser-Headers laden
|
// Lokale Bilder auswählen basierend auf Beschreibung
|
||||||
const nodeHttps = require('https');
|
for (const offer of offers) {
|
||||||
for (let i = 0; i < offers.length; i++) {
|
const desc = (offer.description || '').toLowerCase();
|
||||||
const url = offers[i].image;
|
if (desc.includes('steini')) {
|
||||||
if (!url || !url.startsWith('https://')) continue;
|
// Steini-Kasten
|
||||||
offers[i].image = await new Promise(resolve => {
|
offer.imageLocal = '/koepi/kasten_steini.png';
|
||||||
const req = nodeHttps.get(url, {
|
} else if (desc.includes('0,33') && (desc.includes('24') || desc.includes('24 x'))) {
|
||||||
headers: {
|
// 24x0,33l Kasten
|
||||||
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
|
offer.imageLocal = '/koepi/kasten_033.png';
|
||||||
'Accept': 'image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8',
|
} else if (desc.includes('11') && desc.includes('0,5')) {
|
||||||
'Accept-Language': 'de-DE,de;q=0.9',
|
// 11x0,5l Kasten (von vorne)
|
||||||
'Referer': 'https://www.marktguru.de/',
|
offer.imageLocal = '/koepi/kasten_front.png';
|
||||||
'Origin': 'https://www.marktguru.de',
|
} else if (desc.includes('0,5') && (desc.includes('20') || desc.includes('20 x'))) {
|
||||||
'sec-fetch-dest': 'image',
|
// 20x0,5l Langhalsflasche
|
||||||
'sec-fetch-mode': 'no-cors',
|
offer.imageLocal = '/koepi/kasten_lang.png';
|
||||||
'sec-fetch-site': 'cross-site',
|
} else if (desc.includes('flasche') || desc.includes('6 x') || desc.includes('6x')) {
|
||||||
|
// 6er Träger
|
||||||
|
offer.imageLocal = '/koepi/traeger.png';
|
||||||
|
} else if (desc.includes('0,5')) {
|
||||||
|
offer.imageLocal = '/koepi/kasten_050.png';
|
||||||
|
} else if (desc.includes('0,33')) {
|
||||||
|
offer.imageLocal = '/koepi/kasten_033.png';
|
||||||
|
} else {
|
||||||
|
offer.imageLocal = '/koepi/kasten_050.png'; // default
|
||||||
}
|
}
|
||||||
}, res => {
|
offer.image = null; // CDN nicht mehr nötig
|
||||||
if (res.statusCode !== 200) return resolve(null);
|
|
||||||
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';
|
|
||||||
resolve(`data:${mime};base64,${b64}`);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
req.on('error', () => resolve(null));
|
|
||||||
req.setTimeout(8000, () => { req.destroy(); resolve(null); });
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Filtern auf Ziel-Händler + nur König Pilsener
|
// Filtern auf Ziel-Händler + nur König Pilsener
|
||||||
|
|||||||
BIN
frontend/public/koepi/kasten_033.png
Normal file
BIN
frontend/public/koepi/kasten_033.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 94 KiB |
BIN
frontend/public/koepi/kasten_050.png
Normal file
BIN
frontend/public/koepi/kasten_050.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 100 KiB |
BIN
frontend/public/koepi/kasten_lang.png
Normal file
BIN
frontend/public/koepi/kasten_lang.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 114 KiB |
BIN
frontend/public/koepi/kasten_steini.png
Normal file
BIN
frontend/public/koepi/kasten_steini.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 106 KiB |
BIN
frontend/public/koepi/traeger.png
Normal file
BIN
frontend/public/koepi/traeger.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 129 KiB |
@@ -34,12 +34,11 @@ function OfferCard({ offer }) {
|
|||||||
border:'1px solid rgba(255,255,255,0.1)',
|
border:'1px solid rgba(255,255,255,0.1)',
|
||||||
display:'flex', flexDirection:'column', gap:8,
|
display:'flex', flexDirection:'column', gap:8,
|
||||||
}}>
|
}}>
|
||||||
{/* Bild oben, volle Breite */}
|
{/* Bild oben */}
|
||||||
{offer.image && (
|
{offer.imageLocal && (
|
||||||
<div style={{ margin:'-12px -14px 8px -14px', borderRadius:'8px 8px 0 0', overflow:'hidden', background:'#1a1a1a', display:'flex', alignItems:'center', justifyContent:'center', maxHeight:220 }}>
|
<div style={{ margin:'-12px -14px 8px -14px', borderRadius:'8px 8px 0 0', background:'transparent', height:180, display:'flex', alignItems:'center', justifyContent:'center' }}>
|
||||||
<img src={offer.image} alt="König Pilsener"
|
<img src={offer.imageLocal} alt="König Pilsener"
|
||||||
style={{ maxWidth:'100%', maxHeight:220, width:'auto', height:'auto', display:'block', objectFit:'contain' }}
|
style={{ maxWidth:'100%', maxHeight:'180px', width:'auto', height:'auto', display:'block', objectFit:'contain' }}
|
||||||
onError={e => { e.target.parentElement.style.display='none'; }}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|||||||
Reference in New Issue
Block a user