A small proof-of-work
The widget asks the browser to find a nonce whose SHA-256 hash has a set number of leading zero bits. For a real visitor that costs a fraction of a second; run at the scale a bot needs, it costs real CPU and real money. The difficulty is yours to tune.