fix(tradein): cian newbuilding MFE/reliability drift — initialState extraction (#972)
All checks were successful
CI / changes (push) Successful in 8s
CI / backend-tests (push) Has been skipped
CI / frontend-tests (push) Has been skipped
CI / openapi-codegen-check (push) Has been skipped
CI / changes (pull_request) Successful in 6s
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

Cian переименовал MFE ЖК-карточки и переместил reliability-контейнер, из-за чего
fetch_newbuilding получал initialState=None → failed_fetch для всех домов
(verified live 2026-06-15 на прод-браузере через мобильный egress):

- MFE: 'newbuilding-card-desktop-fichering-frontend' → 'newbuilding-card-desktop-frontend'
  (старое имя на странице отсутствует → extract_state=None → backfill succeeded=0)
- reliability: initialState.reliability → initialState.reliabilityState.reliability
  (inner dict сохранил форму {checkStatus, details[], banner, actions})

Проверено на ЖК «Светлый» (nb 17556): newbuilding.id, realtyValuation chart (27 точек),
reliabilityState.reliability.checkStatus + 2 details — всё извлекается.

test_fetch_newbuilding_parses_state: fixture обновлён под reliabilityState.reliability.
Полный suite зелёный (1779 passed; 2 несвязанных env-only локальных падения —
cian_valuation cache / search_api auth — в CI проходят).

Refs #972
This commit is contained in:
bot-backend 2026-06-15 21:12:05 +03:00
parent 483fdb0caa
commit 891598a5d7
2 changed files with 13 additions and 8 deletions

View file

@ -1,12 +1,12 @@
"""Cian.ru newbuilding (ЖК) catalog page scraper.
URL: https://zhk-<slug>-<city>-i.cian.ru/
MFE: 'newbuilding-card-desktop-fichering-frontend', key: 'initialState'
MFE: 'newbuilding-card-desktop-frontend', key: 'initialState'
Sister state containers extracted from same MFE initialState top-level keys:
- realtyValuation: 7-month price chart (data.priceDynamics.chart.data.{labels,values})
houses_price_dynamics
- reliability: наш.дом.рф checkStatus + details[] house_reliability_checks
- reliabilityState.reliability: наш.дом.рф checkStatus + details[] house_reliability_checks
- offers: grouped by roomType (fromDeveloperRooms[].layouts[])
- reviews: house reviews list
- housesByTurn: корпуса по очередям (stored as jsonb on houses)
@ -140,7 +140,9 @@ async def fetch_newbuilding(
async with BrowserFetcher() as browser:
html = await browser.fetch(zhk_url)
mfe = "newbuilding-card-desktop-fichering-frontend"
# Cian ЖК-карточка: MFE 'newbuilding-card-desktop-frontend', key 'initialState'
# (verified live 2026-06-15).
mfe = "newbuilding-card-desktop-frontend"
nb_state = extract_state(html, mfe=mfe, key="initialState")
if nb_state is None:
@ -185,8 +187,9 @@ async def fetch_newbuilding(
result.realty_valuation_chart = _extract_chart(rv_state)
result.raw_sister_states["realtyValuation"] = rv_state
# reliability (наш.дом.рф) — located at initialState.reliability (sec 15.6)
rel_state = top.get("reliability") or mfe_states.get("reliability")
# reliability (наш.дом.рф) — initialState.reliabilityState.reliability
# ({checkStatus, details[], banner, actions}, verified live 2026-06-15).
rel_state = (top.get("reliabilityState") or {}).get("reliability")
if rel_state and isinstance(rel_state, dict):
result.reliability_checks = _extract_reliability_checks(rel_state)
result.raw_sister_states["reliability"] = rel_state

View file

@ -343,9 +343,11 @@ async def test_fetch_newbuilding_parses_state(monkeypatch):
}
}
},
"reliability": {
"checkStatus": {"status": "reliable", "title": "Проверено"},
"details": [{"type": "problemHousesRegistry", "iconType": "success"}],
"reliabilityState": {
"reliability": {
"checkStatus": {"status": "reliable", "title": "Проверено"},
"details": [{"type": "problemHousesRegistry", "iconType": "success"}],
},
},
}