Zpět na domů

API WB Ozon: zpracování chyb 429 a 50x

Článek popisuje strategie zpracování chyb 429 a 50x při práci s API Wildberries a Ozon. Jsou zváženy retry-logika s backoffem, batčování požadavků podle dnů a monitorování na pozadí pro plnou automatizaci sběru dat.

Bez chyb 429 z API marketplaců: kód a taktiky
Advertisement 728x90

Zpracování chyb 429 a 50x při práci s API Wildberries a Ozon

Při parsování dat z API Wildberries a Ozon se vývojáři často setkávají s chybami 429 (příliš mnoho požadavků) a 50x (serverové selhání). Tyto problémy vznikají kvůli vysoké zátěži na endpoints. Standardní odpověď technické podpory je nastavit retry. Podíváme se na tři přístupy: základní zpracování s opakováním, optimalizaci objemu požadavků a monitorování s dočítáním.

Základní zpracování opakovaných pokusů

První krok je považovat chyby 429 a 50x za očekávané události. Implementujte retry logiku s exponenciálními pauzami a čtením hlaviček jako X-Ratelimit-Retry. Toto minimalizuje blokování a zvyšuje odolnost.

Příklad funkce pro POST požadavek s retry:

Google AdInline article slot
def get_oz(url, heads, params, max_retries=5, timeout=30):
    result = {}
    for retries in range(1, max_retries + 1):  
        
        try:
            response = requests.post(url, headers=heads, json=params, timeout=timeout)
        except requests.RequestException as e:
            print(f'!!! Síťová chyba v pokusu {retries}: {e}!!!')
            time.sleep(2 * retries)
            continue  
                
        # Kód 200 – získaná správná odpověď
        if response.status_code == 200:
            return response.json()
            
        # Kód 429 – Příliš mnoho požadavků, provedeme chytrou pauzu a znovu požadáme
        elif response.status_code == 429:
            pause_time = 2 ** retries
            
            # X-Ratelimit-Retry – funkce WB, ale Ozon může také zavést
            if 'X-Ratelimit-Retry' in response.headers:
                pause_time = int(response.headers['X-Ratelimit-Retry']) + 5
            print(f'get_oz: ! -Příliš mnoho požadavků- v pokusu {retries}. Pauza {pause_time} sek')
            time.sleep(pause_time)
        
        # Při chybě 5xx po pauze přejdeme na další pokus
        elif 500 <= response.status_code < 600:
            pause_time = 2 ** retries
            print(f'get_oz: ! -Chyba {response.status_code}- v pokusu {retries}. Pauza {pause_time} sek')
            time.sleep(pause_time)
        
        # Pokud jiná chyba – ukončíme cyklus!
        else:
            print(f'get_oz: !!! Chyba získávání dat přes API! code: {response.status_code}')
            return None
    
    print(f'get_oz: !!! Všech {max_retries} pokusů selhalo')
    return None
  • 5 retry obvykle stačí pro typické zatížení.
  • Cyklus stránkování (offset/page) vynechte na vyšší úrovni.
  • Při úplném selhání odložte na hodinu a více.

Tato logika se integruje do jakéhokoli ETL pipeline pro API.

Optimalizace objemu dat

Velké požadavky (např. transakce za týden) vyvolávají chyby na pozdních stránkách stránkování. Rozdělte je na menší nezávislé batche: po dnech, kategoriích nebo podle filtrů. Ukládejte každý batch okamžitě do databáze – ztráta jedné části neruší celý pokrok.

Výhody:

Google AdInline article slot
  • Méně stránek na požadavek (1–3 místo 20).
  • Nezávislé retry pro batche.
  • Částečné uložení při selháních.

Příklad načítání transakcí Ozon po dnech:

date_from = today() - timedelta(days=7)
date_to = today() - timedelta(days=1)
current_date = date_from
delta = timedelta(days=1)

# procházíme dny od date_from do date_to
while current_date <= date_to:  
    transactions_oneday = pd.DataFrame([])           
    url = "https://api-seller.ozon.ru/v3/finance/transaction/list"
    ipage = 1
    all_pages_data = []
    while True:
        data = {
            "filter": {
                "date": {
                    "from": str(current_date) + "T00:00:00.000Z",
                    "to": str(current_date) + "T23:59:59.999Z"
                }
            },
            "page": ipage,
            "page_size": 1000
            }
        dd = []
        apioz_response = get_oz(url, headers, data, 5)
        if len(apioz_response) > 0 :
            dd = apioz_response['result']['operations']
            all_pages_data.extend(dd)
        else:
            print(f'!!! Prázdná odpověď z API')

        # pokud na stránce je méně než 1000 řádků – je to poslední, ukončíme cyklus
        if len(dd) < 1000: break

        ipage +=1
            
    transactions_oneday = pd.DataFrame(all_pages_data)        
    # okamžitě exportujeme do databáze, co jsme získali z API
    export_to_db('oz_transactions', transactions_oneday)

    # přejdeme na další den
    current_date += delta

Navzdory vnořeným cyklům se spolehlivost exponenciálně zvyšuje.

Monitorování a dočítání

Pro plnou automatizaci přidejte "záložní řešení" – pozadí monitorování. Po hlavním spuštění (např. v 6–7 ráno) kontrolujte logy/databázi každou hodinu (8–12 ráno).

Google AdInline article slot
  • Analyzujte stav posledního úkolu.
  • Kontrolujte integritu dat (mezeru v datech).
  • Spusťte cílené retry pouze pro nedostatky.

Toto snižuje ruční zásahy na minimum, zejména při denních aktualizacích.

Co je důležité

  • Používejte exponenciální backoff s hlavičkami retry pro chyby 429.
  • Rozdělujte velké požadavky na batche po dnech/filtrech s okamžitým uložením.
  • Zaveďte každohodinové monitorování po hlavním sběru pro doplnění.
  • 5 retry pokrývá 95 % selhání; úplné selhání odložte na hodinu a více.
  • Integrujte do ETL bez pevných závislostí na stránkování.

— Editorial Team

Advertisement 728x90

Číst dál