Скрапперы A2: четыре точки ходят мимо пула прокси, и тёплый контекст сайдкара ключуется по провайдеру, а не по узлу #3197

Closed
opened 2026-08-28 19:17:25 +00:00 by lekss361 · 3 comments
Owner

Второй шаг унификации. Две правки, которые обязаны ехать одним PR — по отдельности вторая делает первую опасной.

Часть 1: обход пула прокси

BrowserFetcher имеет use_pool=False и proxy_provider=None дефолтом. Кто конструирует его короткой формой — молча идёт мимо пула из четырёх узлов, через единственный статический SCRAPER_PROXY_URL (сейчас это ASocks mobile-1, узел id=9). У Авито этот же класс бага уже чинили отдельно в #3045.

Точки, ходящие мимо пула (проверено grep'ом 28.08):

  • tradein-mvp/backend/app/tasks/cian_history_backfill.py:136
  • tradein-mvp/packages/scraper-kit/src/scraper_kit/providers/yandex/newbuilding.py:189
  • tradein-mvp/packages/scraper-kit/src/scraper_kit/providers/yandex/newbuilding.py:385
  • tradein-mvp/backend/app/tasks/domclick_detail_backfill.py:283

(admin.py:702 — debug-ручка, её можно оставить как есть или подключить заодно.)

Подключать по одной точке, с суточной паузой между ними: смена egress меняет профиль трафика, и если что-то поедет — надо понимать, у кого именно.

Часть 2: ключ тёплого контекста

В #3193 сайдкар получил переиспользуемый браузерный контекст, и он ключуется по провайдеру. Пока ДомКлик ходит мимо пула, это безвредно — узел всё равно один.

Но как только часть 1 подключит пул, аренда узла начнёт меняться между прогонами и внутри прогона (осознанная ротация после N провалов). Тёплый контекст при этом переживёт смену узла, и куки, установленные с одного exit-IP, поедут с другого. Это ровно тот рассинхрон отпечатка, который защита читает как подмену.

Варианты: ключевать контекст по provider + proxy_node_id, либо сбрасывать контекст при смене аренды. Второй проще и переиспользует уже готовый механизм сброса из #3193.

Заодно у контекста сейчас нет ни TTL, ни потолка числа — тёплый контекст живёт, пока живёт браузер. Стоит ограничить.

Приёмка

  • В scrape_proxies растёт использование всех четырёх узлов, а не одного id=9.
  • Нет прогонов, где после смены аренды идёт серия блоков подряд.
  • NoProxyAvailableError при исчерпании пула отрабатывает штатно на всех подключённых точках (у ДомКлика обработчик появился в #3118, у остальных проверить).

Границы

Не трогать: детект блока и ban_kind (это A1, #3196), чекпоинты, логику сессий. Ротацию exit-IP через rotate_url тоже не сюда — у провайдера лимит 3 в сутки, это отдельный разговор (#3171).

Часть плана унификации скрапперов (шаг A2). Refs #3190, #3193, #3045, #3171

Второй шаг унификации. Две правки, которые **обязаны ехать одним PR** — по отдельности вторая делает первую опасной. ## Часть 1: обход пула прокси `BrowserFetcher` имеет `use_pool=False` и `proxy_provider=None` **дефолтом**. Кто конструирует его короткой формой — молча идёт мимо пула из четырёх узлов, через единственный статический `SCRAPER_PROXY_URL` (сейчас это ASocks mobile-1, узел id=9). У Авито этот же класс бага уже чинили отдельно в #3045. Точки, ходящие мимо пула (проверено grep'ом 28.08): - `tradein-mvp/backend/app/tasks/cian_history_backfill.py:136` - `tradein-mvp/packages/scraper-kit/src/scraper_kit/providers/yandex/newbuilding.py:189` - `tradein-mvp/packages/scraper-kit/src/scraper_kit/providers/yandex/newbuilding.py:385` - `tradein-mvp/backend/app/tasks/domclick_detail_backfill.py:283` (`admin.py:702` — debug-ручка, её можно оставить как есть или подключить заодно.) Подключать **по одной точке, с суточной паузой между ними**: смена egress меняет профиль трафика, и если что-то поедет — надо понимать, у кого именно. ## Часть 2: ключ тёплого контекста В #3193 сайдкар получил переиспользуемый браузерный контекст, и он ключуется **по провайдеру**. Пока ДомКлик ходит мимо пула, это безвредно — узел всё равно один. Но как только часть 1 подключит пул, аренда узла начнёт меняться между прогонами и внутри прогона (осознанная ротация после N провалов). Тёплый контекст при этом переживёт смену узла, и куки, установленные с одного exit-IP, поедут с другого. Это ровно тот рассинхрон отпечатка, который защита читает как подмену. Варианты: ключевать контекст по `provider + proxy_node_id`, либо сбрасывать контекст при смене аренды. Второй проще и переиспользует уже готовый механизм сброса из #3193. Заодно у контекста сейчас нет ни TTL, ни потолка числа — тёплый контекст живёт, пока живёт браузер. Стоит ограничить. ## Приёмка - В `scrape_proxies` растёт использование всех четырёх узлов, а не одного id=9. - Нет прогонов, где после смены аренды идёт серия блоков подряд. - `NoProxyAvailableError` при исчерпании пула отрабатывает штатно на всех подключённых точках (у ДомКлика обработчик появился в #3118, у остальных проверить). ## Границы Не трогать: детект блока и `ban_kind` (это A1, #3196), чекпоинты, логику сессий. Ротацию exit-IP через `rotate_url` тоже не сюда — у провайдера лимит 3 в сутки, это отдельный разговор (#3171). Часть плана унификации скрапперов (шаг A2). Refs #3190, #3193, #3045, #3171
lekss361 added the
bug
priority/p1
scope/backend
scrapers
tradein
labels 2026-08-28 19:17:33 +00:00
Collaborator

Точка 1 (cian_history_backfill) — PR #3382 (после доработки по ревью: пустой пул пробрасывается из общей cian/detail.py::fetch_detail, тест через настоящий fetch_detail). domclick_detail_backfill.py:403 из списка issue уже на пуле (образец), список устарел.

Важное для точек 2-3 (yandex/newbuilding.py:189/385): прод-разбор 06.09 (#3386) показал, что env-фолбэк SCRAPER_PROXY_URL, на котором они сидят, — выключенный узел 9 пула (407); camoufox падает InvalidIP, т.е. эти точки сейчас не «идут мимо пула», а не работают вовсе. И шире: у процесса tradein-backend флагов USE_PROXY_POOL_* нет совсем (только у scraper), так что подключение точки к пулу помогает только там, где путь исполняется в scraper-контейнере. Сначала #3386, потом точки 2-3.

Точка 1 (`cian_history_backfill`) — PR #3382 (после доработки по ревью: пустой пул пробрасывается из общей `cian/detail.py::fetch_detail`, тест через настоящий `fetch_detail`). `domclick_detail_backfill.py:403` из списка issue уже на пуле (образец), список устарел. Важное для точек 2-3 (`yandex/newbuilding.py:189/385`): прод-разбор 06.09 (#3386) показал, что env-фолбэк `SCRAPER_PROXY_URL`, на котором они сидят, — **выключенный узел 9 пула (407)**; camoufox падает `InvalidIP`, т.е. эти точки сейчас не «идут мимо пула», а не работают вовсе. И шире: у процесса `tradein-backend` флагов `USE_PROXY_POOL_*` нет совсем (только у scraper), так что подключение точки к пулу помогает только там, где путь исполняется в scraper-контейнере. Сначала #3386, потом точки 2-3.
Collaborator

PR #3382 смержен и задеплоен (06.09 ~22:50 UTC, BUILD_SHA=b21b1a9 в backend и scraper; маркер caused_by_no_proxy в scraper_kit/providers/cian/detail.py контейнера scraper — есть, в старой сборке не было).

Критерий приёмки (событийный, до 13.09): первый cian_history_backfill после деплоя — в логе сайдкара docker logs tradein-browser | grep 'tradein-browser\[cian\]' строка прокси изменился (override=True) — relaunch перед fetch (или запуск с override без InvalidIP) в окне прогона; до правки Циан proxy в теле /fetch не слал. Плюс: прогон при пустом пуле обязан быть status='failed' + counters.no_proxy_stop=1, не banned. Отрицательный контроль: в логах за сутки до деплоя таких строк для cian нет.

PR #3382 смержен и задеплоен (06.09 ~22:50 UTC, `BUILD_SHA=b21b1a9` в backend и scraper; маркер `caused_by_no_proxy` в `scraper_kit/providers/cian/detail.py` контейнера scraper — есть, в старой сборке не было). **Критерий приёмки (событийный, до 13.09):** первый `cian_history_backfill` после деплоя — в логе **сайдкара** `docker logs tradein-browser | grep 'tradein-browser\[cian\]'` строка `прокси изменился (override=True) — relaunch перед fetch` (или запуск с override без InvalidIP) в окне прогона; до правки Циан `proxy` в теле `/fetch` не слал. Плюс: прогон при пустом пуле обязан быть `status='failed'` + `counters.no_proxy_stop=1`, не `banned`. Отрицательный контроль: в логах за сутки до деплоя таких строк для cian нет.
Collaborator

Точки 2-3 (PR #3389) смержены и задеплоены (07.09 ~01:50 UTC, BUILD_SHA=3fe2d31 в backend и scraper; маркер build_browser_fetcher в providers/yandex/newbuilding.py контейнера scraper — 4 вхождения, в старой сборке 0). Из списка issue не подключена только debug-ручка admin.py:702:511 cian-login).

Критерий приёмки (событийный): yandex_newbuilding_sweep 07.09 03:58 UTC — в логе сайдкара [yandex] … override=True (старый путь proxy в теле не слал), InvalidIP за окно = 0, в counters succeeded > 0; обратное направление — при пустом пуле failed + no_proxy_stop=1 после одного дома, не done после limit.

Точки 2-3 (PR #3389) смержены и задеплоены (07.09 ~01:50 UTC, `BUILD_SHA=3fe2d31` в backend и scraper; маркер `build_browser_fetcher` в `providers/yandex/newbuilding.py` контейнера scraper — 4 вхождения, в старой сборке 0). Из списка issue не подключена только debug-ручка `admin.py:702` (и `:511` cian-login). **Критерий приёмки (событийный):** `yandex_newbuilding_sweep` **07.09 03:58 UTC** — в логе сайдкара `[yandex] … override=True` (старый путь `proxy` в теле не слал), `InvalidIP` за окно = 0, в counters `succeeded > 0`; обратное направление — при пустом пуле `failed` + `no_proxy_stop=1` после одного дома, не `done` после `limit`.
Sign in to join this conversation.
No milestone
No project
No assignees
2 participants
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#3197
No description provided.