Compare commits

..

No commits in common. "fcc6c6576a6c2ebed1bec795a218e41ddf5eb057" and "9edf8b07d0f94c48bb51961e92a0037dfb340590" have entirely different histories.

2 changed files with 27 additions and 36 deletions

View file

@ -61,11 +61,14 @@ Per-provider модель (#1793):
НЕ читается см. _RETIRED_ENV; в проде он всё ещё
выставлен во всех трёх контейнерах и ни на что не влияет.
BROWSER_BLOCK_IMAGES булев глобальный дефолт camoufox block_images (#3185).
Дефолт для ВСЕХ провайдеров True (блокируем). Пробовали
выключить для avito по гипотезе «блокировка = сигнал для
QRATOR» замер её не подтвердил, дефолт откатан; разбор
и цифры в комментарии у _BLOCK_IMAGES_DEFAULT_BY_PROVIDER.
Сама ручка осталась: выключить можно env'ом, без релиза.
Camoufox сам предупреждает (LeakWarning), что блокировка
картинок повышает риск детекта на крупных WAF картинки
часть нормального fingerprint браузера, их отсутствие
выделяет сессию. Авито стоит за QRATOR: с block_images=True
в проде ~32% detail-сборов возвращали заглушку. Дефолт для
avito поэтому False (не блокировать); для cian/yandex/generic
остаётся True их WAF-чувствительность не замеряна, менять
без замера не будем.
BROWSER_BLOCK_IMAGES_{PROVIDER} per-provider override, тот же формат, что у
BROWSER_MIN_PAGE_INTERVAL_S_{PROVIDER}: PROVIDER в
upper-case (AVITO, CIAN, YANDEX, GENERIC), перебивает и
@ -245,20 +248,10 @@ _MIN_PAGE_INTERVAL_BY_PROVIDER: dict[str, float] = {
p: _resolve_min_interval(p) for p in ("avito", "cian", "yandex", "generic")
}
# Код-дефолт block_images ПО ПРОВАЙДЕРУ. Сейчас пуст — все провайдеры блокируют
# картинки, как и до #3185 (см. _BLOCK_IMAGES_DEFAULT_FALLBACK). Ручка из #3185
# остаётся: поменять поведение можно через env, без релиза.
#
# Почему дефолт откатан (#3185). Гипотеза «блокировка картинок = лишний сигнал для
# QRATOR» шла от camoufox'ского LeakWarning, а не от замера. Прямой A/B на сайдкаре её
# не подтвердил: 6/8 успехов с блокировкой против 7/8 без — разница в пределах шума.
# На проде после выкатки avito=False стало хуже: прогон 5200 (картинки блокировались) —
# 43/63 карточки при 32% блоков; прогоны 5206 и 5207 (не блокировались) — 2/22 и 2/13
# при 91% и 77% блоков. Причинность НЕ доказана: между прогонами через тот же пул
# прокси прошло ~40 диагностических запросов, репутация пула могла просесть от них.
# Но выгоды правка не показала ни разу, поэтому дефолт возвращается к прежнему
# поведению; эффект картинок мерить отдельно и на чистом пуле.
_BLOCK_IMAGES_DEFAULT_BY_PROVIDER: dict[str, bool] = {}
# Код-дефолт block_images ПО ПРОВАЙДЕРУ (#3185): avito не измерен пассивно — детект на
# QRATOR стоит дороже, чем экономия трафика/времени рендера. cian/yandex/generic не
# замерены, поведение не трогаем (True, как раньше).
_BLOCK_IMAGES_DEFAULT_BY_PROVIDER: dict[str, bool] = {"avito": False}
_BLOCK_IMAGES_DEFAULT_FALLBACK: bool = True
@ -270,7 +263,7 @@ def _resolve_block_images(
Приоритет (выше сильнее): per-provider env ``BROWSER_BLOCK_IMAGES_{PROVIDER}``
глобальный env ``BROWSER_BLOCK_IMAGES`` код-дефолт per-provider
(``_BLOCK_IMAGES_DEFAULT_BY_PROVIDER``; сейчас пуст все True). Не кидает
(``_BLOCK_IMAGES_DEFAULT_BY_PROVIDER``, avito=False, остальные=True). Не кидает
исключений невалидный/отсутствующий env тихо проваливается на следующий уровень.
Args:
@ -441,9 +434,13 @@ async def _launch_browser(provider: str, proxy_override: str | None = None) -> N
"locale": "ru-RU",
"geoip": True,
"humanize": True,
# Значение per-provider (#3185): env BROWSER_BLOCK_IMAGES /
# BROWSER_BLOCK_IMAGES_{PROVIDER}, см. docstring модуля. Дефолт для всех — True
# (блокируем), почему именно так — у _BLOCK_IMAGES_DEFAULT_BY_PROVIDER.
# block_images НЕ бесплатен (#3185): camoufox сам предупреждает LeakWarning'ом,
# что блокировка image-запросов повышает риск детекта на крупных WAF — картинки
# часть штатного fingerprint браузера, их отсутствие выделяет сессию. Авито за
# QRATOR: пока блокировали всем провайдерам одинаково, ~32% detail-сборов
# получали заглушку. Теперь значение per-provider (BROWSER_BLOCK_IMAGES /
# BROWSER_BLOCK_IMAGES_{PROVIDER}, см. docstring модуля) — avito по дефолту НЕ
# блокирует, cian/yandex/generic блокируют как раньше (не измерены, не трогаем).
"block_images": _BLOCK_IMAGES_BY_PROVIDER.get(provider, _BLOCK_IMAGES_DEFAULT_FALLBACK),
# Анти-leak: WebRTC может слить реальный IP контейнера мимо прокси → деанон.
"block_webrtc": True,

View file

@ -495,13 +495,13 @@ def test_pace_provider_independent_per_provider(monkeypatch: pytest.MonkeyPatch)
# ── #3185: _resolve_block_images (per-provider block_images) ───────────────────────
def test_resolve_block_images_default_avito_blocked() -> None:
"""Код-дефолт: avito блокирует картинки — как и все (откат #3185, см. server.py)."""
assert server._resolve_block_images("avito", environ={}) is True
def test_resolve_block_images_default_avito_unblocked() -> None:
"""Код-дефолт: avito НЕ блокирует картинки (QRATOR-детект, ~32% заглушек)."""
assert server._resolve_block_images("avito", environ={}) is False
def test_resolve_block_images_default_others_blocked() -> None:
"""Код-дефолт: cian/yandex/generic блокируют — поведение не менялось никогда."""
"""Код-дефолт: cian/yandex/generic блокируют как раньше (не измерены)."""
assert server._resolve_block_images("cian", environ={}) is True
assert server._resolve_block_images("yandex", environ={}) is True
assert server._resolve_block_images("generic", environ={}) is True
@ -522,15 +522,9 @@ def test_resolve_block_images_per_provider_env_overrides_global() -> None:
def test_resolve_block_images_per_provider_env_overrides_avito_default() -> None:
"""BROWSER_BLOCK_IMAGES_AVITO=false снимает блокировку для avito, не трогая прочих.
Проверка направления, которое ОТЛИЧАЕТСЯ от дефолта: после отката #3185 дефолт для
всех True, поэтому тест с env=true проходил бы и у функции, всегда возвращающей
True. Ручка нужна именно чтобы вернуть avito=False без релиза это и проверяем.
"""
env = {"BROWSER_BLOCK_IMAGES_AVITO": "false"}
assert server._resolve_block_images("avito", environ=env) is False
assert server._resolve_block_images("cian", environ=env) is True
"""BROWSER_BLOCK_IMAGES_AVITO=true может включить блокировку и для avito."""
env = {"BROWSER_BLOCK_IMAGES_AVITO": "true"}
assert server._resolve_block_images("avito", environ=env) is True
def test_resolve_block_images_unrecognized_value_is_falsy() -> None: