识别高频异常爬虫后,通过Nginx动态拦截黑名单IP,5分钟生效且无需改业务代码;日志分析发现单IP每小时超200次请求或大量404即标记为恶意,自动写入blacklist.conf并reload,配合cron每5分钟执行,形成服务端闭环防护。

直接看日志就能发现异常爬虫,关键不是“有没有”,而是“谁在高频、集中、无序地刷”。识别之后再用 Nginx 动态拦截,不用改业务代码,5 分钟就能起效。
从 access.log 抓出高频可疑行为
恶意爬虫很少“像人一样浏览”,它们的请求有固定模式,日志里一筛就露馅:
- 单 IP 在 1 小时内请求超过 200 次(正常用户通常
- 只访问 HTML 页面(如 /article/123),完全不加载 CSS、JS、图片等静态资源
- 路径高度规律:比如连续请求 /product/1001 → /product/1002 → …… → /product/5000
- Referer 为空("-"),且 User-Agent 是空、默认值或含 python-requests/scrapy/headlesschrome 等关键词
常用分析命令(以 Nginx 默认日志格式为例):
查最近 1 小时高频 IP:awk -v now=$(date -d '1 hour ago' +"%d/%b/%Y:%H") '$4 ~ now {print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -10
查无 Referer 且集中抓内容页的请求:awk ' == "\"-\"" && ~ /\/article\/|\/product\// {print , }' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -20
用 Nginx 实现动态拦截:限速 + 标记 + 隔离
别一上来就 return 403,那样容易误伤。更稳妥的做法是分三步走:先识别、再限速、最后拦截。Nginx 的 limit_req 和 map 指令配合使用,效果立竿见影。
- 定义一个按 IP 限速的区域:
limit_req_zone $binary_remote_addr zone=spider_limit:10m rate=5r/s;
(每秒最多 5 个请求,超了就排队或拒绝) - 用 map 匹配可疑 UA,打上标记:
map $http_user_agent $is_bot {<br> default 0;<br> "~*(python-requests|scrapy|headlesschrome|curl|wget)" 1;<br> "" 1;<br> } - 在 location 中应用:
location / {<br> if ($is_bot) { limit_req zone=spider_limit burst=3 nodelay; }<br> proxy_pass http://backend;<br> }
这样,真实浏览器不受影响,可疑 UA 被自动压进“慢车道”。
进阶:自动封禁反复试探的 IP
如果某 IP 在短时间内大量触发 404(比如扫目录、试接口)、反复访问 /wp-login.php 或 /search?q=,说明它在探测而非浏览。这类行为应联动日志做自动封禁:
- 用脚本(如 Python 或 Bash)定时扫描日志,提取 5 分钟内触发 > 50 次 404 的 IP
- 将这些 IP 写入 Nginx 的黑名单文件(如 /etc/nginx/conf.d/blacklist.conf):
deny 192.168.100.22;<br> deny 203.124.55.113;
- 在 server 块中 include 该文件,并 reload Nginx:
include /etc/nginx/conf.d/blacklist.conf;
整个过程可自动化,配合 cron 每 5 分钟跑一次,响应快、成本低。
补充建议:别依赖 robots.txt
robots.txt 是君子协议,AI 爬虫、黑产爬虫基本无视。你写 Disallow: /,它们照抓不误。真正有效的防护必须落在服务端——也就是 Nginx 日志分析 + 动态规则执行这个闭环里。如果已有 WAF 或 CDN(如 Cloudflare),建议把 Nginx 作为第二道防线:CDN 层做挑战验证,Nginx 层做行为兜底,双保险更稳。











