Можно обойти любую фильтрацию, но есть некоторые признаки, которые могут отсеять явных ботов
1. переменные окружения — почему-то ленятся скопировать результат запроса типичного браузера
2. скорость клика — боты либо быстрые, либо регулярные. Делаете порог для html запросов в минуту или считаете вариативность задержек между запросами.
3. скачивание/нескачивание контента — обычный браузер качает картинки, css и прочее, но тут есть тонкости — например некоторые браузеры стали оптимизировать и не запрашивают невидимый контент. Но явно нужный css например хороший триггер для человека
4. Прокликивание ссылок — делаете ссылку со страницы, которую пользователь не может нажать и готовый триггер для бота. Для надежности делаете рандомные место, класс и параметры ссылки
5. Javascript — большинство ботов его не выполняет, но есть и пользователи без него. Делаете по загрузке страницы запрос на css, например, что будет условным триггером для человека.
В общем делаете фильтр, который проверяет кучу признаков и по сумме решает что это бот — дальше либо в сессии, если есть такие, выдаете ему всякую фигнгю, либо рубите. Если нет сессий, то создавайте правило в iptables/pf/ipfw что у вас там для данного ip на час-два-сутки.
Надо сказать пару слов о нужных ботах — спайдеров поисковых машин, можно предварительно отфильтровать ip адреса по user-agent, но есть вероятность что под них маскируются ненужные боты. Так что их надо модерировать, прежде чем заносить в белый список.