本文目录导读:

Java防爬虫流程的规范化需要从身份识别、请求频率、访问行为、数据混淆、动态交互五个维度构建纵深防御体系,以下是标准的工程化实践流程:
第一阶段:身份识别与基础过滤
-
IP与UA验证
- IP黑白名单:使用
ServletRequest获取getRemoteAddr(),通过CIDR匹配或Redis黑名单拦截(如5秒内超过阈值)。 - User-Agent检测:维护已知爬虫UA黑名单(
Java/1.8、okhttp/3.x),对空值或无关键字段的请求标记可疑。
- IP黑白名单:使用
-
Header完整性校验
- 检查
Accept-Language、Referer等标准Header是否缺失或异常(如Accept只包含application/json而非text/html)。 - 验证
Sec-Fetch-*头(如Sec-Fetch-Site: none通常为非浏览器请求)。
- 检查
-
Cookie/Token预检
- 首次访问需通过前端提交的JS动态生成的
__csrf_token(HMAC-SHA256加密),服务端验证时效(<2分钟)和签名。 - 对无Cookie或单个会话的API调用频率异常攀升时,触发二次验证。
- 首次访问需通过前端提交的JS动态生成的
第二阶段:动态行为分析
-
Intercepting Filter模式(责任链设计)
- 频率计数器:使用
Guava RateLimiter或Redis + Lua脚本实现滑动窗口限流(如每IP 60次/分钟),超过则响应503并记录日志。 - 时间窗口分析:记录每个会话的请求时间间隔,通过统计平均间隔、标准差(
SimpleDeviations)判断行为异常(如0.1秒恒定间隔)。
- 频率计数器:使用
-
请求路径异常检测
- 畸变URL检测:解析
request.getRequestURI(),如果包含、%00、重复参数名(如id=1&id=2),立即拦截。 - 阈值规则:同一IP访问路径数量超过50条/分钟,或重复访问同一资源且未加载CSS/JS(通过
Accept头判断)。
- 畸变URL检测:解析
第三阶段:反抓取中间件
-
JS动态验证(服务端渲染)
- 验证码生成:使用Java实现
Kaptcha或整合Tencent Captcha,在用户连续点击5次后弹出滑块验证。 - 前端行为采集:通过
Selenium注入JS代码收集鼠标移动轨迹、页面停留时间(performance.now()),服务端用pandas分析滑动轨迹线性度(爬虫通常轨迹不自然)。
- 验证码生成:使用Java实现
-
WebDriver检测
- Java端使用
navigator.webdriver检测(通过JavaScript注入Object.defineProperty(navigator, 'webdriver', { get: () => undefined }),但更有效的是检查document.documentElement.getAttribute(webdriver值)。
- Java端使用
-
异步延迟加载
- 核心数据通过WebSocket在渲染后推送(如
javax.websocket),关键字段加密传输(AES-256-CBC,密钥由前端通过RSA公钥加密后传递)。
- 核心数据通过WebSocket在渲染后推送(如
第四阶段:数据层混淆与动态响应
-
HTML/JSON混淆
- URL编码替代:
<img src="data:image/svg+xml,%3Csvg%2F%3E">静态资源延迟加载。 - 数字混淆:价格字段通过自定义算法(如
(原值-随机质数)^偏移量)加密,前端使用big-integer库解码。 - CSS偏移:部分文本用
<span style="display:none">假数据</span>,动态替换真实位置(如数据在after伪元素中)。
- URL编码替代:
-
响应签名验证
- 返回JSON时附加
signature(SHA256(数据体 + 盐值 + 时间戳)),前端需先发起解密请求获取盐值(经OAuth 2.0授权)。
- 返回JSON时附加
第五阶段:日志审计与自适应策略
-
全链路日志
- 使用
log4j2结合MDC记录:{ip, sessionId, url, userAgent],存储到Elasticsearch。 - 失败模式分析:通过
Kibana识别429状态码集中时段,自动调整阈值(如12:00-14:00放宽至80次/分钟)。
- 使用
-
动态规约升级
- 若单IP在30分钟内触发3次验证,从“限制API”升级为“需手机号绑定”。
- 检测到爬虫特征后,返回随机延迟(50-500ms)及带JavaScript的HTML页面(强制执行验证)。
代码示例:频率拦截过滤器
@Component
@WebFilter(urlPatterns = "/*")
public class RateLimitingFilter implements Filter {
private final ConcurrentHashMap<String, RateLimiter> ipRateLimiters = new ConcurrentHashMap<>();
private final Duration window = Duration.ofMinutes(1);
private final long maxRequests = 60L;
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
String ip = request.getRemoteAddr();
RateLimiter limiter = ipRateLimiters.computeIfAbsent(ip, k -> RateLimiter.create(maxRequests, window));
if (!limiter.tryAcquire()) {
((HttpServletResponse) response).setStatus(429);
response.getWriter().write("请求过于频繁");
return;
}
chain.doFilter(request, response);
}
}
关键注意事项
- 避免误伤:对搜索引擎爬虫(Googlebot、BingBot)需白名单通过,可通过
reverse DNS验证googlebot.com域。 - 法律合规:用户隐私保护优先,不可在日志中明文记录密码或身份证号。
- 性能平衡:非核心API(如文章列表)可降低验证强度,核心交易类API加强验证。
- CDN与WAF协同:配置Cloudflare的
Bot Fight Mode或阿里云WAF的爬虫识别模块,减少底层过滤压力。
通过以上多层策略的组合,可构建具备90%以上爬虫拦截率的防御体系,且能根据攻击手法自动调整防护等级。