网站被爬虫攻击时,可通过Nginx日志中$time_iso8601、$remote_addr、$uri、$status、$http_user_agent等字段,结合时间窗口、IP、路径三维度聚类,还原爬虫行为轨迹并驱动自动拦截。

当网站突然遭遇大量异常请求,页面加载变慢、API 响应超时、数据库连接数飙升,大概率是被大规模爬虫盯上了。Nginx 日志虽不直接记录“谁在爬”,但通过时间戳、IP、URI、状态码、User-Agent、请求大小等字段,能完整还原爬虫的访问路径图——不是单点扫描,而是全天候行为脉络。
聚焦关键日志字段,快速识别异常模式
Nginx 默认的 log_format 往往不够用。生产环境建议启用增强型日志格式,至少包含以下字段:
- $time_iso8601:精确到秒的时间戳,便于按分钟/小时聚合分析行为节奏
- $remote_addr / $http_x_forwarded_for:真实客户端 IP(注意区分代理穿透)
-
$request_method $uri $args:完整请求路径,含参数,用于识别遍历式爬取(如
/article?id=1→/article?id=2) - $status $body_bytes_sent:200 大量返回 + 小响应体 = 高概率内容盗取;404 集中爆发 = 目录爆破或旧链扫描
-
$http_user_agent:识别已知爬虫标识(如
python-requests、Go-http-client),也注意伪装成 Chrome 的恶意 UA - $request_time $upstream_response_time:区分是 Nginx 拦截快,还是后端真被压垮
用时间窗口+IP+路径三维度聚类,绘制爬虫轨迹
单看 IP 或单看 URI 都容易误判。真正有效的路径图需交叉分析:
- 按 5 分钟窗口 统计每个 IP 的请求数、唯一 URI 数、平均 request_time —— 突增且 URI 高度离散(如 300 次请求访问 298 个不同路径),基本可判定为自动化遍历
- 对高频 URI 提取路径层级(如
/api/v2/user/123→/api/v2/user/*),观察是否出现规律性通配(/product?page=1~/product?page=1000) - 将同一 IP 在一天内访问的 URI 按时间排序,生成“访问序列”:若呈现
/robots.txt → /sitemap.xml → /category/1 → /product/1001 → /product/1002…这类典型流程,就是标准爬虫行为链
结合日志与实时指标,定位攻击入口和薄弱环节
日志还原不能停留在“知道被爬”,要驱动防御动作:
- 比对异常时段的 QPS 上升曲线 和 5xx 错误率突增点:若两者高度重合,说明爬虫已穿透限流,正在冲击业务层
- 检查高请求 URI 对应的后端服务:是否缺少缓存?是否每次查询都直连 DB?例如
/search?q=xxx接口无 Redis 缓存 + 无查询限长,极易被关键词穷举 - 查看
444或403状态码分布:若大量请求在进入 upstream 前就被 Nginx 主动拒绝,说明已有基础规则(如 UA 黑名单)生效;若全是 200,说明当前防护形同虚设
落地建议:从日志分析到自动拦截的闭环
人工查日志只能应急,长期需构建可复用的防御链:
- 用 GoAccess 或 awk + sort + uniq 快速生成日报:TOP 10 异常 IP、TOP 20 遍历路径、每小时 UA 分布热力图
- 将聚类结果写入临时黑名单(如 Redis Set),由 Nginx lua-resty-iputils 模块实时校验,5 分钟内自动封禁高危 IP
- 对确认为爬虫的 UA 或路径模式,在 Nginx 配置中增加 map 规则,将风险请求打上
$is_crawler标签,分流至专用限流策略(如漏桶速率 1r/s) - 定期导出“爬虫路径图”样本(含时间线+IP+URI序列),喂给 WAF 或自研风控模型,提升下一次识别准确率











