Są dwa podejścia "na szybko":
Pierwsze to JS, który jest pracochłonny. To co ma robić jest zupełnie dowolne :) może np. faktoryzować liczbę pierwszą. Zadanie ma być na tyle obciążające, żeby zniechęcić boty i na tyle proste, żeby użytkownik tego nie zauważył. Były takie pomysły, żeby w czasie weryfikacji kopać bitcoiny, ale nie wiem gdzie te projekty zaszły :)
Drugie to oszustwo. Zmieniasz input name z "email" na coś innego np. "gruzobeton". Dodajesz drugiego inputa "oszusta" o nazwie email i dajesz mu display: none. Przed submitem przy pomocy JSa usuwasz pole email z DOM, a w backendzie robisz tak, że jak przyjdzie request z polem email to odrzuca jako spam. Boty się na to łapią jak głupie :)