应使用 Nginx map 预判 UA 类型并配合 limit_req_zone 限速,而非 if+return 或防火墙一刀切;需在 server 块顶部定义 map 和 zone,在 location 中直接调用 limit_req,搭配 burst=5 nodelay 实现平滑控流。

用 Nginx limit_req 针对特定蜘蛛限速,而不是一刀切封禁
直接 return 403 会误伤合法采集(比如火车头调试、内部监控),也容易触发搜索引擎降权。真正可控的做法是用 limit_req 对指定 User-Agent 做请求频率限制,既保收录又防刷。
关键点在于:不能只靠 $http_user_agent 粗暴匹配,必须配合 map 指令预判 UA 类型,再绑定限速区域。否则 Nginx 启动会报错“invalid number of arguments in ‘limit_req’ directive”。
- 在宝塔网站配置文件的
server块最上方(location外)添加:map $http_user_agent $is_googlebot { ~*Googlebot 1; ~*Baiduspider 1; ~*Bytespider 1; default 0; } - 紧接着加限速定义(放在
http块更合理,但宝塔不开放该处编辑,所以放server块开头也可):limit_req_zone $is_googlebot zone=spider:10m rate=2r/s;
- 在
location /或具体敏感路径(如/api/)里启用:limit_req zone=spider burst=5 nodelay;
为什么 burst=5 和 nodelay 组合比单纯 rate=2r/s 更实用
纯限速会导致爬虫瞬间失败,反而激发其重试机制,造成更多连接堆积。burst 缓冲 + nodelay 是应对突发抓取的合理组合——允许短时 5 次请求透支,且不排队延迟,既满足搜索引擎正常抓取节奏,又卡死高频扫描。
实测中,若去掉 nodelay,遇到 Googlebot 突发抓取首页+资源链接,会大量返回 503;加上后,日志中 499(客户端主动断连)数量下降约 70%,说明爬虫能平滑适应节奏。
-
burst=5表示允许最多积压 5 个请求等待处理 -
nodelay让这 5 个请求立刻通过,不排队,避免超时中断 - 若需更激进控制(如针对已确认恶意的
dataforseo),可单独建 zone,rate 设为0.1r/s,几乎等效于封禁
避免在 location 中重复写 if + return 导致限速失效
很多教程教你在 location 里写:if ($http_user_agent ~* Googlebot) { limit_req ... } —— 这是错的。limit_req 不支持出现在 if 块内,Nginx 会静默忽略,配置看似生效,实际完全不限速。
正确路径只有一条:先用 map 提前标记 UA,再在 location 中无条件调用 limit_req。这也是为什么必须把 map 放在 server 块最顶部——它要在所有上下文之前完成变量初始化。
- 错误写法:
if ($http_user_agent ~* Googlebot) { limit_req zone=spider; } - 正确写法:依赖
$is_googlebot变量,在location中直接写limit_req zone=spider; - 验证是否生效:访问日志中检查
upstream_cache_status字段是否出现MISS后持续HIT,或用curl -I -A "Googlebot/2.1" https://yoursite.com/多次触发,观察响应头是否有X-RateLimit-Limit类字段(需自定义日志格式)
结合宝塔防火墙做 UA 分层处理,别全压给 Nginx
宝塔免费防火墙的 User-Agent过滤 规则适合处理明确恶意的 UA(如 semrushbot、mj12bot、sqlmap),这类直接 return 403 没问题;而主流搜索引擎蜘蛛应交给 Nginx 限速模块,因为防火墙无法做精细速率控制,且规则过多会影响整体 WAF 性能。
一个常见疏漏是:在防火墙里把 Googlebot 也加进禁止列表,结果限速配置完全没机会执行——请求根本到不了 Nginx 的 server 块。
- 防火墙只放高危 UA:复制粘贴时删掉
Googlebot|Baiduspider等关键词 - Nginx 配置专注限速:保留这些 UA 在
map里,用limit_req管理 - 注意防火墙规则顺序:越靠上的规则优先匹配,恶意 UA 规则务必置于“允许搜索引擎”类规则之上
复杂点在于 map 变量作用域和 limit_req_zone 的内存分配——zone=spider:10m 中的 10m 不是随便写的,1m 约支持 1600 个 key,如果同时限速 10 类蜘蛛,至少留足 5m,否则会出现 “limiting requests, excess … request rate exceeded” 却无日志记录的静默丢弃。

















