diff --git a/tradein-mvp/backend/tests/test_kit_serp_proxy_pool.py b/tradein-mvp/backend/tests/test_kit_serp_proxy_pool.py index 812c2955..36667db1 100644 --- a/tradein-mvp/backend/tests/test_kit_serp_proxy_pool.py +++ b/tradein-mvp/backend/tests/test_kit_serp_proxy_pool.py @@ -12,6 +12,16 @@ proxy_provider + use_pool=config.use_proxy_pool_browser в BrowserFetcher. BrowserFetcher монки-патчится на recording-заглушку в модуле каждого скрапера, так что реального HTTP к tradein-browser не происходит. + +Yandex (#2363, F4c миграция): `yandex/serp.py::__aenter__` больше не конструирует +`BrowserFetcher(...)` напрямую — вызывает shared `build_browser_fetcher()` из +`scraper_kit.providers._base`, который ВНУТРИ себя ссылается на СВОЙ собственный +импорт `BrowserFetcher`. Патч локального имени `yandex_serp.BrowserFetcher` больше +не перехватывает вызов (реальный `BrowserFetcher.__init__` конструировался бы, а +`calls` оставался пуст) — патчим `scraper_kit.providers._base.BrowserFetcher` +(реальную зависимость `build_browser_fetcher`), сохраняя все assertions как есть. +Cian (`cian/serp.py`) пока НЕ мигрирован (F4b, отдельный issue) — там патч +локального имени остаётся корректным. """ from __future__ import annotations @@ -84,7 +94,7 @@ def _config(*, use_pool: bool) -> types.SimpleNamespace: async def test_yandex_serp_wires_pool_when_flag_on(monkeypatch: pytest.MonkeyPatch) -> None: """proxy_provider + флаг on → BrowserFetcher получает провайдер + use_pool=True.""" rec_fetcher, calls = _make_recorder() - monkeypatch.setattr(yandex_serp, "BrowserFetcher", rec_fetcher) + monkeypatch.setattr("scraper_kit.providers._base.BrowserFetcher", rec_fetcher) provider = _FakeProxyProvider() scraper = yandex_serp.YandexRealtyScraper(_config(use_pool=True), proxy_provider=provider) @@ -101,7 +111,7 @@ async def test_yandex_serp_wires_pool_when_flag_on(monkeypatch: pytest.MonkeyPat async def test_yandex_serp_no_pool_by_default(monkeypatch: pytest.MonkeyPatch) -> None: """Без provider/флага → BrowserFetcher(proxy_provider=None, use_pool=False) — ship-dark.""" rec_fetcher, calls = _make_recorder() - monkeypatch.setattr(yandex_serp, "BrowserFetcher", rec_fetcher) + monkeypatch.setattr("scraper_kit.providers._base.BrowserFetcher", rec_fetcher) scraper = yandex_serp.YandexRealtyScraper(_config(use_pool=False)) async with scraper: @@ -118,7 +128,7 @@ async def test_yandex_serp_provider_without_flag_stays_dark( ) -> None: """provider задан, но флаг off → use_pool=False (BrowserFetcher пул не трогает).""" rec_fetcher, calls = _make_recorder() - monkeypatch.setattr(yandex_serp, "BrowserFetcher", rec_fetcher) + monkeypatch.setattr("scraper_kit.providers._base.BrowserFetcher", rec_fetcher) provider = _FakeProxyProvider() scraper = yandex_serp.YandexRealtyScraper(_config(use_pool=False), proxy_provider=provider) diff --git a/tradein-mvp/packages/scraper-kit/src/scraper_kit/providers/yandex/serp.py b/tradein-mvp/packages/scraper-kit/src/scraper_kit/providers/yandex/serp.py index 6781e640..8a42a6f1 100644 --- a/tradein-mvp/packages/scraper-kit/src/scraper_kit/providers/yandex/serp.py +++ b/tradein-mvp/packages/scraper-kit/src/scraper_kit/providers/yandex/serp.py @@ -51,6 +51,7 @@ from scraper_kit.browser_fetcher import BrowserFetcher from scraper_kit.house_type_normalizer import normalize_house_type from scraper_kit.price_brackets import get_price_seed_brackets from scraper_kit.pricing import BisectionConfig, ProbeFailPolicy, ProbeResult, walk_price_range +from scraper_kit.providers._base import build_browser_fetcher if TYPE_CHECKING: from scraper_kit.contracts import ProxyProvider, ScraperConfig @@ -506,13 +507,16 @@ class YandexRealtyScraper(BaseScraper): fetch_timeout_s=_YANDEX_BROWSER_FETCH_TIMEOUT_S (30s) ограничивает потери на один тайм-аутовый запрос: worst-case 30s×(1+retries)=90s на combo вместо 360s. + + Собрано через shared `build_browser_fetcher()` (#2358 Foundation, #2363 + миграция) — endpoint/use_pool берутся из `config` mandatory, footgun-класс + #2322/#2330 (пропущенный endpoint/use_pool) закрыт структурно. """ - self._browser = BrowserFetcher( + self._browser = build_browser_fetcher( + self._config, source="yandex", - fetch_timeout_s=_YANDEX_BROWSER_FETCH_TIMEOUT_S, - endpoint=self._config.browser_http_endpoint, proxy_provider=self._proxy_provider, - use_pool=self._config.use_proxy_pool_browser, + fetch_timeout_s=_YANDEX_BROWSER_FETCH_TIMEOUT_S, ) await self._browser.__aenter__() return self