反爬虫与风控
一、反爬虫的种类
1. 基于用户行为
- 访问频率限制:检测单位时间内请求次数,超阈值封禁IP
- 行为模式分析:分析点击、滚动、停留时间等,识别机器行为
- 验证码:图片验证码、滑块验证、行为验证等
2. 基于请求特征
- User-Agent 检测:过滤非正常浏览器请求
- Referer 检测:验证请求来源
- Cookie 验证:检测是否携带特定 Cookie
- 请求头完整性:检查是否包含浏览器标准字段
3. 动态内容加载
- JavaScript 渲染:动态生成页面内容
- AJAX 异步加载:通过异步请求加载数据
- WebSocket:使用 WebSocket 协议传输数据
4. 内容保护技术
- 字体反爬:自定义字体文件,将文字映射到不同 Unicode 编码
- CSS 偏移:CSS 打乱元素顺序,DOM 结构与显示不一致
- 图片化:将文字内容转换为图片
- Canvas/WebGL 指纹:生成唯一设备指纹
5. 数据加密
- 参数加密:请求参数加密,需逆向算法才能构造请求
- 响应数据加密:返回数据加密,需解密才能使用
- Token 机制:动态生成 Token 验证请求合法性
6. 蜜罐技术
- 隐藏链接:放置普通用户看不到但爬虫会访问的链接
- 诱饵数据:插入虚假数据来识别和追踪爬虫
二、风控核心维度
风控系统从三个维度审视用户:
1. 环境风控(你是谁?)
- IP 地址:检测是否为数据中心IP或代理IP
- 设备指纹:显卡型号、屏幕分辨率、电池电量等硬件信息
- 运行环境:检测模拟器、无头浏览器等
2. 行为风控(你在做什么?)
- 访问频率:正常人需要时间阅读,爬虫毫秒级请求
- 操作轨迹:人类鼠标有惯性和抖动,爬虫是直线
- 访问逻辑:正常浏览路径:首页→搜索→详情页;爬虫直接请求API
3. 协议风控(你在说什么?)
- 代码混淆:变量名用乱码代替,增加逆向难度
- 加密参数:请求需携带特定算法计算的签名(Sign)或令牌(Token)
三、Headers 风控分析
| Header | 风控关注点 | 风险等级 | 规避策略 |
|---|---|---|---|
| User-Agent | 是否为爬虫标识、是否与浏览器指纹匹配 | 高 | 维护真实UA池,与TLS/Client Hints保持一致 |
| Cookie | 会话状态、行为追踪标识 | 高 | Session保持会话,定期刷新 |
| Referer | 请求来源是否合理 | 中 | 模拟正常浏览路径 |
| Sec-Fetch-* | 请求上下文(mode/site/dest) | 中 | 理解含义后正确伪造 |
| Sec-CH-UA-* | Client Hints 指纹识别 | 中 | 与UA版本保持一致 |
| X-Forwarded-For | 代理IP检测 | 中 | 使用高匿代理 |
| Accept-Language | 语言偏好是否与IP地域一致 | 低 | 根据代理IP地域设置 |
完整 Headers 模板
python
def get_chrome_headers(referer=None):
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
"Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8",
"Accept-Encoding": "gzip, deflate, br",
"Sec-Fetch-Dest": "document",
"Sec-Fetch-Mode": "navigate",
"Sec-Fetch-Site": "none" if not referer else "same-origin",
"Sec-Fetch-User": "?1",
"Sec-CH-UA": '"Chromium";v="122", "Not(A:Brand";v="24", "Google Chrome";v="122"',
"Sec-CH-UA-Mobile": "?0",
"Sec-CH-UA-Platform": '"Windows"',
}
if referer:
headers["Referer"] = referer
return headersHeader 之外的检测
| 检测维度 | 说明 | 解决方案 |
|---|---|---|
| TLS/JA3 指纹 | TLS握手参数形成唯一指纹 | curl_cffi、tls-client |
| HTTP/2 指纹 | SETTINGS帧、WINDOW_UPDATE值 | httpx 原生HTTP/2 |
| 行为分析 | 请求间隔、鼠标轨迹、页面停留 | 随机化间隔、模拟人类行为 |
| JS 指纹 | Canvas、WebGL、AudioContext | Playwright + Stealth 插件 |
四、Web 风控对抗
突破方法
- 真实浏览器环境:
undetected-chromedriver、Puppeteer Stealth、Playwright - 模拟人类行为:随机鼠标轨迹、随机输入间隔、随机请求间隔
- 代理池 + 指纹伪造:使用
selenium_profiles随机配置 - 逆向加密算法:Chrome DevTools 分析 + Hook 关键函数
python
# curl_cffi 模拟真实浏览器TLS指纹
from curl_cffi import requests
response = requests.get("https://example.com", impersonate="chrome110")五、Android 风控对抗
检测手段
- Root 检测、模拟器检测、Hook 框架检测(Xposed/Frida)
- VPN/代理检测、多开检测、签名校验、SO 加固
绕过方法
- Frida 动态 Hook:Hook Root 检测、文件存在性检查
- VirtualXposed/太极:无需 Root 使用 Xposed 模块
- 模拟器伪装:修改
build.prop属性 - 绕过 SSL Pinning:Frida Hook
CertificatePinner.check - 反编译重打包:
apktool反编译 → 去除检测 → 重签名
六、iOS 风控对抗
检测手段
- 越狱检测、代码签名验证、反调试(LLDB)
- 反注入(检测 Substrate/Frida)、完整性校验、SSL Pinning
绕过方法
- Frida 绕过越狱检测:Hook
NSFileManager.fileExistsAtPath、canOpenURL - Objection 自动化:
ios jailbreak disable、ios sslpinning disable - 重签名注入:
insert_dylib注入 FridaGadget - 越狱插件:A-Bypass、Liberty Lite、Shadow、FlyJB X
七、工具推荐
| 工具 | 适用场景 | 特点 |
|---|---|---|
requests | 简单站点 | 轻量,但TLS指纹明显 |
httpx | 需要HTTP/2 | 支持异步,原生HTTP/2 |
curl_cffi | 绕过TLS检测 | 可模拟真实浏览器指纹 |
Playwright | 重度反爬站点 | 真实浏览器,配合stealth |
undetected-chromedriver | Selenium场景 | 自动绕过常见检测 |
八、总结
- 采用纵深防御,不依赖单一防护手段
- 风控需平衡安全性和用户体验
- 攻防对抗持续演进,需定期更新策略
- 遵守
robots.txt和相关法律法规