Open source · MIT

Prospector

Finds local businesses with no website, or one I can prove is broken.

  • Python
  • SQLite
  • Playwright
  • Google Places API
  • libphonenumber
  • OpenAI and Anthropic APIs
  • Go
  • HTML, CSS, JS
View on GitHub
Prospector, an open source tool that finds local businesses with a missing or broken website

The problem

I build websites for small local businesses: one person, small jobs, no agency. Finding the ones that actually need a site meant scrolling Google Maps and opening link after link on my phone, and most of what I found was fine.

I wanted a search that produced evidence. Not "this business might need a website", but "this site has no mobile layout, here is the check that proved it". If I tell someone their site is broken and it isn't, I have lost the job in one sentence.

What I built

An open-source tool that searches Google for local businesses, loads each website to check whether it is missing or genuinely broken, and drafts a short message quoting only what it verified. It runs entirely on my own machine: a Python command-line tool, a local web interface, and a double-click Mac launcher. SQLite stores every lead, so nothing is ever found, drafted or messaged twice.

One rule runs through all of it: a message may only mention something the tool checked itself.

How it works

  1. Find

    Pulls business listings from Google.

  2. Audit

    Loads each site normally and again in a phone-sized browser, scoring what is wrong: dead site, expired SSL, no mobile layout, http instead of https, very slow load, a parked "coming soon" page. No website at all is the strongest lead.

  3. Draft

    One AI call per business, given only the verified facts. Drafts are rejected automatically if they contain [placeholders] or agency-speak.

  4. Send

    A WhatsApp queue where each message is pre-typed and I send them by hand, one at a time. Nothing sends itself.

Decisions that mattered

Check before you claim

A valid certificate was once reported broken because Python's certificate list was older than the operating system's. A site behind Cloudflare blocked my checker while loading fine for real people. That case is now marked "inconclusive" rather than "broken". The audit is allowed to say it does not know.

One wrong number is a stranger's phone

An early run mangled Dubai numbers into malformed US ones. Now the country comes from the area being searched, every number is validated with Google's libphonenumber, and anything that fails is dropped instead of messaged. Landlines get flagged, since they aren't on WhatsApp.

Manual by design

Automated WhatsApp outreach gets numbers banned, and nobody wants a bot in their inbox. Sending stays a human click.

Testing

I ran a 10-round adversarial bug hunt with AI agents attacking the code, then re-verified every reported issue by hand, because a hunt that grades its own homework mostly produces confident noise. Twenty real findings survived and all twenty are fixed, including a cross-site scripting hole in the queue page, spreadsheet formula injection in exports, and a do-not-contact list that silently failed for phone numbers.

Screenshots

Screenshots use demo data. The businesses and phone numbers are fictional.

Free and MIT licensed. Use it yourself.

View on GitHub