Elena Mashitskaya
Built outside workВне работы  /  My own projectСвой проект

A flat scanner that runs without me

Сканер квартир, который работает без меня

I was looking for a flat in Yerevan and got tired of going round five sites in three languages. So I wrote a scanner: it walks the listings every six hours and puts everything in one place.

Искала квартиру в Ереване и устала обходить пять сайтов на трёх языках. Написала сканер: он ходит по объявлениям каждые шесть часов и складывает всё в одно место.

Mine · idea, spec, backlog, codeМоё · идея, спека, бэклог, код Python · SQLite · launchd · MCP Running since · summer 2026Работает с · лета 2026

Open the flat finder ↗Открыть поиск квартиры ↗ demo on public listings, in Russian; my own filters removedдемо на публичных объявлениях, мой профиль поиска снят

4sites it walks, plus developers' own pagesсайта обходит, плюс страницы застройщиков
6 hчbetween runs, day and nightмежду прогонами, днём и ночью
9 000+listings in two databases: sale and rentобъявлений в двух базах: продажа и аренда
3storefronts, one navigation between themвитрины с общей навигацией
What it gives meЧто я с этого имею

Three pages instead of five tabs

Три страницы вместо пяти вкладок

buyкупитьnew buildsстройкиrentснять
BuyКупить Resale and new builds together, on a map, with a "−N% against the street" badge. Click a photo and you're in the listing.Вторичка и новостройки вместе, на карте, с бейджем «−N% к улице». Клик по фото — и ты в объявлении. the page I open firstстраница, которую открываю первой
buyкупитьnew buildsстройкиrentснять
New buildsСтройки Catalogues plus the developers' own sites. One of them going down doesn't take the others with it.Каталоги плюс сайты застройщиков. Если один упал, остальные собираются как ни в чём не бывало. updated once a dayобновляется раз в сутки
buyкупитьnew buildsстройкиrentснять
RentСнять The same streets, but rentals. It exists so the other pages can answer one question: is buying here better than renting?Те же улицы, только аренда. Нужна, чтобы другие страницы могли ответить на вопрос: покупать здесь выгоднее, чем снимать? feeds the yield tableкормит таблицу доходности
The interesting partСамое интересное

Decisions you only see from inside

Решения, которые видно только изнутри

Days on market counted from the ad's own date«Дней на рынке» считаю от даты объявления
The obvious way is to count from when my scanner first saw it. That number lies: sellers repost, and a flat hanging around for four months looks brand new. So I count from the date the site itself shows.Очевидный способ — считать с того момента, как сканер увидел лот впервые. Эта цифра врёт: продавцы перезаливают объявления, и квартира, которая висит четыре месяца, выглядит свежей. Поэтому считаю от даты, которую показывает сам сайт.
Buy or rent, street by street«Купить или снимать» по улицам
I have both databases for the same streets, which no portal does. So the page can say: on this street a flat pays for itself in 22 years, on that one in 32. That's an argument in a negotiation.У меня есть обе базы по одним улицам — такого нет ни у одного портала. Поэтому страница говорит: здесь квартира отбивается арендой за 22 года, а рядом за 32. Это аргумент в торге.
Better a listing too many than one missedЛучше лишний лот, чем пропущенный
The filters are deliberately loose. Ten minutes of scrolling past things that don't fit costs me less than never seeing the one flat that did.Фильтры специально нестрогие. Десять минут пролистывания неподходящего стоят меньше, чем одна не увиденная квартира, которая подходила.
A viewing checklist that lives on my phoneЧеклист просмотра, который живёт в телефоне
Water pressure, street noise, which way the sun goes, the paperwork. Ticks are saved in the browser, so I open it standing in the hallway.Напор воды, шум с улицы, куда ходит солнце, документы. Галочки сохраняются в браузере, так что открываю прямо в прихожей.
The search profile is a config fileПрофиль поиска лежит в конфиге
District, rooms, size, price ceiling, the street list. Changing my mind about any of it takes one file and no code.Район, комнаты, площадь, потолок цены, список улиц. Передумать по любому пункту — это один файл и ни строчки кода.
How it stays aliveКак это живёт

Nobody presses a button

Никто не нажимает кнопку

collectсобрать
Four sitesЧетыре сайтаpolitely, with pausesвежливо, с паузами
tidyпривести в порядок
One shapeОдин форматthree languages, two currenciesтри языка, две валюты
deduplicateсклеить
One flatОдна квартираthe same one on four sitesона же на четырёх сайтах
keepхранить
Price historyИстория ценso drops are visibleчтобы видеть снижения
showпоказать
Three pagesТри страницыrebuilt every runпересобираются каждый раз

A scheduled job wakes it every six hours and archives everything once a week. On top sits a small server, so I can ask Claude "what's new on my streets this week" without opening anything. And there are tests: a scraper that quietly returns nothing is worse than one that falls over loudly. The code is written with AI coding agents — the spec, the backlog and what counts as broken are mine.

Планировщик будит его каждые шесть часов и раз в неделю архивирует. Сверху маленький сервер, чтобы спросить у Клода «что нового на моих улицах за неделю» и вообще ничего не открывать. И есть тесты: парсер, который молча возвращает пустоту, хуже того, который громко падает. Код пишут AI-агенты — спека, бэклог и то, что считается поломкой, мои.

Limits I setГраницы

What I decided not to do

Чего я решила не делать

Not a mass scraperНе масс-скрейперOne search profile, one person. I'm not collecting the market and I'm not reselling anyone's data.Один профиль поиска, один человек. Я не собираю рынок и не перепродаю чужие данные.
No captchas, no loginsНикаких капч и логиновOnly what's open to anyone with a browser, taken slowly enough not to bother anybody.Только то, что открыто любому человеку с браузером, и медленно, чтобы никому не мешать.
Not the whole countryНе вся странаA few streets in one district. Widening it brings back exactly the scrolling I built this to avoid.Несколько улиц в одном районе. Расширишь — вернётся ровно то листание, ради избавления от которого всё затевалось.
Telegram alerts are parkedОповещения в телеграм запаркованыWritten down in the backlog and deliberately not built. Six hours is soon enough.Записаны в бэклоге и осознанно не сделаны. Шести часов достаточно.
What I take from itЧто я отсюда забираю

Same job, smaller scale

Та же работа, только меньше

A spec and a backlog, even for myselfСпека и бэклог даже для себяWritten down, prioritised, with what I'm deliberately not doing. It's the same document I'd write for a team.Записано, расставлено по приоритету, с пунктом «чего не делаем». Это ровно тот же документ, что я написала бы для команды.
Question the number before you show itСомневаться в цифре до того, как её показать"Days on market" was wrong in the obvious version. Nobody would have noticed, and I'd have negotiated off a lie.«Дней на рынке» в очевидном варианте врали. Никто бы не заметил, а я бы торговалась по вранью.
Park things on purposeПарковать осознанноAlerts aren't forgotten, they're declined for now, in writing. That's a different thing from a backlog nobody looks at.Оповещения не забыты, а отклонены на время, и это записано. Это совсем не то же самое, что бэклог, в который никто не смотрит.

The flat, I still haven't found. The scanner works.

Квартиру я пока не нашла. Сканер работает.

My actual budget and street list live in a config file and aren't shown here. The listings themselves are public. Nothing from work is involved: this one is entirely mine, evenings and weekends.

Мой настоящий бюджет и список улиц лежат в конфиге и здесь не показаны. Сами объявления — публичные. С работой это никак не связано: проект полностью мой, по вечерам и выходным.