FMAN.cz má 3 600 produktů z 12 e-shopů, Zveráč.cz dokonce 53 000 z 8 partnerů. Klíč k tomu, že to není zoo duplikátů a nesmyslů: feed pipeline s automatickým párováním přes EAN. V tomto článku detailně rozeberu, jak ji postavit — od stahování XML feedů po deduplikaci a monitoring.
Co se v tomto článku dozvíte
- Architektura feed pipeline (5 fází)
- EAN matching strategy (90 % automatický match)
- Fuzzy matching když EAN chybí (Levenshtein, brand normalization)
- Monitoring + alerting pro feedy
- Časté chyby (drahé z hlediska SEO i UX)
Architektura feed pipeline (5 fází)
Fáze 1: Stahování (Fetcher)
- Cron 1× denně (00:30 noční hodiny)
- Per e-shop konfigurace (URL, auth method, retry policy)
- Streaming download (XML stream parser, ne load celý do paměti)
- Validation: kontrola, že feed má min. 50 % původní velikosti
Fáze 2: Parsing (Parser)
- XML / CSV / JSON adaptery per format
- Ukládá do staging tabulky (raw_offers)
- Žádné ověření vůči existující DB ještě
- Pole: source_id, sku, ean, name, price, url, image, brand, category
Fáze 3: Normalizace (Normalizer)
- Brand normalize (Royal Canin / RoyalCanin / Royal-Canin → ROYAL_CANIN)
- Category mapping (per e-shop dictionary → unifikovaná taxonomie)
- Cena s DPH check (E-shop A bez DPH, E-shop B s DPH)
- HTML sanitization (popis bez tracking pixelů a iframe)
- Image download + WebP conversion
Fáze 4: Matching (Matcher)
Klíčová fáze. 4 strategie v pořadí:
- EAN match — 90 % case
- MPN + brand fallback — 5 % případů
- Fuzzy name match (Levenshtein dist < 10) + brand + category — 3 %
- Manuální review queue — 2 %
Fáze 5: Persistence (Writer)
- Batch insert / update do products + offers
- Trigger na materialized view refresh
- Search index update (pokud používáte Algolia / Meilisearch)
- Sitemap regeneration
EAN matching deep dive
EAN (European Article Number) = 13-digit code unikátní per produkt. Funguje pro 90 % FMCG produktů.
Pseudokód
function matchProduct(rawOffer):
if rawOffer.ean and len(rawOffer.ean) == 13:
existing = Product.findByEan(rawOffer.ean)
if existing:
return existing
else:
return Product.create(from_offer=rawOffer)
else:
return fuzzyMatch(rawOffer)Edge cases
- Variant produkty (velikost, barva) — stejný EAN per variant. Řešení: SKU jako secondary key.
- EAN typo — checksum validation (poslední číslice je hash předchozích 12).
- Bundle produkty (set 3 ks) — separátní EAN, často chybí. Řešení: ručně.
- Generic items (bezznačkové, např. „bavlněné tričko XL“) — chybí EAN. Fuzzy match.
Fuzzy matching když EAN chybí
Pro 10 % produktů bez EAN je nutný fuzzy match. Algoritmus:
- Brand match (musí být stejný brand)
- Category match (musí být ve stejné kategorii)
- Name similarity (Levenshtein distance < 10 z 50 znaků)
- Confidence score > 0.85
Pod confidence 0.85 jde do review queue (admin schvaluje manuálně).
Monitoring + alerting
| Metrika | Threshold alert |
|---|---|
| Feed not fetched 24 h | Critical |
| Product count drop > 10 % | Warning |
| Match rate < 80 % | Warning |
| Manual review queue > 100 | Info |
| Fetcher error rate > 5 % | Critical |
Alert kanály: Slack, email, SMS pro Critical.
Reálná data: FMAN.cz pipeline
- 12 partnerských e-shopů
- 3 600 unique produktů, ~5 200 nabídek (1 produkt často ve 2+ e-shopech)
- Daily run: 4 minuty (od fetch po DB write)
- Match rate: 89 % (10 % manuální review, 1 % skip)
- Hosting cost: $8/měs (DB) + $5 cron worker
- Maintenance: 2 hodiny / týden (review queue + adjustments)
Časté chyby
- Žádný checksum validation EAN. Typo v EAN vytvoří fake produkt.
- Žádná category dictionary. E-shop A „Mountain Bike“, E-shop B „Horské kolo“ — bez mapování duplicate kategorie.
- Image hotlink. Linkujete obrázek z partnerova CDN — když ho smaže, váš web má broken image.
- Žádný retry. Fetcher failne, partner ve feedu chybí 24 hodin.
- Sync v reálném čase. Daily 4-min batch jobu lepší než real-time webhook spam.
Často kladené otázky
Jak rychlé pipeline pro 50k+ produktů?
Zveráč.cz: 53 000 produktů, daily run 18 minut. Kombinace MySQL bulk insert (10k rows/batch) + parallelism (4 worker threads).
Funguje to s Heuréka XML feedem?
Ano. Heuréka XML format je standard. Většina českých e-shopů ho exportuje.
Co s real-time změnami cen?
Daily batch je dostatečný pro 95 % use cases. Pro flash sales (Black Friday) doporučuju 4× denně.
Mohu mít fuzzy match s Embedding modelem?
Ano. OpenAI text-embedding-3 nebo Cohere embed-multilingual-v3 dají lepší fuzzy match než Levenshtein. Cena: $0.13/1M tokens — pro 50k produktů ~$2/měs.
Co OutOfStock products?
Označit jako out_of_stock = true, neukazovat v hlavním listu. Po 90 dnech soft delete.
Související články
SEO checklist 2026 — 57 bodů
Praktický audit pro malé a střední firmy. Technické SEO + GEO pro AI vyhledávače. PDF okamžitě po zadání emailu.
Stáhnout checklist zdarma