Files
maru-hleda-byt/CLAUDE.md
Marie Michalova 59ef3274b6 Add CLAUDE.md project documentation for session context
Provides automatic context loading for new Claude Code sessions,
documenting architecture, filters, sources, and conventions.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 09:58:01 +01:00

4.7 KiB

Maru hledá byt

Projekt pro hledání bytů v Praze. Scrapuje inzeráty ze 7 realitních portálů, filtruje, deduplikuje a generuje interaktivní mapu.

Jazyk komunikace: Čeština (uživatelka Marie). Kód a komentáře v kódu jsou mix CZ/EN.

Architektura

run_all.sh (orchestrátor)
  ├─ scrape_and_map.py      → byty_sreality.json     (Sreality API)
  ├─ scrape_bezrealitky.py  → byty_bezrealitky.json  (HTML Apollo cache)
  ├─ scrape_idnes.py        → byty_idnes.json        (HTML regex)
  ├─ scrape_psn.py }        → byty_psn.json          (React API + curl)
  ├─ scrape_cityhome.py }   → byty_cityhome.json     (HTML tabulky)
  ├─ scrape_bazos.py        → byty_bazos.json        (HTML regex)
  └─ scrape_realingo.py     → byty_realingo.json     (Next.js __NEXT_DATA__)
      ↓
  merge_and_map.py
      ├─ byty_merged.json (deduplikovaná data)
      └─ mapa_bytu.html   (Leaflet.js mapa)
      ↓
  generate_status.py → status.json + scraper_history.json
      ↓
  server.py (port 8080) → servíruje mapu + status page + ratings API

Filtry (společné všem scraperům)

Parametr Hodnota Poznámka
Max cena 13.5M Kč (Sreality/Realingo/Bezrealitky/iDNES), 14M Kč (PSN/CityHome/Bazoš) Rozdíl je záměrný
Min plocha 69 m²
Min patro 2. NP 2. NP se na mapě označí varováním
Dispozice 3+kk, 3+1, 4+kk, 4+1, 5+kk, 5+1, 6+
Region Praha
Vyloučit panelové domy, sídliště regex v popisu/polích

Klíčové soubory

  • scrape_and_map.py — Sreality scraper + generate_map() funkce (sdílená, generuje HTML mapu)
  • merge_and_map.py — sloučí 7 JSON zdrojů, deduplikuje (klíč: ulice + cena + plocha), volá generate_map()
  • scraper_stats.py — utility: validate_listing() (validace povinných polí + GPS bounds) a write_stats()
  • generate_status.py — generuje status.json a scraper_history.json z výstupů scraperů
  • server.py — HTTP server (port 8080), endpointy: /mapa_bytu.html, /scrapers-status, /api/ratings, /api/status
  • run_all.sh — orchestrátor, spouští scrapery postupně (PSN+CityHome paralelně), pak merge + status

Mapa (mapa_bytu.html)

  • Leaflet.js + CARTO tiles
  • Barvy markerů podle ceny/m² (modrá < 110k → červená > 165k, šedá = neuvedeno)
  • PSN/CityHome = srdíčkové markery (❤️)
  • Nové inzeráty (≤ 1 den) = žlutý badge "NEW"
  • Zamítnuté = zprůhledněné + 🚫 SVG overlay
  • Oblíbené = hvězdička ()
  • Filtry: patro, max cena (input, default 13.5M, max 14M), datum přidání, skrýt zamítnuté, klik na cenový pás
  • Ratings uložené v localStorage + sync na server /api/ratings

Barvy zdrojů na mapě

source_colors = {
    "sreality": "#1976D2",    # modrá
    "realingo": "#00897B",    # teal
    "bezrealitky": "#E91E63", # růžová
    "idnes": "#FF6F00",       # oranžová
    "psn": "#D32F2F",         # červená
    "cityhome": "#D32F2F",    # červená
    "bazos": "#7B1FA2",       # fialová
}

Deduplikace (merge_and_map.py)

  • Klíč: normalize_street(locality) + price + area
  • Normalizace ulice: první část před čárkou, lowercase, odstranění diakritiky, jen alfanumerické znaky
  • PSN a CityHome mají prioritu (načtou se první)

Vývoj

  • Git remote: https://gitea.home.hrajfrisbee.cz/littlemeat/maru-hleda-byt.git
  • Gitea API token: uložen v .claude/settings.local.json
  • Python 3.9+ kompatibilita (from __future__ import annotations)
  • Žádné pip závislosti — jen stdlib (urllib, json, re, logging, pathlib, subprocess)
  • Docker: build/Dockerfile (python:3.13-alpine), cron každé 4 hodiny
  • Generované soubory (byty_*.json, mapa_bytu.html, *.log) jsou v .gitignore

Typické úlohy

# Rychlý test scraperu
python3 scrape_bazos.py --max-pages 1 --max-properties 5 --log-level DEBUG

# Lokální validace (všechny scrapery s limity)
make validation-local

# Vygenerovat mapu z existujících dat
python3 merge_and_map.py

# Spustit server
python3 server.py  # nebo: make serve

# Plný scrape
./run_all.sh

Pořadí scraperů v run_all.sh

  1. Sreality
  2. Bezrealitky
  3. iDNES
  4. PSN + CityHome (paralelně)
  5. Bazoš
  6. Realingo (poslední — uživatelka ho nemá ráda)
  7. Merge + mapa
  8. Status generování

Konvence

  • Commit messages v angličtině, PR popis v angličtině
  • Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com
  • PRy přes Gitea API (viz create_pr.sh pattern v historii)
  • Nové scrapery kopírují vzor z scrape_bezrealitky.py
  • Každý scraper má argparse s --max-pages, --max-properties, --log-level