fix(tradein): decode Avito houses URL-encoded __preloadedState__ (#566) #618

Merged
Light1YT merged 1 commit from feat/tradein-avito-houses-fix into main 2026-05-28 10:58:55 +00:00
Owner

Summary

Avito сменил формат SSR state-блоба houses-каталога → парсер молча перестал наполнять houses (starve'ит #6 same-building + #569 deal-центроиды). Воркер снял живой fixture (curl_cffi chrome120, не заблокирован) и пофиксил 3 ломающих изменения:

  1. __preloadedState__ теперь URL-encoded литерал (был JSON.parse js-escaped) → urllib.parse.unquote + json.loads
  2. виджеты обёрнуты в placeholders[0].widgets
  3. developmentData re-nested под props.housePage, rating → ratingPreview

Decode вынесен в pure _extract_preloaded_state (fallback на старую форму), _flatten_widgets, tolerant _parse_house_page.

Tests

Real-HTML fixture (Yumasheva-6 EKB) + 4 regression → 22 passed. Ruff clean. code-reviewer APPROVE (regex anchoring, decode safety no-eval, backward-compat, delisted-house graceful, fixture без PII).

Deploy

Миграций нет. После merge cron-sweep снова наполняет houses. Public API не изменился.

Closes #566.

## Summary Avito сменил формат SSR state-блоба houses-каталога → парсер молча перестал наполнять houses (starve'ит #6 same-building + #569 deal-центроиды). Воркер снял живой fixture (curl_cffi chrome120, не заблокирован) и пофиксил 3 ломающих изменения: 1. `__preloadedState__` теперь URL-encoded литерал (был JSON.parse js-escaped) → urllib.parse.unquote + json.loads 2. виджеты обёрнуты в placeholders[0].widgets 3. developmentData re-nested под props.housePage, rating → ratingPreview Decode вынесен в pure _extract_preloaded_state (fallback на старую форму), _flatten_widgets, tolerant _parse_house_page. ## Tests Real-HTML fixture (Yumasheva-6 EKB) + 4 regression → 22 passed. Ruff clean. code-reviewer APPROVE (regex anchoring, decode safety no-eval, backward-compat, delisted-house graceful, fixture без PII). ## Deploy Миграций нет. После merge cron-sweep снова наполняет houses. Public API не изменился. Closes #566.
Light1YT added 1 commit 2026-05-28 10:58:53 +00:00
Avito switched the houses-catalog state blob from JSON.parse("<js-escaped>")
to a URL-encoded string literal, wrapped the 10 widgets in
placeholders[0].widgets, и re-nested developmentData под props.housePage.
JS-unescape path silently failed → houses rows перестали наполняться
(starve'ит #6 same-building + #569 deal centroids).

Extract decode в pure _extract_preloaded_state (urllib.parse.unquote,
JSON.parse fallback для старой формы), add _flatten_widgets, и сделать
_parse_house_page tolerant к обеим developmentData/ratingPreview формам.
Real-HTML fixture (Yumasheva-6 EKB) + 4 regression-теста.

code-reviewer:  APPROVE no critical (regex anchoring verified, decode
safe — no eval/unicode_escape, backward-compat реальный, delisted-house
envelope degrade'ит gracefully, fixture без PII/secrets). Tests: 22 passed.

Closes #566
Light1YT merged commit 1058dc2430 into main 2026-05-28 10:58:55 +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#618
No description provided.