Project

Job Finder

A tool I built for my own job search. It checks the job boards twice a day, drops anything that isn't really in London or isn't relevant, and ranks what's left by how well it fits. It shows its reasoning rather than just a number.

Node.js / Express MySQL Adzuna & Reed APIs systemd timers Cloudflare Tunnel

The problem

"London" isn't London. Search a radius around the city and you get Watford and half of Surrey, because that's where the commuters live. Distance alone doesn't fix it. Twelve kilometres from Charing Cross already reaches Hertfordshire.

A keyword match isn't relevance. Search "coordinator" and you get wedding coordinators. Search "operations" and you get theatre lists. Nothing in the listing tells you whether it's worth opening.

How it works

Every twelve hours it queries the Adzuna and Reed APIs across nine search terms. Each advert then goes through three stages:

Adverts are deduplicated across boards, so a role listed twice appears once. Anything marked shortlisted or applied keeps that status through later sweeps.

The bit worth explaining

The obvious way to cut the commuter belt is to blacklist county names. Surrey, Hertfordshire, Middlesex. That's wrong, and quietly so.

Uxbridge and Harrow are still written "Middlesex". Richmond and Kingston are still written "Surrey". All four sit inside Greater London. A county blacklist drops real jobs in real boroughs and you'd never spot it, because you can't miss what you never saw.

So the rule runs the other way. A recognised London place always wins, and only a named town outside the boundary can reject an advert. "Watford, London" is thrown out. "Richmond, Surrey" is kept and labelled Richmond upon Thames. There's a test suite covering these cases.

Scoring

Title match is tiered, so "project coordinator" scores well above a bare "coordinator". On top of that it weighs salary, how recently the advert was posted, and keywords taken from the work I actually do.

It also subtracts. Senior posts and sales roles lose points. Hard blockers like security clearance take a heavy penalty. Every score carries its reasons, so a low rank can be checked rather than trusted.

Why build it

Job alerts already exist, but they optimise for volume. They want you opening emails. I wanted a short ranked list where anything below the line has an explanation attached, and I wanted to define "suitable" myself.

It deliberately doesn't scrape LinkedIn or Indeed. Both prohibit it, both block it, and a scraper breaks whenever they change their markup. The boards' own APIs give wider coverage and keep working.

Status

Running twice a day on a small cloud instance. The dashboard is private, since it shows my live job search, so it isn't linked here.

Back to portfolio