Боевой оркестратор (scrape_pipeline.py) читал только статический
settings.scraper_proxy_url — ни один боевой скрейпер не использовал
proxy_pool/scrape_proxies (git grep "acquire(" = 0 хитов). Бан на общем
IP выносил avito+cian+yandex+domklik разом.
Подключён pool-aware proxy acquisition/rotation в 3 curl-режим Avito
entry points (run_avito_pipeline, run_avito_city_sweep,
run_avito_newbuilding_sweep), за флагом use_proxy_pool_curl (default
False — ship-dark, поведение не меняется пока явно не включат):
- _pool_proxy_dict(): health-filtered acquire() lease, fallback на
статический прокси при пустом пуле/ошибке/флаге off.
- _rotate_pool_proxy(): на бан — mark_health(ok=False) → acquire()
замены → ТОЛЬКО ПОСЛЕ release(current_lease). Порядок принципиален:
release ДО acquire() позволял пулу молча вернуть тот же только что
забаненный прокси (один бан не достигает MAX_CONSECUTIVE_FAILS=3,
leased_by IS NULL фильтр не исключал бы его) — найдено на pre-push
review, воспроизведено и закрыто регрессионным тестом с CURRENT id
ниже GOOD id (оригинальный тест проходил случайно из-за id tie-break).
- run_id прокинут в acquire() на обоих sweep call sites — scrape_proxies
.leased_by несёт реальный run id для диагностики, не NON_RUN_LEASE_MARKER.
Cian/Yandex/DomClick (browser-mode, отдельный сервис) и
run_avito_full_load (использует AvitoScraper напрямую, много вызывающих
кода за пределами scrape_pipeline) — вне скоупа, задокументировано как
follow-up в PR description.
Refs #2202