GA4会自动排除一部分已知的机器人和蜘蛛流量,但它无法识别所有自动化访问,所以仍然会有机器流量进入到GA4。
如果有明显的特征,可以考虑在GTM、Nginx 里过滤。
如果没有可用的特征,可以考虑引入第三方风控服务,比如reCAPTCHA v3。
reCAPTCHA v3是什么?
很多人提到reCAPTCHA,首先想到的是「我不是机器人」复选框或图片验证。
reCAPTCHA v3的工作方式不同。它不会默认打断用户,也不会要求用户点击图片,而是根据访问环境和行为返回一个0到1的风险分数:
- 1.0 → 更像正常用户
- 0.0 → 更像可疑或自动化流量
| 分数 |
初步处理 |
0.7–1.0 |
暂时正常放行 |
0.3–0.7 |
记录并观察 |
< 0.3 |
标记为可疑,结合其他特征判断 |
Google也说明,分数需要根据网站自己的流量进行观察和调整,默认的0.5只能作为起始参考,不能视为通用标准。
reCAPTCHA v3识别机器流量的工作流程
完整流程如下:
- 访客打开网页
- GTM无感加载reCAPTCHA v3
- 浏览器取得临时Token
- Token发送到Cloudflare Worker
- Worker使用Secret Key 请求 Google 验证
- Google返回success、score、action、hostname
- Worker将结果返回给浏览器
- GTM将结果通过 dataLayer发送
- GA4记录并分析
可以看到整个流程是很长,耗时较长,如果用户在响应完成前离开页面,很容易导致追踪数据丢失。
为解决这个问题,我选择Cloudflare Workers作为服务端。它依托遍布全球的CDN节点,能将请求就近调度,大幅缩短网络耗时。同时,这套代码具备良好的可移植性,你也可以将其部署到自有服务器上,兼顾边缘加速与私有化需求。
步骤一:创建reCAPTCHA Key
在reCAPTCHA后台创建一个reCAPTCHA,选择reCaptcha v3:

创建后你会获得两个秘钥:

两者的部署位置不同:
| Key |
部署位置 |
用途 |
| Site Key |
网页或 GTM |
调用 reCAPTCHA v3 |
| Secret Key |
Cloudflare Worker |
向 Google 验证 Token |
步骤二:使用Cloudflare Worker验证Token
在Cloudflare Dashboard中创建 Worker,进入Edit code,粘贴以下代码:
const ALLOWED_ORIGIN = "https://www.ichdata.com"; //域名要换成你自己的
function corsHeaders() {
return {
"Access-Control-Allow-Origin": ALLOWED_ORIGIN,
"Access-Control-Allow-Methods": "POST, OPTIONS",
"Access-Control-Allow-Headers": "Content-Type",
"Content-Type": "application/json; charset=UTF-8",
"Cache-Control": "no-store"
};
}
function send(data, status) {
return new Response(JSON.stringify(data), {
status,
headers: corsHeaders()
});
}
export default {
async fetch(request, env) {
if (request.method === "OPTIONS") {
return new Response(null, {
status: 204,
headers: corsHeaders()
});
}
if (request.method !== "POST") {
return send({
success: false,
error: "method_not_allowed"
}, 405);
}
try {
const body = await request.json();
const token = body.token;
if (!token) {
return send({
success: false,
error: "token_missing"
}, 400);
}
const googleResponse = await fetch(
"https://www.google.com/recaptcha/api/siteverify",
{
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded"
},
body: new URLSearchParams({
secret: env.RECAPTCHA_SECRET,
response: token
})
}
);
const result = await googleResponse.json();
const valid =
result.success === true &&
result.action === "visitor_check" &&
(
result.hostname === "www.ichdata.com" ||
result.hostname === "ichdata.com"
);
return send({
success: valid,
score: result.score ?? null,
action: result.action ?? null,
hostname: result.hostname ?? null,
google_errors: result["error-codes"] ?? []
}, 200);
} catch (error) {
console.error("Worker error:", error);
return send({
success: false,
error: "worker_exception"
}, 500);
}
}
};
复制上一步创建的Secret Key,在Cloudflare Worker 里点击「设置」——「添加变量」,做如下设置:

