fix(tradein): yandex_realty captures house number + parse_rub strips NBSP #593

Merged
Light1YT merged 1 commit from fix/yandex-realty-address-with-house-number into main 2026-05-27 07:23:36 +00:00
Owner

Summary

Two critical bugs в yandex_realty scraper обнаружены при investigating #582 (217 houses без номера дома):

Bug 1 — address терял house number

yandex_realty.py:162-163 брал text() только из anchor tag — это была только улица. House number жил в sibling text node parent контейнера .AddressWithGeoLinks__addressContainer--<hash>.

Fix: читаем text() parent контейнера + normalise whitespace. Получаем улица Малышева, 125 вместо улица Малышева.

Bug 2 — parse_rub() не стрипал NBSP (\xa0)

Yandex SERP форматирует 9\xa0800\xa0000 ₽ через non-breaking space (U+00A0). Прежний .replace(" ", "") стрипал только regular space → int("9\xa0800\xa0000") raise ValueError → parse_rub возвращал None → _card_to_lot silently failed.

На production main парсилось 0/23 cards из live HTML по этой причине. Это объясняет почему yandex_realty_nb накопил так мало houses (305).

Fix: re.sub(r"\s", "", ...) covers NBSP, thin space, tab, etc.

Tests

  • 52/52 pass (yandex_helpers + yandex_realty_serp)
  • 4 новых address tests: letter suffix, slash fraction, district prefix, fallback
  • 2 новых NBSP tests: regular + млн form

Files

  • app/services/scrapers/yandex_realty.py +44/-3 (address fix)
  • app/services/scrapers/yandex_helpers.py +6/-2 (NBSP fix)
  • tests/test_yandex_realty_serp.py +91/-4
  • tests/test_yandex_helpers.py +15

+156 / -7 net.

Post-deploy verification

  • Следующий yandex sweep должен parse ~23/23 cards (было 0/23)
  • Новые yandex_realty_nb houses имеют address с цифрами
  • Existing 217 street-only houses починятся через backfill_house_coords.py (precision filter теперь exact)

Refs #582.

## Summary Two critical bugs в yandex_realty scraper обнаружены при investigating #582 (217 houses без номера дома): ### Bug 1 — address терял house number `yandex_realty.py:162-163` брал text() только из anchor tag — это была только улица. House number жил в sibling text node parent контейнера `.AddressWithGeoLinks__addressContainer--<hash>`. **Fix:** читаем text() parent контейнера + normalise whitespace. Получаем `улица Малышева, 125` вместо `улица Малышева`. ### Bug 2 — parse_rub() не стрипал NBSP (\xa0) Yandex SERP форматирует `9\xa0800\xa0000 ₽` через non-breaking space (U+00A0). Прежний `.replace(" ", "")` стрипал только regular space → `int("9\xa0800\xa0000")` raise ValueError → parse_rub возвращал None → _card_to_lot silently failed. **На production main парсилось 0/23 cards** из live HTML по этой причине. Это объясняет почему `yandex_realty_nb` накопил так мало houses (305). **Fix:** `re.sub(r"\s", "", ...)` covers NBSP, thin space, tab, etc. ## Tests - 52/52 pass (yandex_helpers + yandex_realty_serp) - 4 новых address tests: letter suffix, slash fraction, district prefix, fallback - 2 новых NBSP tests: regular + млн form ## Files - `app/services/scrapers/yandex_realty.py` +44/-3 (address fix) - `app/services/scrapers/yandex_helpers.py` +6/-2 (NBSP fix) - `tests/test_yandex_realty_serp.py` +91/-4 - `tests/test_yandex_helpers.py` +15 **+156 / -7 net.** ## Post-deploy verification - [ ] Следующий yandex sweep должен parse ~23/23 cards (было 0/23) - [ ] Новые `yandex_realty_nb` houses имеют address с цифрами - [ ] Existing 217 street-only houses починятся через `backfill_house_coords.py` (precision filter теперь exact) Refs #582.
Light1YT added 1 commit 2026-05-27 07:23:34 +00:00
Two critical bugs в yandex_realty scraper, обнаружены при investigating
issue #582 (217+ houses без номера дома в address):

1. **Address скрейпился только до street name** (yandex_realty.py:162-163).
   Прежний код брал text() только anchor tag `a[href*="/kupit/kvartira/st-..."]`
   что = только «улица Малышева». House number жил sibling text node parent'а
   `.AddressWithGeoLinks__addressContainer--<hash>`.

   Fix: читаем text() parent контейнера + normalise whitespace → получаем
   «улица Малышева, 125». Fallback на legacy street-only link если container
   отсутствует — не регрессим в NULL.

   Tests cover: letter suffix («2В»), slash («14/3»), district prefix
   («Берёзовский, …»), fallback.

2. **parse_rub() не стрипает NBSP** (yandex_helpers.py:289-294).
   Yandex SERP форматирует «9\xa0800\xa0000» через non-breaking space
   (U+00A0). Прежний `.replace(" ", "")` стрипал только regular space →
   `int("9\xa0800\xa0000")` raise ValueError → возвращали None → scraper
   skipping все listings c ценой.

   На production main парсилось **0/23 cards** из live HTML by-this-reason.
   Это объясняет почему `yandex_realty_nb` накопил мало houses (305) и
   почему `_card_to_lot` silently failed.

   Fix: `re.sub(r"\s", "", ...)` covers `\xa0`, тонкие пробелы, табы и т.д.
   То же для RE_RUB_MLN branch для consistency.

   Tests cover NBSP в obычной цене и в «4,4\xa0млн\xa0₽» форме.

После merge → deploy → следующий yandex sweep должен parse ~23/23 cards
с full addresses включая house number. Existing 217 houses с street-only
remain — пусть починятся через `backfill_house_coords.py` (precision
filter теперь сможет matchнуть exact).

Tests: 52/52 pass (yandex_realty_serp + yandex_helpers).
Ruff clean.
Light1YT merged commit aa70e9e155 into main 2026-05-27 07:23:36 +00:00
Light1YT deleted branch fix/yandex-realty-address-with-house-number 2026-05-27 07:23:36 +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#593
No description provided.