From f09d9737ce32023368c6014e283b9dff66fb4705 Mon Sep 17 00:00:00 2001 From: bot-backend Date: Sun, 31 May 2026 19:17:01 +0300 Subject: [PATCH] =?UTF-8?q?fix(browser):=20bump=20fetch=20wait=202500?= =?UTF-8?q?=E2=86=926000ms=20so=20avito=20listings=20hydrate=20(#905)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Prod debug (ssh, headless=True + mobileproxy): the camoufox fetch was returning a 274KB generic avito shell with 0 listings — NOT a block/captcha (no captcha/datadome/firewall markers, status 200, correct final_url). Avito hydrates the SERP listings into the DOM client-side AFTER domcontentloaded; at the 2500ms wait the page.content() snapshot still had only the generic shell. At 5-6s it's the full SERP: 3.2MB, priceDetailed=50. Fix: BROWSER_WAIT_MS default 2500→6000 (5s proven full + 1s margin), config.py browser_wait_ms 2500→6000 to match. The whole camoufox+proxy migration works — this was the last blocker. NOT headless detection (headless=True returns real data); the abandoned xvfb/headless=virtual change is unnecessary. Refs #905, #883 --- tradein-mvp/backend/app/core/config.py | 2 +- tradein-mvp/browser/server.py | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/tradein-mvp/backend/app/core/config.py b/tradein-mvp/backend/app/core/config.py index 1eef67ff..6b15943c 100644 --- a/tradein-mvp/backend/app/core/config.py +++ b/tradein-mvp/backend/app/core/config.py @@ -225,7 +225,7 @@ class Settings(BaseSettings): browser_nav_timeout_ms: int = 60000 # Ожидание после DOMContentLoaded для JS-гидрации в мс. Читается сервером. # ENV: BROWSER_WAIT_MS. - browser_wait_ms: int = 2500 + browser_wait_ms: int = 6000 settings = Settings() diff --git a/tradein-mvp/browser/server.py b/tradein-mvp/browser/server.py index d071a0ba..83226b0c 100644 --- a/tradein-mvp/browser/server.py +++ b/tradein-mvp/browser/server.py @@ -17,7 +17,7 @@ WS-сервер) несовместим с современными версия BROWSER_PORT — TCP-порт HTTP-сервера (default: 3000) BROWSER_RECYCLE_PAGES — страниц в одном сеансе браузера до перезапуска (default: 15) BROWSER_NAV_TIMEOUT_MS — таймаут page.goto в мс (default: 60000) - BROWSER_WAIT_MS — ожидание после DOMContentLoaded в мс (default: 2500) + BROWSER_WAIT_MS — ожидание гидрации listings после DOMContentLoaded, мс (default: 6000) AVITO_PROXY_URL — прокси ``http://user:pass@host:port`` (mobileproxy, #623); SCRAPER_PROXY_URL — generic-fallback. Без него — soft-block. @@ -39,7 +39,10 @@ logger = logging.getLogger(__name__) BROWSER_PORT: int = int(os.environ.get("BROWSER_PORT", "3000")) BROWSER_RECYCLE_PAGES: int = int(os.environ.get("BROWSER_RECYCLE_PAGES", "15")) BROWSER_NAV_TIMEOUT_MS: int = int(os.environ.get("BROWSER_NAV_TIMEOUT_MS", "60000")) -BROWSER_WAIT_MS: int = int(os.environ.get("BROWSER_WAIT_MS", "2500")) +# 6000 (не 2500): avito гидрирует listings client-side ПОСЛЕ domcontentloaded; +# на 2.5с в HTML генерик-шелл без объявлений (0 listings), на 5-6с — полная +# выдача (~50 карточек, 3.2МБ). Подтверждено прод-дебагом 2026-05-31. +BROWSER_WAIT_MS: int = int(os.environ.get("BROWSER_WAIT_MS", "6000")) # Прокси: основной источник — AVITO_PROXY_URL (mobileproxy, #623, лежит в # backend/.env.runtime, тот же что у curl_cffi-avito). SCRAPER_PROXY_URL — # опциональный generic-fallback на будущее (cian/yandex). Без прокси camoufox