You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过点击行为识别机器人?方案可行性及代码实现

方案合理性分析

你的核心思路完全靠谱:人类的点击行为天生带有随机性,不可能维持机械级的时间间隔一致性——不管是极快的10ms还是匀速的2秒,这种精准重复都是机器人的典型特征。结合5分钟的时间窗口监控,能有效过滤掉偶然的一致点击,降低误判率。

可以补充两个优化点让检测更精准:

  • 给间隔一致性设置合理误差阈值:比如允许±50ms的波动,避免把偶尔手抖的正常用户误判(人类点击很难完全精准,但机器人会几乎分毫不差)
  • 结合点击频率阈值:比如1秒内点击超过6次直接触发验证,毕竟人类最快的点击速度也有生理极限
代码实现方案

基于你现有的代码,我们可以添加点击时间记录、间隔分析逻辑,直接集成到点击事件中:

首先在你的Activity/Fragment中定义全局变量:

// 存储最近的点击时间戳,只保留5分钟内的记录
private List<Long> clickTimestamps = new ArrayList<>();
// 5分钟对应的毫秒数:5*60*1000=300000
private static final long MONITOR_WINDOW = 300000;
// 间隔一致性的误差阈值(可根据测试调整)
private static final long CONSISTENCY_TOLERANCE = 50;
// 快速点击检测阈值:1秒内超过5次点击
private static final int FAST_CLICK_LIMIT = 5;
private static final long FAST_CLICK_WINDOW = 1000;

然后修改点击事件的逻辑:

frameLayoutBtn.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        v.startAnimation(animation);
        long currentTime = System.currentTimeMillis();
        
        // 清理5分钟外的旧记录,避免内存占用和无效检测
        Iterator<Long> iterator = clickTimestamps.iterator();
        while (iterator.hasNext()) {
            long oldTime = iterator.next();
            if (currentTime - oldTime > MONITOR_WINDOW) {
                iterator.remove();
            }
        }
        
        // 记录当前点击时间
        clickTimestamps.add(currentTime);
        
        // 先检测快速点击:短时间内高频点击
        if (clickTimestamps.size() >= FAST_CLICK_LIMIT) {
            long firstInFastWindow = clickTimestamps.get(clickTimestamps.size() - FAST_CLICK_LIMIT);
            if (currentTime - firstInFastWindow <= FAST_CLICK_WINDOW) {
                showReCaptcha();
                return; // 触发验证后暂停后续业务逻辑
            }
        }
        
        // 再检测间隔一致性:至少需要3次点击才能计算连续间隔
        if (clickTimestamps.size() >= 3) {
            boolean isRobotPattern = true;
            // 取前两次的间隔作为基准
            long baseInterval = clickTimestamps.get(1) - clickTimestamps.get(0);
            // 遍历后续所有间隔,检查是否和基准一致(在误差范围内)
            for (int i = 2; i < clickTimestamps.size(); i++) {
                long currentInterval = clickTimestamps.get(i) - clickTimestamps.get(i-1);
                if (Math.abs(currentInterval - baseInterval) > CONSISTENCY_TOLERANCE) {
                    isRobotPattern = false;
                    break;
                }
            }
            if (isRobotPattern) {
                showReCaptcha();
                return;
            }
        }
        
        // 原有业务逻辑保持不变
        ClickCounter++;
        catStr = getCatTextFromDatabase(ClickCounter);
        if (ClickCounter > 1000) {
            CountText.setText("Count:" + ClickCounter);
        }
        if (catStr != null && !catStr.isEmpty()) {
            CatText.setText(catStr);
        }
    }

    private String getCatTextFromDatabase(long counter) {
        DatabaseHelper dbHelper = new DatabaseHelper(getApplicationContext());
        return dbHelper.getTextForCounter(counter);
    }
});

最后添加ReCaptcha的展示方法(替换成你实际的ReCaptcha集成逻辑):

private void showReCaptcha() {
    // 这里实现人机验证的展示逻辑,比如启动ReCaptcha验证界面
    // 示例提示:
    Toast.makeText(getApplicationContext(), "请完成人机验证", Toast.LENGTH_LONG).show();
    // 验证通过后,清空点击记录,恢复正常操作
    clickTimestamps.clear();
}
额外注意事项
  • 性能优化:如果你的应用有大量高频点击用户,清理旧记录的循环可以放到子线程(不过5分钟内的点击次数有限,一般不会有性能问题)
  • 持久化记录:如果要防止用户重启应用绕过检测,可以把点击记录暂存到SharedPreferences中,重启后恢复
  • 阈值调优:根据你的目标用户群体测试调整CONSISTENCY_TOLERANCE和FAST_CLICK_LIMIT,比如老年用户的点击间隔波动更大,阈值可以设宽一点

内容的提问来源于stack exchange,提问作者Vasant Raval

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 10:17:09