The entity doing the request is the one who identifies itself as either a “normal” user or a bot. It’s a honor based system, with all ups and downs from that.
Most bad actors in the bot ecosystem won’t identify as such and will issue requests disguised as “normal” users, and there is not much Discourse can do in those cases.
If you are comfortable with the command line you long into your server and use the following to track where most requests are coming from:
cd /var/discourse/shared/standalone/log/var-log/nginx/
grep " 200 " access.log | awk '{print $4}' | sort | uniq -c | sort -r