不要把Secret Key写进Worker源码。Cloudflare官方也建议使用Secret变量保存密码、API Key和其他敏感信息。
Worker源码中是env.RECAPTCHA_SECRET,就是读入RECAPTCHA_SECRET密钥。
创建好Worker后,会有一个Worker 地址为
https://ichdata-recaptcha.haran-huang.workers.dev
GTM要请求的完整接口地址是:
https://ichdata-recaptcha.haran-huang.workers.dev/recaptcha-visitor
步骤三:在GTM中调用reCAPTCHA v3
在GTM里新建一个自定义 HTML,复制黏贴如下示例代码,触发器选择Initialization – All Pages,确保尽快加载。
<script>
(function () {
var siteKey = '******'; // 改用你实际的
var verifyEndpoint =
'https://ichdata-recaptcha.haran-huang.workers.dev/recaptcha-visitor'; // 改用你实际的
function loadRecaptcha(callback) {
if (window.grecaptcha) {
callback();
return;
}
var script = document.createElement('script');
script.src =
'https://www.google.com/recaptcha/api.js?render=' +
encodeURIComponent(siteKey);
script.async = true;
script.onload = callback;
document.head.appendChild(script);
}
loadRecaptcha(function () {
grecaptcha.ready(function () {
grecaptcha.execute(siteKey, {
action: 'visitor_check'
}).then(function (token) {
fetch(verifyEndpoint, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
token: token,
page: location.href,
path: location.pathname
})
})
.then(function (response) {
console.log('Worker status:', response.status);
return response.text();
})
.then(function (text) {
console.log(
'Worker raw response:',
JSON.stringify(text)
);
if (!text) {
console.error('Worker returned an empty response');
return;
}
var data;
try {
data = JSON.parse(text);
} catch (error) {
console.error(
'Worker response is not valid JSON:',
error
);
return;
}
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
event: 'recaptcha_verified',
recaptcha_success: data.success === true,
recaptcha_score: data.score,
recaptcha_action: data.action,
recaptcha_hostname: data.hostname,
recaptcha_risk:
data.score !== null &&
data.score < 0.3
? 'high'
: 'normal',
recaptcha_page: location.href,
recaptcha_path: location.pathname
});
console.log(
'reCAPTCHA dataLayer event pushed:',
data
);
})
.catch(function (error) {
console.error(
'Worker request failed:',
error
);
});
});
});
});
})();
</script>
需要注意:示例代码里的siteKey和verifyEndpoint要替换成你自己的。
代码里的:
window.dataLayer.push({
event: 'recaptcha_verified',
recaptcha_success: data.success === true,
recaptcha_score: data.score,
recaptcha_action: data.action,
recaptcha_hostname: data.hostname,
recaptcha_risk:
data.score !== null &&
data.score < 0.3
? 'high'
: 'normal',
recaptcha_page: location.href,
recaptcha_path: location.pathname
});
就是从reCAPTCHA获取的信息发送到dataLayer。
步骤四:验证reCAPTCHA信息
在GTM里点击预览:

可以看到:reCAPTCHA信息都在recaptcha_verified事件里。
recaptcha_verified通常晚于page_view发送:
- 如果你明确愿意接受页面浏览延迟和部分数据缺失,那么可以用recaptcha_verified事件作为页面跟踪的触发器(还可以用recaptcha_scorec的数值排除机器流量,比如分数小于 0.3 的时候,认为机器流量, GA4不跟踪,在recaptcha_verified里的触发条件做限制,recaptcha_scorec大于等于0.3的才触发)
- 如果你不能接受,那么将recaptcha_verified作为单独的事件去跟踪,后面在GA4里新建用户级别或会话级别的细分,看报告的时候使用该细分,将机器流量排除。
步骤五:发送数据到GA4
我这里采用recaptcha_verified事件作为页面跟踪的触发器的方式去跟踪。
在GTM中新建一个数据层变量,命名为recaptcha_score,值是recaptcha_score(其他dataLayer里的信息类似设置),将它设置为 GA4页面跟踪的事件参数,同时在GA4里将它设置为自定义指标。
在GTM中新建一个自定义事件,命名为recaptcha_verified,值是recaptcha_verified,然后将 GA4 页面跟踪的触发条件替换为recaptcha_verified。
步骤六: GTM里预览调试
GTM里预览调试,可以看到事件参数recaptcha_score是 0.9:

page_load_time是3.05秒,影响甚微(如果对你的页面加载速度很大,那就将recaptcha_verified作为单独的事件去跟踪)。
还可以在GA4的实时报表里看上一步所创建的自定义指标:

总结
GA4的已知机器人排除机制只能覆盖Google能识别的部分流量。reCAPTCHA v3可以为浏览器访问返回风险分数,帮助你把GA4中的会话做风险标记。
建议先把reCAPTCHA分数作为辅助信号,结合其他维度帮助定位机器流量。
有疑问可以在底部留言