19 lines
1.7 KiB
JavaScript
19 lines
1.7 KiB
JavaScript
// Bauhaus-Adapter (Muster wie OBI: Produktseite → Preis via JSON-LD + Markt-Status-Heuristik).
|
|
// TODO: products{} mit echten Produkt-URLs/Artikelnummern füllen; Per-Markt-Endpoint ergänzen.
|
|
const UA = 'KuehlfinderBot/0.1 (+https://kuehlfinder.de/bot)';
|
|
export const meta = { id: 'bauhaus', name: 'Bauhaus', kind: 'baumarkt' };
|
|
export const products = { /* 'portasplit': 'https://www....' */ };
|
|
function jsonld(html){const o=[];const re=/<script[^>]+application\/ld\+json[^>]*>([\s\S]*?)<\/script>/gi;let m;while((m=re.exec(html))){try{o.push(JSON.parse(m[1]));}catch{}}return o;}
|
|
function offer(ld){for(const n of (Array.isArray(ld)?ld:[ld])){const g=n['@graph']||[n];for(const x of g){if(x&&(x['@type']==='Product'||x.offers)){const of=Array.isArray(x.offers)?x.offers[0]:x.offers;if(of)return{price:Number(of.price??of.lowPrice),availability:String(of.availability||'')};}}}return null;}
|
|
export async function fetchProduct(productId,{marketId}={}){
|
|
const url=products[productId]; if(!url) return null;
|
|
const res=await fetch(url,{headers:{'User-Agent':UA,'Accept-Language':'de-DE'}}); if(!res.ok) throw new Error('Bauhaus '+res.status);
|
|
const html=await res.text(); const o=jsonld(html).map(offer).find(Boolean);
|
|
const inStore=/vorrätig|verfügbar/i.test(html)&&!/nicht (vorrätig|verfügbar)/i.test(html);
|
|
const price=o?.price ?? Number((html.match(/(\d{2,4})[,.](\d{2})\s*€/)||[])[0]?.replace(/[^\d,]/g,'').replace(',','.'));
|
|
return { productId, source:'bauhaus', marketId:marketId??null, price: price||null,
|
|
availability: inStore?'in_stock':(o&&/InStock/i.test(o.availability)?'online_available':'out_of_stock'),
|
|
checkedAt:new Date().toISOString(), url };
|
|
}
|
|
export async function fetchStores(){ return []; }
|