fix(tradein/scrapers): убрать оставшиеся обходы пула прокси (#2830) #2833

Merged
bot-backend merged 1 commit from fix/2830-remaining-pool-bypass into main 2026-08-12 10:53:37 +00:00
Collaborator

Что

Три места брали egress из статичного SCRAPER_PROXY_URL (он же cian_proxy_url/yandex_proxy_url), который не знает про scrape_proxy_source_bans. Тот же класс, что #2796 (Домклик — ноль лотов четверо суток) и #2798/#2821 (Циан — 403 пятнадцать суток, причём путь ещё и сообщал пулу «узел здоров»).

Место Диагноз Живой?
cian_price_history (ручка) оборванная проводка ручной запуск; последний, судя по отпечатку данных, 2026-05-24 — 80 суток назад; 19 150 cian-листингов ждут
_provider_proxy_url / GET /admin/scraper/health оборванная проводка опрос раз в 30 с, пока панель открыта
resolve_cian_zhk_url_via_search (не был в issue) оборванная проводка, ветка спящая задача newbuilding_enrich идёт ежедневно, но resolved_zhk_url=0 во всех 59 прогонах
resolve_cian_zhk_url (legacy) мёртвый код 0 вызывающих, путь /zhk/<id>/ 404-ит с #972 → удалён

Ловушка, из-за которой одного proxy_provider= мало

USE_PROXY_POOL_CURL: "true" задан только контейнеру scraper (docker-compose.prod.yml), а ручка price-history живёт в backend, где переменной нет. Без флага curl_proxy_url игнорирует переданный провайдер и уходит на env — правка была бы зелёной и без эффекта. Отсюда _PoolCurlConfig (флаг = рубильник раскатки для планировщика, а не решение «этому пути пул не нужен»).

Вердикт возвращается в пул

curl_proxy_url на выходе: mark_banned на CianBlockedError (только 403), mark_health(ok=False) на прочих исключениях, release всегда. 404 (снятое объявление) и пустой SERP — не бан: чужой вердикт узлу не присваиваем (#2805). Health-страница вердикт не возвращает намеренно: ipify-проба говорит о доступности ipify, а не о репутации узла у площадки.

Тест красный на старом коде

10 из 11 падают на origin/main, и падают поведенчески, а не на отсутствии имени (заглушка подставлена под RealProxyProvider, на уровне модуля proxy_pool):

assert [] == ['cian']            # acquire не звался
assert [] == [(9, 'cian')]       # 403 не дошёл до пула
assert {'static-env-node'} == {'pool-node-9'}   # панель показывала env-узел
AssertionError: после отказа пула батч продолжаться не должен

Test plan

  • pytest tests/ — 4236 passed, 18 skipped
  • красный прогон на origin/main — 10 failed, 1 passed
  • ruff (pre-commit 0.7.4) + ruff-format
  • после деплоя: docker logs tradein-backend | grep "proxy_pool: leased" — сейчас 0 таких строк; после нажатия кнопки cian-price-history должна появиться provider=cian by=-1 с id ∈ {9,10,11} (узел 1 забанен для cian до 15.08 04:23 UTC)
  • после деплоя: GET /admin/scraper/healthproxy_host совпадает с выбором пула, в логах 3 строки proxy_egress: source=… -> pool proxy id=… на опрос (сейчас панель отдаёт 190.2.145.131 = статичный env для всех трёх)

Refs #2830

## Что Три места брали egress из статичного `SCRAPER_PROXY_URL` (он же `cian_proxy_url`/`yandex_proxy_url`), который не знает про `scrape_proxy_source_bans`. Тот же класс, что #2796 (Домклик — ноль лотов четверо суток) и #2798/#2821 (Циан — 403 пятнадцать суток, причём путь ещё и сообщал пулу «узел здоров»). | Место | Диагноз | Живой? | |---|---|---| | `cian_price_history` (ручка) | оборванная проводка | ручной запуск; последний, судя по отпечатку данных, 2026-05-24 — **80 суток назад**; 19 150 cian-листингов ждут | | `_provider_proxy_url` / `GET /admin/scraper/health` | оборванная проводка | опрос раз в 30 с, пока панель открыта | | `resolve_cian_zhk_url_via_search` (**не был в issue**) | оборванная проводка, ветка спящая | задача `newbuilding_enrich` идёт ежедневно, но `resolved_zhk_url=0` во **всех 59** прогонах | | `resolve_cian_zhk_url` (legacy) | **мёртвый код** | 0 вызывающих, путь `/zhk/<id>/` 404-ит с #972 → удалён | ## Ловушка, из-за которой одного `proxy_provider=` мало `USE_PROXY_POOL_CURL: "true"` задан **только** контейнеру `scraper` (docker-compose.prod.yml), а ручка price-history живёт в `backend`, где переменной нет. Без флага `curl_proxy_url` игнорирует переданный провайдер и уходит на env — правка была бы зелёной и без эффекта. Отсюда `_PoolCurlConfig` (флаг = рубильник раскатки для планировщика, а не решение «этому пути пул не нужен»). ## Вердикт возвращается в пул `curl_proxy_url` на выходе: `mark_banned` на `CianBlockedError` (только 403), `mark_health(ok=False)` на прочих исключениях, `release` всегда. 404 (снятое объявление) и пустой SERP — **не** бан: чужой вердикт узлу не присваиваем (#2805). Health-страница вердикт **не** возвращает намеренно: ipify-проба говорит о доступности ipify, а не о репутации узла у площадки. ## Тест красный на старом коде 10 из 11 падают на `origin/main`, и падают **поведенчески**, а не на отсутствии имени (заглушка подставлена под `RealProxyProvider`, на уровне модуля `proxy_pool`): ``` assert [] == ['cian'] # acquire не звался assert [] == [(9, 'cian')] # 403 не дошёл до пула assert {'static-env-node'} == {'pool-node-9'} # панель показывала env-узел AssertionError: после отказа пула батч продолжаться не должен ``` ## Test plan - [x] `pytest tests/` — 4236 passed, 18 skipped - [x] красный прогон на `origin/main` — 10 failed, 1 passed - [x] ruff (pre-commit 0.7.4) + ruff-format - [ ] после деплоя: `docker logs tradein-backend | grep "proxy_pool: leased"` — сейчас **0** таких строк; после нажатия кнопки cian-price-history должна появиться `provider=cian by=-1` с id ∈ {9,10,11} (узел 1 забанен для cian до 15.08 04:23 UTC) - [ ] после деплоя: `GET /admin/scraper/health` → `proxy_host` совпадает с выбором пула, в логах 3 строки `proxy_egress: source=… -> pool proxy id=…` на опрос (сейчас панель отдаёт `190.2.145.131` = статичный env для всех трёх) Refs #2830
bot-backend added 1 commit 2026-08-12 10:48:28 +00:00
fix(tradein/scrapers): убрать оставшиеся обходы пула прокси (#2830)
All checks were successful
CI Trade-In / changes (pull_request) Successful in 8s
CI / changes (pull_request) Successful in 8s
CI Trade-In / browser-tests (pull_request) Has been skipped
CI Trade-In / frontend-checks (pull_request) Has been skipped
CI / backend-tests (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Has been skipped
CI Trade-In / backend-tests (pull_request) Successful in 3m57s
0c3cb512c9
Три места продолжали брать egress из статичного SCRAPER_PROXY_URL, который не знает
про scrape_proxy_source_bans. Тот же класс, что #2796 (Домклик, ноль лотов четверо
суток) и #2798/#2821 (Циан, 403 пятнадцать суток при «узел здоров» в пуле).

1. cian_price_history (ручка POST /admin/scrape/cian-price-history) — узел из пула
   + вердикт обратно (mark_banned на 403, mark_health, release). Ловушка, из-за
   которой одного `proxy_provider=` мало: USE_PROXY_POOL_CURL задан только контейнеру
   scraper, а ручка живёт в backend, где флага нет — curl_proxy_url молча ушёл бы на
   env. Отсюда _PoolCurlConfig; иначе правка была бы зелёной и без эффекта.
   Пул пуст в проде → отказ до HTTP и разрыв батча, а не 50 попыток по 5 секунд.

2. GET /admin/scraper/health показывал settings.scraper_proxy_url как «прокси
   источника», пока трафик после #2825/#2831 выбирается пулом по запросу. Теперь тот
   же резолвер, что у боевых путей; пул исчерпан для источника → пусто, а не статичный
   узел (зелёная строка на месте отказа хуже пустой). Вердикт пулу отсюда НЕ уходит:
   ipify-проба про доступность ipify, а не про репутацию узла у площадки (#2805).

3. resolve_cian_zhk_url_via_search — вторая нога обогащения ЖК: #2767 перевёл на пул
   только fetch_newbuilding, резолв ЖК-url остался на config.cian_proxy_url. Плюс 403
   там гасился в `return None` — узел получал mark_health(ok=True) и оставался в выдаче
   Циану (механика #2700). Сейчас ветка спящая: resolved_zhk_url=0 во всех 59 прогонах.

Заодно удалён мёртвый resolve_cian_zhk_url: путь /zhk/<id>/ 404-ит с #972, вызывающих
не было ни одного, egress тоже был мимо пула — чинить незачем, удалить честнее.

Тесты красные на старом коде поведенчески (пул не получил вердикт / панель показала
static-env-node вместо пулового узла), не на отсутствии нового имени.

Refs #2830
bot-backend merged commit e17687aed7 into main 2026-08-12 10:53:37 +00:00
bot-backend deleted branch fix/2830-remaining-pool-bypass 2026-08-12 10:53:37 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: lekss361/gendesign#2833
No description provided.