zov-tech/backend-py/app/parsers
wasrusgen e9b0db6772 wb: API v9 → v18 (WB сменил endpoint и структуру) + brand+category fallback query
DISCOVERED in real test:
- WB API v9 (/exactmatch/ru/common/v9/search) теперь возвращает только метаданные
  (name, query, shardKey, filters, search_result={}) — products пусто
- WB API v18 (/exactmatch/ru/common/v18/search) — рабочий
  Структура: {metadata, products, total} — products НА ВЕРХНЕМ уровне (не data.products)
- Подтверждено: query='Haier холодильник' → 100 products via v18

CHANGES:
1. _SEARCH_URL → v18 endpoint
2. Парсинг products: сначала data.products (legacy fallback), потом products top-level
3. _build_item: цены теперь читаются из sizes[].price.{product, total, basic}
   (v18 формат), с fallback на priceU/salePriceU (v9 legacy)
4. _generate_query_variants: добавлен brand+category fallback
   ('Bosch холодильник' если не нашли по модели)

TEST: Haier холодильник → 100 results (first: 'Холодильник двухкамерный C2F619CFU1')
2026-05-11 22:59:14 +03:00
..
__init__.py backend: working parsers — OZON + Citilink (DOM via Playwright) + WB 2026-05-11 13:53:07 +03:00
citilink.py parsers: skip sponsored/ad URLs (cpc/sponsored=1) — they expire in 2-3 hours 2026-05-11 17:20:59 +03:00
dns.py dns+ozon: 4 retries with proxy rotation (residential pool has dirty IPs) 2026-05-11 16:37:28 +03:00
ozon.py parsers: skip sponsored/ad URLs (cpc/sponsored=1) — they expire in 2-3 hours 2026-05-11 17:20:59 +03:00
playwright_engine.py playwright_engine: route through proxy_pool — random residential IP per request 2026-05-11 16:05:36 +03:00
wb.py wb: API v9 → v18 (WB сменил endpoint и структуру) + brand+category fallback query 2026-05-11 22:59:14 +03:00
yamarket.py parsers: skip sponsored/ad URLs (cpc/sponsored=1) — they expire in 2-3 hours 2026-05-11 17:20:59 +03:00