本文目录导读:

针对爬虫扫描行为的封禁,需要从网络层、应用层、业务层三个维度构建防御体系,由于爬虫技术(特别是AI驱动的爬虫)日益复杂,单一手段很难彻底解决问题,以下是系统的封禁策略,按推荐程度和实现难度排序:
网络层(基础防御,适合快速阻断)
这是最直接的手段,主要针对低端爬虫或扫描器(如 curl、Python requests)。
-
IP 黑名单与动态封禁
- 基于速率限制:监控单个IP的请求频率(如/秒、/分钟),超过阈值(如 100 req/min)自动封禁一段时间(如 10分钟)。
- 基于地域封禁:如果业务不面向特定国家(如俄罗斯、乌克兰),可以直接禁用其IP段。
- 威胁情报库:订阅第三方 IP 黑名单(如 AbuseIPDB、Spamhaus),实时同步封禁。
-
User-Agent 与请求头过滤
- 封禁空 UA、非浏览器 UA、扫描器特征 UA(如
python-requests、Go-http-client、Nmap)。 - 注意:这种做法很容易被绕过(模拟浏览器UA),所以只能作为第一道粗糙的防线。
- 封禁空 UA、非浏览器 UA、扫描器特征 UA(如
-
禁止 HTTP 动词
- 对
TRACE、OPTIONS、PUT、DELETE等非必要动词直接返回 403 或 405,防止扫描器探测你服务器的信息。
- 对
-
限制 HTTP 版本
- 封禁使用
HTTP/0.9、HTTP/1.0的连接(现代浏览器几乎不用,很多扫描器默认使用)。
- 封禁使用
应用层(主动识别与阻截,核心防御)
这一层主要识别伪装成正常浏览器的爬虫。
-
JavaScript 挑战(最推荐)
- 原理:真正的浏览器在打开页面时会执行 JavaScript,向服务器发送额外请求验证;而简单爬虫不会解析或执行 JS。
- 工具:Cloudflare Turnstile / JS Challenge、Google reCAPTCHA v3、Akamai Bot Manager。
- 效果:可阻挡 99% 的普通爬虫。务必使用无感模式(v3),不要给用户弹出验证码。
-
Cookie 验证
首屏加载时,通过 JS 设置一个动态生成的 Cookie,后续请求需携带该 Cookie,爬虫通常无法处理这种两步验证。
-
行为指纹分析(Advanced)
- 使用 FingerprintJS 或 Sentinel 等工具,检测:
- WebGL 渲染:虚拟环境(如 Selenium)的 WebGL 渲染结果与真实浏览器不同。
- Canvas 指纹:真实 GPU 对 canvas 2D 的渲染不同。
- 时间戳精度:爬虫的
performance.now()精度异常。 - 鼠标轨迹:爬虫没有真实的鼠标移动轨迹,或者轨迹过于刻意。
- 对高风险的指纹直接封禁(即使该 IP 是正常的)。
- 使用 FingerprintJS 或 Sentinel 等工具,检测:
-
Honepot 陷阱(蜜罐)
- 在页面中隐藏一个
<link>或<a>(display: none或visibility: hidden),指向一个监控页面/honeypot。 - 爬虫:会抓取所有链接,包括隐藏的;用户:看不见,自然都不会点击。
- 一旦
/honeypot被访问,立即封禁该 IP(因为它一定不是真人用户)。
- 在页面中隐藏一个
-
请求频率的动态调整
- 正常用户:浏览间隔通常 > 1秒,且会看图片、暂停、滚动。
- 爬虫:请求间隔均匀(如 0.5秒一次)。
- 策略:如果检测到“均匀且快速”的请求模式,直接封禁,而不是简单的速率限制。
业务层(高价值数据保护)
如果上面的所有方法都被绕过,爬虫拿到了数据,你仍然可以做最后一层防御。
-
数据加扰与伪装
- 电话号码:显示为
138****1234,点击“查看”才请求完整号码(并带风控校验)。 - 图片水印:重要数据(如房价、价格)用动态生成的图片展示,而非纯文本。
- 随机字段名:每次返回的 HTML 中,
class或id随机化,爬虫无法靠固定选择器定位。
- 电话号码:显示为
-
API 接口加密
- 不使用明文 JSON,使用非对称加密(RSA)或对称加密(AES) + 动态密钥。
- 请求参数进行签名(HMAC-SHA256),签名包含时间戳+随机数,防止重放攻击。
-
虚拟数据注入
- 对高频访问的 API,随机返回
null或虚假数据(如name: "测试用户9991"),观察爬虫是否崩溃或异常。
- 对高频访问的 API,随机返回
进阶策略(对付高级爬虫)
如果爬虫使用了无头浏览器(Headless Chrome)并模拟真人操作,普通 JS 挑战会失效,你需要:
-
CAPTCHA 挑战(二次验证)
- 策略:不要所有用户都弹验证码,只对被怀疑的用户弹。
- 触发条件:请求频率高、行为模式异常、IP 来自数据中心/代理。
- 推荐:Google reCAPTCHA v3(返回分数,无需用户点击);v2(用户需点选图片,但会干扰体验)。
-
CDN/WAF 的边缘计算
- 使用 Cloudflare Workers 或 AWS WAF,在边缘节点直接执行规则:
- 地理封禁:在黑名单国家的请求直接丢弃。
- JS 质询:对可疑请求强制执行 JS 验证。
- 动态频率限制:根据路径灵活限制(如
/api/price比/css/style.css限制更严格)。
- 使用 Cloudflare Workers 或 AWS WAF,在边缘节点直接执行规则:
-
机器学习(异常检测)
- 收集正常用户的行为特征(点击率、页面停留时间、滚动速度),训练模型。
- 当新请求的特征偏离正常分布(如爬虫无停留时间、无鼠标移动),自动打标封禁。
实施流程(建议按照这个顺序)
graph LR
A[原始请求] --> B{IP 是否在黑名单?};
B -- 是 --> C[直接 403 拒绝];
B -- 否 --> D{请求头是否可疑?};
D -- 是 --> E[触发 JS Challenge];
D -- 否 --> F{访问频率是否超阈值?};
F -- 是 --> G[返回 429 Too Many Requests];
F -- 否 --> H{是否触碰到蜜罐?};
H -- 是 --> I[封禁 IP 并记录];
H -- 否 --> J{行为指纹是否异常?};
J -- 是 --> K[触发 CAPTCHA 或降级];
J -- 否 --> L[正常访问];
必须避免的误区
- 不要用“UA 白名单”:因为爬虫可以轻易伪造任何浏览器的 UA。
- 不要过度依赖 IP 封禁:IP 可能被换(如数据中心 IP),且可能误伤正常用户(如公司内网共用一个公网 IP)。
- 不要直接返回 403:低级的爬虫可能不在乎,高级的爬虫会认为“有 CDN”,转而用更隐蔽的方式攻击,更好的做法是返回 200 但内容为空,或者返回虚假数据,让爬虫误以为爬取成功但实际数据无用。
推荐工具组合
- 小型网站:Nginx +
limit_req(速率限制)+ JS Challenge(自己写或用第三方库 likescraper-detect)。 - 中型网站:Cloudflare(免费版即可,开启 Bot Fight Mode) + WAF 规则 + 蜜罐。
- 大型/高价值网站:Akamai / Imperva / Cloudflare Enterprise + 自研行为分析系统 + 数据加密。
没有100%能防住所有爬虫的方案,除非你不让任何人访问。 核心策略是:提高爬虫的成本(让它需要不断破解新验证),降低其收益(让拿到的数据没用/过时),通常封禁率能做到 95% 以上,剩下的 5% 只能通过法律或特殊手段处理。