I have always seen web pages using captchas to do this, but I wonder if there are other methods...
There are other methods, for example:
(1) Record when the form was shown and when submitted, check that form has not been submitted too quickly.
(2) Honeypot: create a text field that is not visible. When submitted check that it is not filled, as a bot may fill all fields with values, but a human would not fill it.
(3) Generate a checkbox using client side JavaScript and tell humans they need to check it. A bot may not process JavaScript so may not be able to check it.
(4) To ensure that the form can only be submitted if the form was actually displayed (a bot may just post the submitted form values without requesting the form first), create and store a session token when the form is displayed and then check that it exists when submitted. Make sure that you delete the session token after it has been used to prevent reuse.
Here's some C# example code that combines (1) and (4).
//When form is displayed
Guid token = Guid.NewGuid();
Session["token_" + token.ToString()] = DateTime.Now;
hdnToken.Value = token.ToString();
//When form is submitted
string token = hdnToken.Value;
book valid = false;
If (Session["token_" + token] != null)
{
DateTime displayed = DateTime.Parse(Session["token_" + token]);
//form must not be submitted within 30 seconds
valid = displayed < DateTime.Now.AddSeconds(-30);
Session.Remove("token_" + token);
}