Compare commits
No commits in common. "9b92b595dbfc6f9bbaa7c19396898f8f29e5011e" and "758a4b06d4635baca7af654927151a96b07d199e" have entirely different histories.
9b92b595db
...
758a4b06d4
2 changed files with 14 additions and 24 deletions
|
|
@ -11,19 +11,13 @@ proxy_provider + use_pool=config.use_proxy_pool_browser в BrowserFetcher.
|
||||||
- proxy_provider задан + флаг on → BrowserFetcher получает провайдер + use_pool=True.
|
- proxy_provider задан + флаг on → BrowserFetcher получает провайдер + use_pool=True.
|
||||||
|
|
||||||
BrowserFetcher монки-патчится на recording-заглушку, так что реального HTTP к
|
BrowserFetcher монки-патчится на recording-заглушку, так что реального HTTP к
|
||||||
tradein-browser не происходит.
|
tradein-browser не происходит. Yandex SERP всё ещё конструирует BrowserFetcher
|
||||||
|
напрямую в своём модуле — патчим `yandex_serp.BrowserFetcher`. Cian SERP
|
||||||
После F4-миграции (#2362 F4b cian + #2363 F4c yandex) ОБА скрапера
|
(#2362, F4b) переведён на общую фабрику `scraper_kit.providers._base.
|
||||||
(`yandex/serp.py::__aenter__` и `cian/serp.py::__aenter__`) больше не конструируют
|
build_browser_fetcher()` — конструктор теперь вызывается ИЗ _base.py, поэтому
|
||||||
`BrowserFetcher(...)` напрямую — оба вызывают shared `build_browser_fetcher()` из
|
патчим `BrowserFetcher` там, а не в `cian_serp` (там больше нет своей ссылки на
|
||||||
`scraper_kit.providers._base`, который ВНУТРИ себя ссылается на СВОЙ собственный
|
класс). Проверяемый инвариант (какие kwargs долетают до BrowserFetcher)
|
||||||
импорт `BrowserFetcher`. Патч локального имени `yandex_serp.BrowserFetcher` /
|
не меняется — меняется только точка патча, отражающая реальное место вызова.
|
||||||
`cian_serp.BrowserFetcher` больше не перехватывает вызов (реальный
|
|
||||||
`BrowserFetcher.__init__` конструировался бы, а `calls` оставался пуст) — поэтому
|
|
||||||
для обоих провайдеров патчим `scraper_kit.providers._base.BrowserFetcher`
|
|
||||||
(реальную зависимость `build_browser_fetcher`), сохраняя все assertions как есть.
|
|
||||||
Проверяемый инвариант (какие kwargs долетают до BrowserFetcher) не меняется —
|
|
||||||
меняется только точка патча, отражающая реальное место вызова.
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
@ -97,7 +91,7 @@ def _config(*, use_pool: bool) -> types.SimpleNamespace:
|
||||||
async def test_yandex_serp_wires_pool_when_flag_on(monkeypatch: pytest.MonkeyPatch) -> None:
|
async def test_yandex_serp_wires_pool_when_flag_on(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||||
"""proxy_provider + флаг on → BrowserFetcher получает провайдер + use_pool=True."""
|
"""proxy_provider + флаг on → BrowserFetcher получает провайдер + use_pool=True."""
|
||||||
rec_fetcher, calls = _make_recorder()
|
rec_fetcher, calls = _make_recorder()
|
||||||
monkeypatch.setattr("scraper_kit.providers._base.BrowserFetcher", rec_fetcher)
|
monkeypatch.setattr(yandex_serp, "BrowserFetcher", rec_fetcher)
|
||||||
provider = _FakeProxyProvider()
|
provider = _FakeProxyProvider()
|
||||||
|
|
||||||
scraper = yandex_serp.YandexRealtyScraper(_config(use_pool=True), proxy_provider=provider)
|
scraper = yandex_serp.YandexRealtyScraper(_config(use_pool=True), proxy_provider=provider)
|
||||||
|
|
@ -114,7 +108,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:
|
async def test_yandex_serp_no_pool_by_default(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||||
"""Без provider/флага → BrowserFetcher(proxy_provider=None, use_pool=False) — ship-dark."""
|
"""Без provider/флага → BrowserFetcher(proxy_provider=None, use_pool=False) — ship-dark."""
|
||||||
rec_fetcher, calls = _make_recorder()
|
rec_fetcher, calls = _make_recorder()
|
||||||
monkeypatch.setattr("scraper_kit.providers._base.BrowserFetcher", rec_fetcher)
|
monkeypatch.setattr(yandex_serp, "BrowserFetcher", rec_fetcher)
|
||||||
|
|
||||||
scraper = yandex_serp.YandexRealtyScraper(_config(use_pool=False))
|
scraper = yandex_serp.YandexRealtyScraper(_config(use_pool=False))
|
||||||
async with scraper:
|
async with scraper:
|
||||||
|
|
@ -131,7 +125,7 @@ async def test_yandex_serp_provider_without_flag_stays_dark(
|
||||||
) -> None:
|
) -> None:
|
||||||
"""provider задан, но флаг off → use_pool=False (BrowserFetcher пул не трогает)."""
|
"""provider задан, но флаг off → use_pool=False (BrowserFetcher пул не трогает)."""
|
||||||
rec_fetcher, calls = _make_recorder()
|
rec_fetcher, calls = _make_recorder()
|
||||||
monkeypatch.setattr("scraper_kit.providers._base.BrowserFetcher", rec_fetcher)
|
monkeypatch.setattr(yandex_serp, "BrowserFetcher", rec_fetcher)
|
||||||
provider = _FakeProxyProvider()
|
provider = _FakeProxyProvider()
|
||||||
|
|
||||||
scraper = yandex_serp.YandexRealtyScraper(_config(use_pool=False), proxy_provider=provider)
|
scraper = yandex_serp.YandexRealtyScraper(_config(use_pool=False), proxy_provider=provider)
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,6 @@ from scraper_kit.browser_fetcher import BrowserFetcher
|
||||||
from scraper_kit.house_type_normalizer import normalize_house_type
|
from scraper_kit.house_type_normalizer import normalize_house_type
|
||||||
from scraper_kit.price_brackets import get_price_seed_brackets
|
from scraper_kit.price_brackets import get_price_seed_brackets
|
||||||
from scraper_kit.pricing import BisectionConfig, ProbeFailPolicy, ProbeResult, walk_price_range
|
from scraper_kit.pricing import BisectionConfig, ProbeFailPolicy, ProbeResult, walk_price_range
|
||||||
from scraper_kit.providers._base import build_browser_fetcher
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from scraper_kit.contracts import ProxyProvider, ScraperConfig
|
from scraper_kit.contracts import ProxyProvider, ScraperConfig
|
||||||
|
|
@ -507,16 +506,13 @@ class YandexRealtyScraper(BaseScraper):
|
||||||
|
|
||||||
fetch_timeout_s=_YANDEX_BROWSER_FETCH_TIMEOUT_S (30s) ограничивает потери
|
fetch_timeout_s=_YANDEX_BROWSER_FETCH_TIMEOUT_S (30s) ограничивает потери
|
||||||
на один тайм-аутовый запрос: worst-case 30s×(1+retries)=90s на combo вместо 360s.
|
на один тайм-аутовый запрос: 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 = build_browser_fetcher(
|
self._browser = BrowserFetcher(
|
||||||
self._config,
|
|
||||||
source="yandex",
|
source="yandex",
|
||||||
proxy_provider=self._proxy_provider,
|
|
||||||
fetch_timeout_s=_YANDEX_BROWSER_FETCH_TIMEOUT_S,
|
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,
|
||||||
)
|
)
|
||||||
await self._browser.__aenter__()
|
await self._browser.__aenter__()
|
||||||
return self
|
return self
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue