Cian отдаёт просмотры не числом, а фразой:
"stats":{"totalViewsFormattedString":"146 просмотров, 8 за сегодня"}
(дословно из tests/fixtures/cian_flat_330982715.html). `_parse_views` звала
на ней int() → ValueError → свой же except → None. Прод: views_total пуст
у ВСЕХ 21 799 cian-листингов, включая 1 571 detail-обогащённый. У соседей
потери нет (avito 12 350/12 352, domklik 6 296/6 296, yandex 1 146/1 210) —
дефект ровно один и только у Cian.
Разбор теперь достаёт из фразы оба числа: «за сегодня» живёт в её хвосте,
отдельного ключа todayViewsFormattedString в ответе нет (в фикстуре его
нет вовсе — прежний вызов по нему всегда возвращал None). Колонка
listings.views_today существует с 019_listings_alter_cian.sql и уже
пишется тем же UPDATE — новых полей не заводим.
Формы, покрытые тестами: фраза из фикстуры дословно, "1 просмотр",
"0 просмотров", "1 234 просмотра" с обычным пробелом и с NBSP,
narrow-NBSP, голое "1 234", пусто/None/строка без цифр → (None, None).
Бэкфилл невозможен: исходной фразы в БД нет — 0 вхождений
ViewsFormattedString в listings.raw_payload (21 799 строк, ключа stats нет
ни у одной) и 0 в listing_sources.raw_payload по всем пяти источникам.
Миграция не заводится.
Эффект на проде появится только после возобновления cian-detail: парсер
стоит с 22 июля (max(detail_enriched_at)=2026-07-22, HTTP 403 из-за
протухших кук, #2700). До этого проверка правки — только на сохранённом
ответе.
Refs #2669