可通过Nginx的map模块精准识别主流搜索引擎蜘蛛UA,结合limit_req实现分层限流:合法蜘蛛宽松限速(如5r/s),普通用户严格限制(2r/s),恶意爬虫极低速率(0.1r/s)或封禁,兼顾抓取友好性与防护强度。

不能直接给爬虫“不限速”的特权,但可以实现对合法搜索引擎蜘蛛完全绕过限流规则,而其他所有流量(包括恶意爬虫、普通用户、脚本)仍受正常速率限制。关键在于用 map 提前识别 UA,再让 limit_req 跳过已标记的合法蜘蛛。
用 map 精准识别主流搜索引擎蜘蛛
在 http 块顶部统一定义识别逻辑,避免分散在多个 location 中:
map $http_user_agent $is_search_engine {
default 0;
~*Googlebot 1;
~*Baiduspider 1;
~*bingbot 1;
~*YandexBot 1;
~*DuckDuckBot 1;
~*Applebot 1;
}
注意:正则匹配区分大小写,加 ~* 表示忽略大小写;规则按书写顺序生效,更具体的 UA(如 Googlebot/2.1)应放在泛化规则(如 ~*curl)之前。
配置限流区域时排除合法蜘蛛
limit_req_zone 的 key 必须能区分“要限”和“不限”的请求。最稳妥的方式是:只对非搜索引擎的请求启用限流:
limit_req_zone $binary_remote_addr$is_search_engine zone=api_limit:10m rate=10r/s;
这个技巧的核心是:当 $is_search_engine = 1 时,key 变成 "$ip1";当为 0 时,key 是 "$ip0"。我们只需让 rate=10r/s 仅作用于 "$ip0" 这类 key,而 "$ip1" 因从未被触发限流逻辑,自然不受约束。
更清晰的做法是显式跳过:
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;
server {
location /api/ {
# 合法蜘蛛不走限流
if ($is_search_engine) {
break;
}
limit_req zone=api_limit burst=20 nodelay;
proxy_pass http://backend;
}
}
</font><p><strong>不推荐用 if + return,但 if + break 是安全的</strong>——它只是跳过后续指令,不会引发重写循环或变量覆盖问题。</p><H3>按 UA 类型分层应用策略(推荐)</H3><p>真正健壮的方案不是“全放行”,而是<strong>对合法蜘蛛给宽松但有底限的速率,对普通用户严格限流,对恶意 UA 极度压制</strong>:</p><font color="gray"><pre class="brush:php;toolbar:false;">
# 区分三类流量
map $http_user_agent $spider_class {
default 0; # 普通用户
~*Googlebot 1; # 合法蜘蛛
~*Baiduspider 1;
~*AhrefsBot 2; # 恶意/低价值爬虫
~*SemrushBot 2;
}
<h1>三档限速区</h1><p>limit_req_zone $binary_remote_addr$spider_class zone=legit:10m rate=5r/s; # 合法蜘蛛:5r/s
limit_req_zone $binary_remote_addr zone=user:10m rate=2r/s; # 普通用户:2r/s
limit_req_zone $binary_remote_addr$spider_class zone=bad:10m rate=0.1r/s; # 恶意:0.1r/s ≈ 封禁</p><p>location / {</p><h1>优先匹配合法蜘蛛</h1><pre class='brush:php;toolbar:false;'>if ($spider_class = 1) {
limit_req zone=legit burst=15 nodelay;
break;
}
# 再匹配恶意
if ($spider_class = 2) {
limit_req zone=bad burst=1;
break;
}
# 默认走用户限流
limit_req zone=user burst=5;}
这样既保障 Googlebot 等稳定抓取,又防止它被滥用,还让 AhrefsBot 这类工具几乎无法持续工作。
验证与调试要点
- 用 curl 模拟不同 UA 测试:
curl -H "User-Agent: Googlebot/2.1" http://yoursite/api/test - 检查 Nginx error log 是否出现
limiting requests日志,合法蜘蛛请求不应出现 - 用
nginx -t确保 map 和 limit_req_zone 语法正确,避免 reload 失败 - 注意:$http_user_agent 可被伪造,该方案依赖 UA 本身可信;高安全场景需结合 IP 反查(如 Googlebot 官方 IP 段)做二次校验


















