I ran into a great post on the PHP devnetwork forums here talking about some tactics to protect your forms without using Captcha.
First is the Honeypot method. The idea is to add a field to the form that bots would likely fill out but that is a hidden element on the form that should remain blank. twindev explains:
Honeypot – This generally stops bots that go to your site auto submit the form. Add a field, called something like URL (something they would really want to fill in), style it so that it is not visible on the screen. Make sure for accessibility, you add a label that says that the field should be left blank. Then on the code that processes the form, if this field doesn’t exist or it does but it isn’t blank, don’t accept the form submission
The second method that twindev suggests is Timeout. It gives forms an encrypted timestamp that requires the form be requested anew and submitted within a certain period of time. twindev describes it:
Time out – If someone writes a bot to just flat out POST to your site, add a field in the form that is the current timestamp. Then when the form is submitted, only accept it if it is within a certain period of time (say, an hour). The direct posting of data will only work for that much time. Now someone looking may recognize the timestamp, so use a simple function to convert it to something very difficult, and then once submitted, convert it back to a number. (See this post of mine for my functions to do this)
It also occurred to me that checking that the timestamp is a little bit old would prevent bots from rapid-fire spamming. For example, require that the post be submitted at least 20 seconds after being rendered. A person would take that long to complete the form, but a bot would have to wait.