Every reported drone and missile strike in the Russia-Ukraine war, day by day. Every figure is a claim, and each one names the outlet that made it. It reads a few dozen sources every morning and has run on its own server since launch.
Write-up
The problem
Strike reporting is scattered across dozens of outlets, in different languages, with different counting rules, and none of it stays findable a week later. There was no single place where a day's claims sat next to their sources: only aggregates with the sourcing stripped out.
What I built
A scraper that reads a few dozen sources every morning, a SQLite store keyed by day and claim, and a Leaflet map that walks the days. It runs under systemd on its own server and serves a public JSON API as well as the site. The core decision: never merge claims. Two outlets giving two figures for the same strike stay two rows, each with its byline. The map reports reporting, it does not adjudicate it.
What went wrong
[ Yours to write: the scraper that silently broke, the outlet that changed its markup, the dedup rule that was wrong for a month. This is the section an interviewer actually reads. ]
Result
Live and public at dronestrikemap.com, with the full dataset available through the open API. It updates itself every morning without being touched.
- Role
- Solo, everything
- Status
- live
- Stack
- Python, SQLite, systemd, Leaflet
- API
- /api/strikes