网站访问统计,别急着把机器人或内部访问全部过滤掉

📍 WDQWDWQD987AAAAA:216.73.217.153
📱 Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; ClaudeBot/1.0; +claudebot@anthropic.com)
🔗 /46190c2734b2.html
📄

网站访问统计,别急着把机器人或内部访问全部过滤掉

处理机器人或内部访问干扰,正确顺序是先识别、再分层标记、最后才决定是否从报表中剔除。直接屏蔽所有可疑流量,往往会把监控探针、预渲染请求和同事的测试访问一起删掉,导致页面异常无人发现、真实用户行为被误判。更稳妥的做法是:保留原始日志,在统计口径上增加“真人外部访问”这一层,让过滤可回溯、可调整。

先分清三类流量,别用一个开关处理

站内统计里出现的非目标访问,通常混着三种性质完全不同的东西,处理方式也不一样。

常见误解是“只要把机器人过滤掉,报表就干净了”。实际上,过滤规则本身会误伤:某些浏览器插件、隐私代理、企业网关的请求特征和机器人高度相似。一旦误判,你会看到某个地区或某个渠道的转化突然归零,却找不到原因。

用可核查的证据链做判断,而不是凭感觉拉黑

识别阶段建议按下面顺序收集证据,每一步都能留下记录,便于多人协作时交接。

  1. 在原始日志中保留完整User-Agent、IP、请求路径、状态码和响应时间,不要只存聚合后的报表数字。
  2. 对可疑IP做反向DNS查询,看是否指向已知搜索引擎或云服务商;正向再解析一次,确认前后一致。
  3. 观察行为特征:真实用户的请求间隔、页面路径、鼠标或滚动事件通常有随机性;固定间隔、只请求接口、不加载静态资源的,机器人概率更高。
  4. 把内部访问单独打标,例如在测试账号的请求头里加一个自定义标识,或在监控探针上固定来源IP段。

这里要区分“可能原因”和“已经定位的原因”。某段IP流量异常,可能是机器人,也可能是公司出口网关或某个合作方接口,只有完成反向解析和行为比对后才能下结论。不要因为一个现象就断言唯一原因。

过滤要分层,并且保留可回滚的原始数据

推荐把统计口径拆成三层,而不是一个总数:

这样做的价值在于:当报表数字和预期差距很大时,可以逐层回看,判断是过滤规则太严,还是真的有流量变化。多人协作时,规则变更要写清生效时间、影响范围和回滚方式,避免不同同事看到的口径不一致。

具体操作上,可以在统计脚本里加一个判断函数,伪代码如下(仅为示例,需按实际环境调整):

if (isInternalIp(ip) || isVerifiedBot(ua, ip)) { track('filtered', {reason: 'internal_or_bot'}); } else { track('pageview'); }

注意这里的关键是“先记录再分类”,而不是“先拦截再记录”。如果一开始就丢弃,后面就无法验证规则是否误伤。

内部访问不必全删,改成单独看

内部访问对业务报表是干扰,对运维和发布验证却是必要信号。更合理的处理是:

适用条件是:团队有基本的日志留存和标签能力。如果暂时做不到分层,至少先做到“不删除原始日志”,只在导出报表时用筛选条件排除已知的内部IP段和已验证的搜索引擎IP。判断结果是否可信,看两点:排除后核心页面的访问趋势是否仍然连续;被排除的流量里是否包含真实用户的典型路径。

下一步:先定义口径,再改规则

在动手过滤之前,先和协作方确认一件事:这份网站访问统计要回答什么问题。是看内容受欢迎程度,还是看服务器负载,还是看转化路径?目标不同,机器人或内部访问该不该排除、排除到什么程度也不同。把口径写进交接文档,再按上面的分层方式调整规则,比直接拉黑一堆IP更不容易返工。

图1 图2

nginx