屏蔽恶意爬虫:UA 与频控的组合
发布时间:2026-06-22 11:04       
更新时间:2026-06-22 20:05
屏蔽爬虫的动作要从轻到重排好顺序:robots 提示放最前,UA 拦截居中,频控兜底,每一步都先观察再收紧。
一、robots.txt 的定位
robots.txt 是给守规矩的爬虫看的声明,恶意采集器不会理会。它的价值在于划清正式边界:搜索引擎的爬虫遵守它,误伤问题在第一层就解决了。但它挡不住任何恶意流量,别指望一个 Disallow 解决所有问题;robots 规则生效也有延迟,搜索引擎重新抓取这份文件才会更新,急不得。
二、UA 拦截
nginx 里用 map 做匹配,比堆叠多个 if 清晰:
map $http_user_agent $bad_agent {
default 0;
"" 1;
~*scrapy 1;
~*python-request 1;
}
server 块里加一行 if ($bad_agent) { return 403; }。正则用 ~* 表示大小写不敏感;空 UA 直接判 1。名单只加确认过恶意的标识,别把 curl 一刀切禁掉,很多监控探活也在用这些 UA;名单维护成文件便于审计,谁加的、为什么加,写进注释。规则上线后用 curl -A 模拟对应 UA 请求一次,确认返回 403、且没有误伤其他路径。
三、频控
UA 可以伪造,频控看的是行为。nginx 的 limit_req 按来源地址限速:
limit_req_zone $binary_remote_addr zone=perip:10m rate=10r/s;
location / {
limit_req zone=perip burst=20 nodelay;
}
阈值从宽到严:先给 10r/s 跑几天,看被限流日志里有没有正常用户特征,再逐步收紧。正常用户点页面的频率远低于采集器,每秒 10 到 20 次的量级通常不影响人、只卡机器。被限流的请求默认返回 503,配上 limit_req_status 403 可以和业务错误区分开,统计日志时方便。登录、搜索这类成本高的接口,单独配更严格的 location 级阈值,比全站一刀切更精准;静态资源路径则单独放宽,图片加载频繁,和页面请求共用一套限流会误伤正常浏览。
四、误伤评估
上线前先设观察模式:把 return 403 临时改成只记日志不拦截,跑一两天,统计命中名单里有没有带正常 referer、带 cookie 的请求;评估误伤别只看数量,抽几条命中日志看完整请求头,是不是真用户一眼可辨。前面有 CDN 时,限流要在还原真实 IP 之后配,否则所有请求共享节点 IP 的额度,一封就是一片。封禁名单定期清理,家庭宽带和手机网络的 IP 是轮换的,老名单只会扩大误伤面。