Side project · Web automation

Melbourne Deal Finder

Every morning a GitHub Actions job starts headless Chromium with Playwright, scans homely.com.au for houses for sale in western Melbourne, and scores each one as a buyer. It flags new listings and publishes the results below. Nobody runs it by hand.

Python Playwright GitHub Actions Scheduled CI

Live results

Today's scan

The filters start at the criteria I'm buying with. Change them to explore everything the scan found.

Run a fresh scan ↗ Opens the scan job on GitHub. Click Run workflow there, wait about 3 minutes, then refresh this page. Only the repo owner can start it. Everyone else sees the 7am daily scan.
–
listings scanned
–
match the filters
–
new since last scan
–
last updated

Loading today's scan…

How it works

A scraper that keeps itself up to date

I built this for my own house hunt. It also shows the same skills I use at work: browser automation, resilient parsing, and pipelines that run without anyone watching them.

  1. 01 · 7am daily

    Scheduled run

    A cron-triggered GitHub Actions workflow installs Python and Playwright's Chromium on a fresh runner.

  2. 02 · Scrape

    Read the page data

    Instead of guessing at visible text, it reads the structured JSON that the site embeds in each search page.

  3. 03 · Score

    Score as a buyer

    It scores land, build, value and availability out of 100. It also estimates upfront cash, including VIC stamp duty and LMI.

  4. 04 · Publish

    Commit and serve

    The job commits a JSON feed back to the repo. This page reads it in your browser, so there's no server to maintain.

Resilience

When the site changed

Challenge: Domain and realestate.com.au block automated browsers before any content loads. Later, homely.com.au moved to a newer Next.js version and the original data source disappeared overnight.

What I did: I tested each portal with headless Chromium to find one that serves real data. I parse the embedded JSON rather than the rendered HTML. When the page format changed, I added a decoder for the new streamed format and kept the old path as well.

Outcome: When parsing fails, the scan shows a clear warning instead of crashing or quietly publishing an empty report. Bad upstream values, such as $1 prices or 34-hectare suburban blocks, are filtered out by sanity bounds.

Honest data

Known limits

The source has no build year and no independent valuation, so those parts of the score are neutral rather than guessed. Agent price text is often marketing copy, so the scanner extracts real dollar figures from it and falls back to the site's reference price. Treat the results as research, not advice, and check every listing at the source.

Need automation that keeps running?

I build Playwright suites, API tests and CI pipelines that teams can trust.