feat(tradein): yandex_newbuilding.py — ЖК landing parser (149 selectors + NLP) #467
No reviewers
Labels
No labels
admin
analytics
auth
automation
bug
business
chore
ci
compliance
data
data-moat
docs
duplicate
dx
enhancement
Fable 5 ревью
feedback/max
generative
GG-форсайт
needs-discussion
needs-human
observability
pause-bots
performance
priority/p0
priority/p1
priority/p2
priority/p3
scope/backend
scope/db
scope/devops
scope/frontend
scope/qa
scrapers
security
site-finder
stage/1
stage/2
status/blocked
status/done
status/needs-analysis
status/needs-fix
status/qa
status/ready
status/review
status/wip
tech-debt
tradein
ux
week ревью 1
wontfix
вторичка
ИРД
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: lekss361/gendesign#467
Loading…
Add table
Reference in a new issue
No description provided.
Delete branch "feat/tradein-yandex-newbuilding-parser"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Motivation
Stage 5 of 9 for YandexRealtyScraper v1 (Wave 4 / Worker B — parallel with
yandex_detail.pyandyandex_valuation.py).ЖК landing pages are the richest Yandex data source — comparable to or richer than Avito Houses Catalog. Reference target: ЖК Татлин (slug=
tatlin, id=1592987) — class comfort+, June 2023, PRINZIP developer, rating 4.3, 1505 ratings, 353 text reviews, coords (56.855312, 60.576668).Module
tradein-mvp/backend/app/services/scrapers/yandex_newbuilding.py—YandexNewbuildingScraper(BaseScraper)with asyncfetch_jk(slug, id, city="ekaterinburg").URL pattern:
/{city}/kupit/novostrojka/<slug>-<id>/YandexNewbuildingInfo fields
ext_id,ext_slug,source_url,name,addresslat,lon(city-range filtered)house_class(comfort_plusetc.),commission_year,commission_month(RU)total_floors,corpus_count(word→int "три"→3),total_area_hadeveloper_name,developer_url,developer_other_jk[]rating,ratings_count,text_reviews_count(the 353!)description(full text),metro_stations[],house_type(NLP fallback)Coord extraction
Inline scan of full HTML for any
\d{2}\.\d{4,8}matching plausible city range:NLP regex constants
RE_FLOORS_TOWERS— "35-этажные башни"RE_AREA_HA— "участке 1,5 га"RE_COMMISSION— "введён в эксплуатацию в июне 2023"RE_CORPUS_COUNT_WORD— handles word ("три" → 3) and digit formsRE_RATING/RE_RATINGS_COUNT/RE_TEXT_REVIEWSRE_METRO_INLINE— "Уральская 11 мин"Plus delegation to
parse_house_class/parse_house_typefromyandex_helpers.Tests
Files
tradein-mvp/backend/app/services/scrapers/yandex_newbuilding.py(new, 352 lines)tradein-mvp/backend/tests/test_yandex_newbuilding.py(new, 422 lines)Reviewer note
Reviewer: deep-code-reviewer — only merge after APPROVE. Wave 4 sibling PRs: yandex_detail.py + yandex_valuation.py.
Stage 5 of YandexRealtyScraper v1 (Wave 4 / Worker B — parallel with yandex_detail.py and yandex_valuation.py). Module: app/services/scrapers/yandex_newbuilding.py - YandexNewbuildingScraper(BaseScraper) — fetch_jk(slug, id, city) URL: /{city}/kupit/novostrojka/<slug>-<id>/ - YandexNewbuildingInfo Pydantic model (ext_id/slug, name, address, lat/lon, house_class, commission_year/month, total_floors, corpus_count, total_area_ha, developer_name/url + other_jk, rating + ratings_count + text_reviews_count, description, metro_stations, house_type) - Inline coord extraction (Yandex unique: lat/lon visible in raw HTML within city range filter) - NLP regex: floors-towers, area-ha, commission date, corpus count (word→int), rating + counts, metro inline - Helpers: _find_section_text (h2/h3 → next siblings), _parse_corpus_count (word/digit), _parse_metro, _extract_jk_address Tests: 28 unit tests against Татлин-like fixture HTML. All pass. Ruff clean.Deep Code Review — verdict APPROVE (merged)
Status: APPROVE
Files reviewed: 2 (P1: scraper, P3: tests)
LOC: +774/-0
Merge commit:
51650276b2a8613760118f633bef193df678ebf8Cross-file impact
parse_house_class,parse_house_type,RE_JK_ID— confirmed exports inyandex_helpers.py(re-uses Stage 3 helpers PR #456 pattern). OK.BaseScraper._http_get/sleep_between_requests/ abstractfetch_around— used identically to existingyandex_realty.py:64(caller responsible forasync withcontext).Critical focus areas — all satisfied
test_parse_rating_and_countsassertsinfo.text_reviews_count == 353on Татлин fixture ✅developer_other_jk[]capped at 10 + deduptest_developer_other_jk_capped_at_10+test_developer_other_jk_dedupcorpus_countword→int_WORD_NUMcovers одна/одну/одной/две/три/четыре/пять/шесть/семь/восемь + digit branchcommission_monthRUtextcolumnMinor improvements (non-blocking, future PR)
_extract_coordsindependently picks first lat-in-range and first lon-in-range. If page has a stray decimal56.xxxxBEFORE the real coords block, parser could return mismatched lat without paired lon (or vice-versa: Moscow lat 55.7558 falls in EKB LAT_RANGE —test_extract_coords_outside_range_returns_noneonly assertslon is None, lat in that case = 55.7558 ≠ EKB). Recommend post-merge: require lat and lon within ~50 chars of each other in HTML (similar to fixture"56.855312, 60.576668").RE_CORPUS_COUNT_WORDmissingдевять/десять— edge case, low priority.Positive observations
Field(default_factory=list),Nonefor optionals)fetch_aroundraises NotImplementedError explaining JK-slug pattern (correct delegation to fetch_jk)href.startswith("http"))developer_other_jk[:10]cap prevents unbounded list growthVault cross-check
decisions/YandexRealtyScraper_v1_Implementation_Plan.mdStage 5 scope match 100%decisions/Schema_YandexRealty_Recon.mdsec 17-26 — confirms inline coords + 149 markers + 353 reviews targetcode/modules/tradein/Yandex_Newbuilding_Parser.mdper CLAUDE.md rule #6Blast radius
Merged via deep-code-reviewer.