fix: KöPi - Bild Proxy mit Referer, Adresse, kein Produktuntertitel
This commit is contained in:
@@ -66,8 +66,11 @@ async function scrapeMarktguru() {
|
|||||||
const descEl = card.querySelector('.info div, .info');
|
const descEl = card.querySelector('.info div, .info');
|
||||||
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, [class*="badge"]')?.textContent?.trim() || '';
|
const badge = card.querySelector('.badge, .discount-badge')?.textContent?.trim() || '';
|
||||||
return { name, brand, price, oldPrice, retailer, dateRange, validity, description, badge, image: img?.src || null };
|
const address = card.querySelector('.retailer-address, .address, dd.address, [class*="address"]')?.textContent?.trim() || '';
|
||||||
|
// Bild: medium → large für bessere Qualität
|
||||||
|
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 };
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -175,7 +178,7 @@ router.get('/img', authenticate, (req, res) => {
|
|||||||
const parsed = new URL(url);
|
const parsed = new URL(url);
|
||||||
const allowed = ['content-media.bonial.biz','publisher-media.bonial.biz','cdn.marktguru.de','www.marktguru.de'];
|
const allowed = ['content-media.bonial.biz','publisher-media.bonial.biz','cdn.marktguru.de','www.marktguru.de'];
|
||||||
if (!allowed.some(h => parsed.hostname === h)) return res.status(403).end();
|
if (!allowed.some(h => parsed.hostname === h)) return res.status(403).end();
|
||||||
const r = https.get(url, { headers: {'User-Agent':'Mozilla/5.0'} }, imgRes => {
|
const r = https.get(url, { headers: {'User-Agent':'Mozilla/5.0','Referer':'https://www.marktguru.de/','Origin':'https://www.marktguru.de'} }, imgRes => {
|
||||||
res.setHeader('Content-Type', imgRes.headers['content-type'] || 'image/jpeg');
|
res.setHeader('Content-Type', imgRes.headers['content-type'] || 'image/jpeg');
|
||||||
res.setHeader('Cache-Control', 'public, max-age=3600');
|
res.setHeader('Cache-Control', 'public, max-age=3600');
|
||||||
imgRes.pipe(res);
|
imgRes.pipe(res);
|
||||||
|
|||||||
@@ -35,42 +35,45 @@ function OfferCard({ offer }) {
|
|||||||
display:'flex', flexDirection:'column',
|
display:'flex', flexDirection:'column',
|
||||||
}}>
|
}}>
|
||||||
{/* Produktbild */}
|
{/* Produktbild */}
|
||||||
<div style={{ height:160, background:'#fff', display:'flex', alignItems:'center', justifyContent:'center', flexShrink:0, overflow:'hidden', position:'relative' }}>
|
{offer.image && (
|
||||||
{offer.image
|
<div style={{ height:160, background:'#f5f5f5', display:'flex', alignItems:'center', justifyContent:'center', flexShrink:0, overflow:'hidden', position:'relative' }}>
|
||||||
? <img src={`/api/tools/koepi/img?url=${encodeURIComponent(offer.image)}`}
|
<img
|
||||||
alt={offer.name} style={{ maxHeight:'100%', maxWidth:'100%', objectFit:'contain' }}
|
src={`/api/tools/koepi/img?url=${encodeURIComponent(offer.image)}`}
|
||||||
onError={e => { e.target.style.display='none'; }}
|
alt="König Pilsener"
|
||||||
|
style={{ maxHeight:'100%', maxWidth:'100%', objectFit:'contain' }}
|
||||||
|
onError={e => { e.target.parentElement.style.display='none'; }}
|
||||||
/>
|
/>
|
||||||
: null
|
{offer.oldPrice && (
|
||||||
}
|
|
||||||
{offer.badge && (
|
|
||||||
<div style={{ position:'absolute', top:6, left:6, background:'#e2001a', color:'#fff',
|
<div style={{ position:'absolute', top:6, left:6, background:'#e2001a', color:'#fff',
|
||||||
borderRadius:4, padding:'2px 6px', fontSize:9, fontFamily:'monospace', fontWeight:700 }}>
|
borderRadius:4, padding:'2px 6px', fontSize:9, fontFamily:'monospace', fontWeight:700 }}>
|
||||||
{offer.badge}
|
-29%
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<div style={{ padding:'12px 14px', flex:1, display:'flex', flexDirection:'column', gap:5 }}>
|
||||||
|
{/* Händler Badge + Adresse */}
|
||||||
|
<div>
|
||||||
|
<div style={{
|
||||||
|
display:'inline-block',
|
||||||
|
background:`${color}22`, border:`1px solid ${color}55`,
|
||||||
|
borderRadius:4, padding:'2px 8px', marginBottom:3,
|
||||||
|
color, fontFamily:'monospace', fontSize:10, fontWeight:700,
|
||||||
|
}}>{offer.retailer}</div>
|
||||||
|
{offer.address && (
|
||||||
|
<div style={{ color:'rgba(255,255,255,0.3)', fontFamily:'monospace', fontSize:9 }}>
|
||||||
|
📍 {offer.address}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style={{ padding:'12px 14px', flex:1, display:'flex', flexDirection:'column', gap:5 }}>
|
{/* König Pilsener */}
|
||||||
{/* Händler Badge */}
|
|
||||||
<div style={{
|
|
||||||
display:'inline-block', alignSelf:'flex-start',
|
|
||||||
background:`${color}22`, border:`1px solid ${color}55`,
|
|
||||||
borderRadius:4, padding:'2px 8px',
|
|
||||||
color, fontFamily:'monospace', fontSize:10, fontWeight:700,
|
|
||||||
}}>{offer.retailer}</div>
|
|
||||||
|
|
||||||
{/* Name + Marke */}
|
|
||||||
<div style={{ color:'#fff', fontFamily:'monospace', fontSize:13, fontWeight:600, lineHeight:1.3 }}>
|
<div style={{ color:'#fff', fontFamily:'monospace', fontSize:13, fontWeight:600, lineHeight:1.3 }}>
|
||||||
König Pilsener
|
König Pilsener
|
||||||
</div>
|
</div>
|
||||||
{offer.name && offer.name.toLowerCase() !== 'könig pilsener' && (
|
|
||||||
<div style={{ color:'rgba(255,255,255,0.5)', fontFamily:'monospace', fontSize:11 }}>
|
|
||||||
{offer.name}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{/* Beschreibung/Flaschengröße */}
|
{/* Flaschengröße/Beschreibung */}
|
||||||
{offer.description && (
|
{offer.description && (
|
||||||
<div style={{ color:'rgba(255,255,255,0.55)', fontFamily:'monospace', fontSize:10, lineHeight:1.5 }}>
|
<div style={{ color:'rgba(255,255,255,0.55)', fontFamily:'monospace', fontSize:10, lineHeight:1.5 }}>
|
||||||
{offer.description}
|
{offer.description}
|
||||||
|
|||||||
Reference in New Issue
Block a user