[HIGH] tradein/cian: detail-страницы отдают 403 на 50 из 50 попыток 15 дней подряд — прогон пишет errors=0 и done, все домовые поля Циана нулевые #2700

Closed
opened 2026-08-06 05:55:06 +00:00 by bot-backend · 5 comments
Collaborator

Найдено при проверке «серия и высота потолков Циана не разбираются» (эпик #2674). Разбор работает — предпосылка опровергнута. Не работает то, что его кормит, и это не видно ни по одному статусу.

Прогон отчитывается успехом при стопроцентном отказе подзадачи

Четыре последних прогона cian_city_sweep, счётчики дословно:

3258 | 2026-08-06 02:49 | done | detail_attempted 50 | detail_failed 50 | detail_enriched 0 | errors_count 0
3185 | 2026-08-05 04:16 | done | detail_attempted 50 | detail_failed 50 | detail_enriched 0 | errors_count 48
3112 | 2026-08-04 03:25 | done | detail_attempted 50 | detail_failed 50 | detail_enriched 0 | errors_count 45
3034 | 2026-08-03 04:59 | done | detail_attempted 50 | detail_failed 50 | detail_enriched 0 | errors_count 15

Пятьдесят попыток из пятидесяти неудачны — каждый день. В последнем прогоне при этом errors_count: 0 и итоговая строка лога:

cian-sweep run_id=3258 done: anchors=5/5 lots=1680 (ins=59/upd=626) detail=0/50 houses=0/40 errors=0

«errors=0» напечатано в одной строке с «detail=0/50». Счётчик ошибок не считает отказы подзадач, поэтому прогон, у которого целое направление работы отказало полностью, внешне неотличим от здорового.

Причина

WARNING scraper_kit.providers.cian.detail: Cian detail fetch https://ekb.cian.ru/sale/flat/332663200/... → HTTP 403

HTTP 403 на каждой странице. Выдача при этом собирается нормально (1 680 лотов за прогон) — 403 приходит только на детальные страницы, которым нужна авторизация.

Согласуется с уже известным: куки Циана протухли 2026-06-30. Сегодня в 03:22 cian_history_backfill впервые честно отчитался skipped с причиной «куки Циана протухли (36 дн. назад)» — это работает #2658. Но второй потребитель тех же кук, cian_city_sweep, честного отказа не получил и продолжает отчитываться успехом.

Что из-за этого стоит

listings.detail_enriched_at у Циана заморожен на 2026-07-22 (15 дней), обогащено 1 571 из 21 799.

Все домовые поля, которые наполняет только Cian-detail, нулевые во всех 9 457 домах:

Поле Непустых
series_name 0
entrances 0
flat_count 0
heat_supply_type 0

Серия при этом выводится на экран (SaleShareList.tsx:192) — там всегда пусто.

Важное следствие для оценки чужих правок

Две правки разбора Циана уже смержены — BTI из offerData (c232772e, 2026-08-05 23:39) и разбор высоты потолков. Прогон cian_city_sweep бежал после деплоя обеих (2026-08-06 02:49) и дал ноль. То есть это не «не проверено, продюсер не запускался», а «запускался и заблокирован выше по потоку». Любая проверка этих правок будет давать ноль, пока 403 не снят, и трактовать этот ноль как «правка не работает» — ошибка.

Что нужно

  1. Владельцу: восстановить учётную запись/куки Циана. Автоперелогин недоступен — логин задекларирован в конфиге, но в проде отсутствует (#2674). Без этого весь Cian-detail стоит.
  2. errors_count обязан учитывать отказы подзадач. Прогон с detail_failed == detail_attempted не done. Паттерн уже есть у соседних источников (#2625/#2658/#2657).
  3. Проверка кук должна быть общей для всех потребителей, а не только у cian_history_backfill: сейчас один и тот же протухший ключ даёт честный skipped в одном задании и зелёный done в другом.

Связано: #2674, #2670, #2673, #2658, #2625, #2699, #2435.

Найдено при проверке «серия и высота потолков Циана не разбираются» (эпик #2674). Разбор **работает** — предпосылка опровергнута. Не работает то, что его кормит, и это не видно ни по одному статусу. ## Прогон отчитывается успехом при стопроцентном отказе подзадачи Четыре последних прогона `cian_city_sweep`, счётчики дословно: ``` 3258 | 2026-08-06 02:49 | done | detail_attempted 50 | detail_failed 50 | detail_enriched 0 | errors_count 0 3185 | 2026-08-05 04:16 | done | detail_attempted 50 | detail_failed 50 | detail_enriched 0 | errors_count 48 3112 | 2026-08-04 03:25 | done | detail_attempted 50 | detail_failed 50 | detail_enriched 0 | errors_count 45 3034 | 2026-08-03 04:59 | done | detail_attempted 50 | detail_failed 50 | detail_enriched 0 | errors_count 15 ``` Пятьдесят попыток из пятидесяти неудачны — **каждый день**. В последнем прогоне при этом `errors_count: 0` и итоговая строка лога: ``` cian-sweep run_id=3258 done: anchors=5/5 lots=1680 (ins=59/upd=626) detail=0/50 houses=0/40 errors=0 ``` **«errors=0» напечатано в одной строке с «detail=0/50».** Счётчик ошибок не считает отказы подзадач, поэтому прогон, у которого целое направление работы отказало полностью, внешне неотличим от здорового. ## Причина ``` WARNING scraper_kit.providers.cian.detail: Cian detail fetch https://ekb.cian.ru/sale/flat/332663200/... → HTTP 403 ``` **HTTP 403 на каждой странице.** Выдача при этом собирается нормально (1 680 лотов за прогон) — 403 приходит только на детальные страницы, которым нужна авторизация. Согласуется с уже известным: куки Циана протухли **2026-06-30**. Сегодня в 03:22 `cian_history_backfill` впервые честно отчитался `skipped` с причиной «куки Циана протухли (36 дн. назад)» — это работает #2658. Но второй потребитель тех же кук, `cian_city_sweep`, честного отказа не получил и продолжает отчитываться успехом. ## Что из-за этого стоит `listings.detail_enriched_at` у Циана заморожен на **2026-07-22** (15 дней), обогащено 1 571 из 21 799. Все домовые поля, которые наполняет только Cian-detail, **нулевые во всех 9 457 домах**: | Поле | Непустых | |---|---:| | `series_name` | 0 | | `entrances` | 0 | | `flat_count` | 0 | | `heat_supply_type` | 0 | Серия при этом **выводится на экран** (`SaleShareList.tsx:192`) — там всегда пусто. ## Важное следствие для оценки чужих правок Две правки разбора Циана уже смержены — BTI из `offerData` (`c232772e`, 2026-08-05 23:39) и разбор высоты потолков. Прогон `cian_city_sweep` **бежал после деплоя обеих** (2026-08-06 02:49) и дал ноль. То есть это не «не проверено, продюсер не запускался», а «запускался и заблокирован выше по потоку». Любая проверка этих правок будет давать ноль, пока 403 не снят, и трактовать этот ноль как «правка не работает» — ошибка. ## Что нужно 1. **Владельцу: восстановить учётную запись/куки Циана.** Автоперелогин недоступен — логин задекларирован в конфиге, но в проде отсутствует (#2674). Без этого весь Cian-detail стоит. 2. **`errors_count` обязан учитывать отказы подзадач.** Прогон с `detail_failed == detail_attempted` не `done`. Паттерн уже есть у соседних источников (#2625/#2658/#2657). 3. **Проверка кук должна быть общей для всех потребителей**, а не только у `cian_history_backfill`: сейчас один и тот же протухший ключ даёт честный `skipped` в одном задании и зелёный `done` в другом. Связано: #2674, #2670, #2673, #2658, #2625, #2699, #2435.
Author
Collaborator

Тот же корень убил седьмой источник эстиматора — и это доказуемо, а не предположение

external_valuations на проде:

Источник Строк filters_hash Последняя строка
yandex_valuation 1 519 0 2026-08-05 13:57
cian_valuation 139 139 2026-06-29 16:19

Оба источника — on-demand: строка появляется, когда пользователь запрашивает оценку. Ни у того, ни у другого нет строки в scrape_schedules, то есть оба срабатывают по одному и тому же триггеру.

Яндекс пишет строки до вчерашнего дня. Значит оценки запрашиваются. Циан не написал ни одной с 29 июня — за день до того, как протухли куки.

Это не «источник простаивает», это источник отказывает, и соседний источник по тому же триггеру служит контрольной группой, отделяющей одно от другого. Без него «139 строк, последняя 29 июня» одинаково читалось бы как «никто не просил оценок».

Практический итог: в каждой выданной с 29 июня оценке седьмой источник молча отсутствовал. Ни алерта, ни следа в статусах — то же, что и с cian_city_sweep выше.

Побочно: filters_hash у Яндекса — не второй такой же баг

0 из 1 519 выглядит как повторение дефекта, починенного в #2689. Проверено: ключ filtersHash не встречается ни в одном сохранённом ответе Яндекса (0 из 1 519 payload'ов содержат подстроку). Колонка циан-специфична по природе ответа, у Яндекса заполнять её нечем. Предпосылка снята, работы тут нет.

## Тот же корень убил седьмой источник эстиматора — и это доказуемо, а не предположение `external_valuations` на проде: | Источник | Строк | `filters_hash` | Последняя строка | |---|---:|---:|---| | `yandex_valuation` | 1 519 | 0 | **2026-08-05 13:57** | | `cian_valuation` | 139 | 139 | **2026-06-29 16:19** | Оба источника — **on-demand**: строка появляется, когда пользователь запрашивает оценку. Ни у того, ни у другого нет строки в `scrape_schedules`, то есть оба срабатывают по одному и тому же триггеру. Яндекс пишет строки до вчерашнего дня. Значит **оценки запрашиваются**. Циан не написал ни одной с 29 июня — за день до того, как протухли куки. Это не «источник простаивает», это **источник отказывает**, и соседний источник по тому же триггеру служит контрольной группой, отделяющей одно от другого. Без него «139 строк, последняя 29 июня» одинаково читалось бы как «никто не просил оценок». Практический итог: в каждой выданной с 29 июня оценке седьмой источник молча отсутствовал. Ни алерта, ни следа в статусах — то же, что и с `cian_city_sweep` выше. ## Побочно: `filters_hash` у Яндекса — не второй такой же баг 0 из 1 519 выглядит как повторение дефекта, починенного в #2689. Проверено: ключ `filtersHash` **не встречается ни в одном** сохранённом ответе Яндекса (0 из 1 519 payload'ов содержат подстроку). Колонка циан-специфична по природе ответа, у Яндекса заполнять её нечем. Предпосылка снята, работы тут нет.
Author
Collaborator

Проверка на проде 2026-08-07: ни один из трёх пунктов не закрыт

Проверял по существу, а не по упоминаниям задачи в PR. Ни одна из вчерашних cian-правок
(#2705 просмотры, #2768 новостройки) этой задачи не касается.

п.1 (учётная запись Циана — владельцу) — не сделано. Прогон cian_history_backfill
07.08 02:03 честно отчитался skipped с причиной «куки Циана протухли 2026-06-30
(37 дн. назад)».

п.2 (errors_count обязан учитывать отказы подзадач) — не сделано. Ровно та строка, что в
шапке задачи, сутки спустя:

3344 | 2026-08-07 02:16 | done | detail_attempted 50 | detail_failed 50 | detail_enriched 0 | errors_count 0
3258 | 2026-08-06 02:49 | done | detail_attempted 50 | detail_failed 50 | detail_enriched 0 | errors_count 0

Пятьдесят из пятидесяти неудачны, ошибок ноль, статус done. Городские sweep'ы Циана
(Первоуральск, Серов, Каменск, Нижний Тагил, Верхняя Пышма) — то же самое: detail_failed
равен detail_attempted, статус done.

п.3 (общая проверка кук) — не сделано. Один и тот же протухший ключ по-прежнему даёт
честный skipped у cian_history_backfill и зелёный done у cian_city_sweep.

Цена не изменилась ни на строку:

series_name      0 из 9 625 домов
entrances        0
flat_count       0
heat_supply_type 0

listings.detail_enriched_at у Циана заморожен на 2026-07-22 (16-й день)

Седьмой источник эстиматора — контрольная группа держится:

yandex_valuation  1 531 строка   последняя 2026-08-07 08:10   ← оценки запрашиваются
cian_valuation      139 строк    последняя 2026-06-29 16:19   ← источник отказывает

Побочно: из-за того же 403 не может дать эффекта правка #2669 (просмотры Циана) —
views_total пуст у всех 21 951 объявления, потому что detail-путь не доходит. Ноль там
означает «заблокировано выше по потоку», а не «правка не работает» — ровно то, о чём
предупреждает раздел «Важное следствие» этой задачи.

Оставляю открытой. п.2 и п.3 чинятся кодом и не ждут владельца.

## Проверка на проде 2026-08-07: ни один из трёх пунктов не закрыт Проверял по существу, а не по упоминаниям задачи в PR. Ни одна из вчерашних cian-правок (#2705 просмотры, #2768 новостройки) этой задачи не касается. **п.1 (учётная запись Циана — владельцу) — не сделано.** Прогон `cian_history_backfill` 07.08 02:03 честно отчитался `skipped` с причиной «куки Циана протухли 2026-06-30 (**37 дн.** назад)». **п.2 (`errors_count` обязан учитывать отказы подзадач) — не сделано.** Ровно та строка, что в шапке задачи, сутки спустя: ``` 3344 | 2026-08-07 02:16 | done | detail_attempted 50 | detail_failed 50 | detail_enriched 0 | errors_count 0 3258 | 2026-08-06 02:49 | done | detail_attempted 50 | detail_failed 50 | detail_enriched 0 | errors_count 0 ``` Пятьдесят из пятидесяти неудачны, ошибок ноль, статус `done`. Городские sweep'ы Циана (Первоуральск, Серов, Каменск, Нижний Тагил, Верхняя Пышма) — то же самое: `detail_failed` равен `detail_attempted`, статус `done`. **п.3 (общая проверка кук) — не сделано.** Один и тот же протухший ключ по-прежнему даёт честный `skipped` у `cian_history_backfill` и зелёный `done` у `cian_city_sweep`. **Цена не изменилась ни на строку:** ``` series_name 0 из 9 625 домов entrances 0 flat_count 0 heat_supply_type 0 listings.detail_enriched_at у Циана заморожен на 2026-07-22 (16-й день) ``` **Седьмой источник эстиматора — контрольная группа держится:** ``` yandex_valuation 1 531 строка последняя 2026-08-07 08:10 ← оценки запрашиваются cian_valuation 139 строк последняя 2026-06-29 16:19 ← источник отказывает ``` Побочно: из-за того же 403 не может дать эффекта правка #2669 (просмотры Циана) — `views_total` пуст у всех 21 951 объявления, потому что detail-путь не доходит. Ноль там означает «заблокировано выше по потоку», а не «правка не работает» — ровно то, о чём предупреждает раздел «Важное следствие» этой задачи. Оставляю открытой. п.2 и п.3 чинятся кодом и не ждут владельца.
Author
Collaborator

Перемер 2026-08-10: половина чисел задачи устарела, а причина была другой

Актуальные числа против чисел задачи

Что В задаче (25.07-07.08) Прод 10.08
detail-прогоны 50 из 50 отказов, 15 суток 50/50 успешны 08.08 и 09.08, 10/11 сегодня
series_name в домах 0 из 9 625 19 из 9 179
entrances / flat_count / heat_supply_type 0 / 0 / 0 63 / 65 / 80
listings.detail_enriched_at (Циан) заморожен на 22.07 10.08 05:02, обогащено 1 731 из 22 542
views_total (#2669) 0 из 21 951 148
cian_valuation 139 строк, последняя 29.06 139 строк, последняя 29.06 — не изменилось

403 прекратились между прогонами 3344 (07.08 02:16, 50/50 отказ) и 3418 (08.08 03:05, 50/50 успех). Само по себе — без объяснения; объяснение ниже.

Различающая проба по узлам — главный вопрос закрыт

Один и тот же detail-URL, один и тот же код (build_curl_cffi_session + боевые заголовки providers/cian/detail.py), менялся ТОЛЬКО прокси-узел. 4 запроса, пауза 4 с.

узел метка exit-IP статус размер маркеры defaultState
1 asocks-residential-1 46.8.110.92 403 21 564 cian_waf_block
9 asocks-mobile-1 5.227.16.0 200 617 352 нет ok
10 asocks-mobile-2 95.104.183.29 200 617 355 нет ok
11 asocks-mobile-3 95.55.49.98 200 617 407 нет ok

Случай (б): отбиты конкретные узлы. Не (а) — площадка отдаёт 200 трём узлам из четырёх прямо сейчас. Не (в) — запрос тот же самый, что и на 403.

Опровергнутые предпосылки задачи

  1. «403 приходит только на детальные страницы, которым нужна авторизация» — detail-страница авторизации НЕ требует. Все три 200 выше получены без единой куки; в коде fetch_detail куки не отправляет вовсе (build_curl_cffi_session с двумя заголовками). Связь 403 с протухшими 30.06 куками — совпадение по времени, не причина.
  2. «Циан нас забанил» — забанена пара «узел × Циан». Тот же самый узел 1 в тот же момент рабочий для других источников.
  3. errors_count не «не считает отказы подзадач» из вредности — 403 гасился в return None внутри провайдера, наружу не выходило ничего. Тот же return None сообщал пулу mark_health(ok=True) на отбитый узел, поэтому пул продолжал выдавать его Циану. Один корень на все три симптома, а не три дефекта.

Что чинится кодом — PR #2821

  • 403 → CianBlockedError (наследник ProxyBanError): generic curl-слой снимает узел с выдачи Циану (per-source бан), вызывающий считает исключение в errors_count, ротация фазы работает. 404 баном не считается.
  • mark_done (обе копии): прогон, у которого отказала КАЖДАЯ попытка целой фазы (>=3 попыток), больше не done. Замер за 90 суток: 52 прогона из 3 292 done (1.6%), из них 11 — avito_city_sweep*, про которые никто не знал.

Тест красный на старом коде в трёх утверждениях (узел не банился; оба финализатора писали done прогону 3258).

Что уходит владельцу — и это НЕ прокси

Седьмой источник эстиматора стоит на куках, и вот проверка, отделяющая куки от блокировки: тот же запрос на калькулятор через ЗДОРОВЫЙ узел 10 отдал HTTP 200, 352 048 байт, маркеров нет, isAuthenticated=false.

То есть площадка нас пускает, а сессия мертва. В БД одна запись: account_user_id=75544897, две куки (DMIR_AUTH, _CIAN_GK), загружены 31.05, expires_at_estimate=30.06 — но это ОЦЕНКА (upload + 30 дней), а не факт; факт даёт проба выше, и он тот же: вход нужен заново.

Цена простоя числом:

  • 320 оценок выдано с 29.06 по 07.08 без седьмого источника (Яндекс за то же окно написал 107 строк — оценки запрашивались, отказывал именно Циан);
  • 42 суток без cian_history_backfill (последний успешный прогон 29.06; сегодня в 02:16 снова честный skipped).

Автоперелогина нет — подтверждаю: providers/cian/session.py умеет только save_session/load_session/verify_session, логин делает Playwright-скрипт scripts/local-cian/ с машины владельца.

Побочно: фаза houses отказывает 10 из 10 прямо сейчас

Прогоны 3344, 3418, 3500, 3597 (сегодня 04:53): houses_attempted=10, houses_failed=10, houses_enriched=0 — включая прогон ПОСЛЕ мержа #2798/#2801/#2804. Это #2767, не эта задача, но после PR #2821 такой прогон станет failed и перестанет быть невидимым.


Пробы: 4 detail-запроса + 1 запрос калькулятора, паузы 4 с, только чтение. Записей в БД не делалось.

## Перемер 2026-08-10: половина чисел задачи устарела, а причина была другой ### Актуальные числа против чисел задачи | Что | В задаче (25.07-07.08) | Прод 10.08 | |---|---|---| | detail-прогоны | 50 из 50 отказов, 15 суток | **50/50 успешны 08.08 и 09.08**, 10/11 сегодня | | `series_name` в домах | 0 из 9 625 | **19** из 9 179 | | `entrances` / `flat_count` / `heat_supply_type` | 0 / 0 / 0 | **63 / 65 / 80** | | `listings.detail_enriched_at` (Циан) | заморожен на 22.07 | **10.08 05:02**, обогащено 1 731 из 22 542 | | `views_total` (#2669) | 0 из 21 951 | **148** | | `cian_valuation` | 139 строк, последняя 29.06 | **139 строк, последняя 29.06** — не изменилось | 403 прекратились между прогонами 3344 (07.08 02:16, 50/50 отказ) и 3418 (08.08 03:05, 50/50 успех). Само по себе — без объяснения; объяснение ниже. ### Различающая проба по узлам — главный вопрос закрыт Один и тот же detail-URL, один и тот же код (`build_curl_cffi_session` + боевые заголовки `providers/cian/detail.py`), менялся ТОЛЬКО прокси-узел. 4 запроса, пауза 4 с. | узел | метка | exit-IP | статус | размер | маркеры | `defaultState` | |---|---|---|---:|---:|---|---| | 1 | asocks-residential-1 | 46.8.110.92 | **403** | 21 564 | `cian_waf_block` | — | | 9 | asocks-mobile-1 | 5.227.16.0 | 200 | 617 352 | нет | ok | | 10 | asocks-mobile-2 | 95.104.183.29 | 200 | 617 355 | нет | ok | | 11 | asocks-mobile-3 | 95.55.49.98 | 200 | 617 407 | нет | ok | **Случай (б): отбиты конкретные узлы.** Не (а) — площадка отдаёт 200 трём узлам из четырёх прямо сейчас. Не (в) — запрос тот же самый, что и на 403. ### Опровергнутые предпосылки задачи 1. **«403 приходит только на детальные страницы, которым нужна авторизация»** — detail-страница авторизации НЕ требует. Все три 200 выше получены **без единой куки**; в коде `fetch_detail` куки не отправляет вовсе (`build_curl_cffi_session` с двумя заголовками). Связь 403 с протухшими 30.06 куками — совпадение по времени, не причина. 2. **«Циан нас забанил»** — забанена пара «узел × Циан». Тот же самый узел 1 в тот же момент рабочий для других источников. 3. **`errors_count` не «не считает отказы подзадач» из вредности** — 403 гасился в `return None` внутри провайдера, наружу не выходило ничего. Тот же `return None` сообщал пулу `mark_health(ok=True)` на отбитый узел, поэтому пул продолжал выдавать его Циану. Один корень на все три симптома, а не три дефекта. ### Что чинится кодом — PR #2821 - 403 → `CianBlockedError` (наследник `ProxyBanError`): generic curl-слой снимает узел с выдачи **Циану** (per-source бан), вызывающий считает исключение в `errors_count`, ротация фазы работает. 404 баном не считается. - `mark_done` (обе копии): прогон, у которого отказала КАЖДАЯ попытка целой фазы (>=3 попыток), больше не `done`. Замер за 90 суток: 52 прогона из 3 292 `done` (1.6%), из них 11 — `avito_city_sweep*`, про которые никто не знал. Тест красный на старом коде в трёх утверждениях (узел не банился; оба финализатора писали `done` прогону 3258). ### Что уходит владельцу — и это НЕ прокси Седьмой источник эстиматора стоит на куках, и вот проверка, отделяющая куки от блокировки: тот же запрос на калькулятор через ЗДОРОВЫЙ узел 10 отдал **HTTP 200, 352 048 байт, маркеров нет, `isAuthenticated=false`**. То есть площадка нас пускает, а сессия мертва. В БД одна запись: `account_user_id=75544897`, две куки (`DMIR_AUTH`, `_CIAN_GK`), загружены 31.05, `expires_at_estimate=30.06` — но это ОЦЕНКА (upload + 30 дней), а не факт; факт даёт проба выше, и он тот же: вход нужен заново. **Цена простоя числом:** - **320 оценок** выдано с 29.06 по 07.08 без седьмого источника (Яндекс за то же окно написал 107 строк — оценки запрашивались, отказывал именно Циан); - **42 суток** без `cian_history_backfill` (последний успешный прогон 29.06; сегодня в 02:16 снова честный `skipped`). Автоперелогина нет — подтверждаю: `providers/cian/session.py` умеет только `save_session`/`load_session`/`verify_session`, логин делает Playwright-скрипт `scripts/local-cian/` с машины владельца. ### Побочно: фаза `houses` отказывает 10 из 10 прямо сейчас Прогоны 3344, 3418, 3500, 3597 (сегодня 04:53): `houses_attempted=10, houses_failed=10, houses_enriched=0` — включая прогон ПОСЛЕ мержа #2798/#2801/#2804. Это #2767, не эта задача, но после PR #2821 такой прогон станет `failed` и перестанет быть невидимым. --- Пробы: 4 detail-запроса + 1 запрос калькулятора, паузы 4 с, только чтение. Записей в БД не делалось.
Author
Collaborator

Смержено и проверено на проде

PR #2821 (merged 11:29 UTC) — 403 больше не гаснет в return None: узел снимается с выдачи Циану, отказ доходит до errors_count, прогон со стопроцентно отказавшей фазой перестаёт быть done.
PR #2822 (merged 11:49 UTC) — поправка замера: 42 прогона, а не 52 (в SQL считались пары «прогон × фаза»).

Верификация деплоя по коду в контейнерах, не по релиз-метке:

tradein-scraper:  _raise_if_blocked ×3, _phase_totally_failed ×3 (kit + app)
tradein-backend:  то же

Число с прода — деплойнутая функция по боевым counters (3 574 прогона за 90 суток, обе копии дают одинаковый вердикт на всех):

'done' сейчас: 3293 → под правило попадают 42 (1.3%)
  15 cian_city_sweep · 5 avito_city_sweep · 4 verkhnyaya_pyshma · по 3 nizhniy_tagil/
  kamensk/pervouralsk/serov (cian) · 3 avito_serov · 2 avito_nizhniy_tagil · 1 avito_kamensk

run 3258 (06.08) → failed, фаза 'detail' 50 из 50   ← прогон из шапки задачи
run 3344 (07.08) → failed, фаза 'detail' 50 из 50
run 3418 (08.08) → failed, фаза 'houses' 10 из 10
run 3597 (10.08) → failed, фаза 'houses' 10 из 10   ← сегодняшний, «зелёный»

Критерий приёмки записан ДО факта

A. Ближайший cian_city_sweep, 2026-08-11 ~03:00-05:30 UTC.

SELECT id, status, left(error, 90), counters FROM scrape_runs
WHERE source LIKE 'cian_city_sweep%' AND started_at > '2026-08-11';

Принято: прогон с houses_failed = houses_attempted >= 3 (или то же по detail) имеет status='failed' и error с префиксом phase-honest-status:.
Опровергнуто: такой прогон снова done → правка не доехала до образа либо проводка оборвана.

B. Снятие отбитого узла — не раньше 2026-08-12 08:14 UTC (до этого времени узел 1 и так вне выдачи Циану: его забанила проба #2803).

SELECT proxy_id, source, reason, banned_at, ban_count FROM scrape_proxy_source_bans WHERE source='cian';

Принято: после первого же 403 боевого сбора появляется строка reason='banned:cian' (не probe:browser), и в counters того прогона detail_failed ≤ 3 при кратно большем detail_attempted.
Опровергнуто: снова detail_failed = detail_attempted без строки бана.

Пункты задачи

  • п.2 (errors_count и статус) — закрыт: 403 теперь исключение (растит errors_count у обоих вызывающих), а прогон с полностью отказавшей фазой уходит в failed из mark_done — в ОДНОМ месте на все четыре десятка вызывающих, а не в каждом sweep'е.
  • п.3 (общая проверка кук) — НЕ делаю намеренно, и предпосылка тут сместилась: detail-путь куки не использует вовсе, поэтому «общая проверка кук для всех потребителей» защитила бы только cian_valuation и cian_history_backfill, у которых он и так есть у одного из двух. Отдельный вопрос — молчаливое отсутствие седьмого источника в оценке: estimate_via_cian_valuation возвращает None и на этом всё. Если нужно — заводите отдельной задачей, тут это уже не про 403.
  • п.1 (учётная запись) — владельцу, см. предыдущий комментарий: проба через здоровый узел дала HTTP 200 без маркеров и isAuthenticated=false. Цена: 320 оценок с 29.06 без седьмого источника, 42 суток без cian_history_backfill.

Оставляю открытой до п.1 и до проверки критерия A завтра.

## Смержено и проверено на проде **PR #2821** (merged 11:29 UTC) — 403 больше не гаснет в `return None`: узел снимается с выдачи Циану, отказ доходит до `errors_count`, прогон со стопроцентно отказавшей фазой перестаёт быть `done`. **PR #2822** (merged 11:49 UTC) — поправка замера: 42 прогона, а не 52 (в SQL считались пары «прогон × фаза»). **Верификация деплоя по коду в контейнерах**, не по релиз-метке: ``` tradein-scraper: _raise_if_blocked ×3, _phase_totally_failed ×3 (kit + app) tradein-backend: то же ``` **Число с прода — деплойнутая функция по боевым counters** (3 574 прогона за 90 суток, обе копии дают одинаковый вердикт на всех): ``` 'done' сейчас: 3293 → под правило попадают 42 (1.3%) 15 cian_city_sweep · 5 avito_city_sweep · 4 verkhnyaya_pyshma · по 3 nizhniy_tagil/ kamensk/pervouralsk/serov (cian) · 3 avito_serov · 2 avito_nizhniy_tagil · 1 avito_kamensk run 3258 (06.08) → failed, фаза 'detail' 50 из 50 ← прогон из шапки задачи run 3344 (07.08) → failed, фаза 'detail' 50 из 50 run 3418 (08.08) → failed, фаза 'houses' 10 из 10 run 3597 (10.08) → failed, фаза 'houses' 10 из 10 ← сегодняшний, «зелёный» ``` ## Критерий приёмки записан ДО факта **A. Ближайший `cian_city_sweep`, 2026-08-11 ~03:00-05:30 UTC.** ```sql SELECT id, status, left(error, 90), counters FROM scrape_runs WHERE source LIKE 'cian_city_sweep%' AND started_at > '2026-08-11'; ``` Принято: прогон с `houses_failed = houses_attempted >= 3` (или то же по detail) имеет `status='failed'` и `error` с префиксом `phase-honest-status:`. Опровергнуто: такой прогон снова `done` → правка не доехала до образа либо проводка оборвана. **B. Снятие отбитого узла — не раньше 2026-08-12 08:14 UTC** (до этого времени узел 1 и так вне выдачи Циану: его забанила проба #2803). ```sql SELECT proxy_id, source, reason, banned_at, ban_count FROM scrape_proxy_source_bans WHERE source='cian'; ``` Принято: после первого же 403 боевого сбора появляется строка `reason='banned:cian'` (не `probe:browser`), и в counters того прогона `detail_failed` ≤ 3 при кратно большем `detail_attempted`. Опровергнуто: снова `detail_failed = detail_attempted` без строки бана. ## Пункты задачи - **п.2 (`errors_count` и статус)** — закрыт: 403 теперь исключение (растит `errors_count` у обоих вызывающих), а прогон с полностью отказавшей фазой уходит в `failed` из `mark_done` — в ОДНОМ месте на все четыре десятка вызывающих, а не в каждом sweep'е. - **п.3 (общая проверка кук)** — НЕ делаю намеренно, и предпосылка тут сместилась: detail-путь куки не использует вовсе, поэтому «общая проверка кук для всех потребителей» защитила бы только `cian_valuation` и `cian_history_backfill`, у которых он и так есть у одного из двух. Отдельный вопрос — молчаливое отсутствие седьмого источника в оценке: `estimate_via_cian_valuation` возвращает `None` и на этом всё. Если нужно — заводите отдельной задачей, тут это уже не про 403. - **п.1 (учётная запись)** — владельцу, см. предыдущий комментарий: проба через здоровый узел дала HTTP 200 без маркеров и `isAuthenticated=false`. Цена: 320 оценок с 29.06 без седьмого источника, 42 суток без `cian_history_backfill`. Оставляю открытой до п.1 и до проверки критерия A завтра.
lekss361 added the
bug
scope/backend
scrapers
tradein
labels 2026-08-16 10:25:17 +00:00
Owner

Закрываю по итогам разбора трекера 16.08.2026

Вердикт: сделано кодом.

Оба симптома закрыты смерженными PR #2821 (403 больше не гасится молча, узел снимается) и #2822 (поправка замера).

Доказательство: 20ec6a5d fix(tradein/cian): 403 снимает узел с выдачи, а не гаснет в return None (#2700) (#2821); 74344f7b docs (#2822)

Независимая проверка. Вердикт отдельно проверялся вторым проходом, задачей которого было именно опровергнуть закрытие, а не подтвердить его:

Проверил прод, а не только PR. п.2 (errors_count/статус) — живой: 8 прогонов с error LIKE 'phase-honest-status:%' (последний 16.08 06:21, avito_city_sweep failed, 'фаза detail отказала полностью'). Cian detail починился: прогоны cian_city_sweep 14-16.08 — detail_failed=0 при detail_attempted 7-50, houses_failed=0; поля домов больше не нулевые (series_name 126, entrances 595, flat_count 597, heat_supply_type 632 из 9587 — в задаче было 0/0/0/0). п.1 (учётка Циана, владельцу) де-факто закрыт: external_valuations source='cian_valuation' — 147 строк, последняя 14.08 17:30 с реальной ценой 19 100 000 и accuracy=96 (в задаче: 139 строк, последняя 29.06); cian_history_backfill 13-16.08 идёт status='done' без error, а не skipped «куки протухли». п.3 автор снял осознанно с доказанной предпосылкой (detail-путь кук не отправляет вовсе), и после восстановления сессии он моот. Единственная придирка: «оба симптома закрыты #2821/#2822» — формулировка неточная (#2822 это только поправка замера), но по существу задача закрываема.

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

## Закрываю по итогам разбора трекера 16.08.2026 **Вердикт:** сделано кодом. Оба симптома закрыты смерженными PR #2821 (403 больше не гасится молча, узел снимается) и #2822 (поправка замера). **Доказательство:** 20ec6a5d fix(tradein/cian): 403 снимает узел с выдачи, а не гаснет в return None (#2700) (#2821); 74344f7b docs (#2822) **Независимая проверка.** Вердикт отдельно проверялся вторым проходом, задачей которого было именно опровергнуть закрытие, а не подтвердить его: > Проверил прод, а не только PR. п.2 (errors_count/статус) — живой: 8 прогонов с error LIKE 'phase-honest-status:%' (последний 16.08 06:21, avito_city_sweep failed, 'фаза detail отказала полностью'). Cian detail починился: прогоны cian_city_sweep 14-16.08 — detail_failed=0 при detail_attempted 7-50, houses_failed=0; поля домов больше не нулевые (series_name 126, entrances 595, flat_count 597, heat_supply_type 632 из 9587 — в задаче было 0/0/0/0). п.1 (учётка Циана, владельцу) де-факто закрыт: external_valuations source='cian_valuation' — 147 строк, последняя 14.08 17:30 с реальной ценой 19 100 000 и accuracy=96 (в задаче: 139 строк, последняя 29.06); cian_history_backfill 13-16.08 идёт status='done' без error, а не skipped «куки протухли». п.3 автор снял осознанно с доказанной предпосылкой (detail-путь кук не отправляет вовсе), и после восстановления сессии он моот. Единственная придирка: «оба симптома закрыты #2821/#2822» — формулировка неточная (#2822 это только поправка замера), но по существу задача закрываема. Если что-то из перечисленного всё же живо — переоткройте задачу, разбор мог упустить частный случай.
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#2700
No description provided.