Get请求在Postman中正常,curl/NodeJS/Python调用多次后被封禁原因是什么?
核心原因及对应解决方案
1. TLS指纹识别导致的特征封禁
当前多数站点的WAF已经不再仅依赖User-Agent识别自动化请求,而是会通过JA3/JA3S指纹标记客户端类型:TLS握手阶段客户端上报的加密套件列表、加密套件排序、支持的TLS扩展、扩展排序、椭圆曲线/椭圆曲线点格式等组合特征会生成唯一的JA3指纹,Python requests/urllib、NodeJS原生HTTP模块、默认编译的curl的JA3指纹和Chrome、Postman的指纹存在明显差异,即使你修改了User-Agent,WAF依然可以通过指纹识别到你是脚本请求,累计几次后就会拉黑对应特征的请求。而你本地的Postman、浏览器的指纹未被标记,所以同一IP下依然可以正常访问。
2. 请求头的完整性、顺序不匹配
你仅添加了User-Agent参数,但Postman、浏览器发起的请求会携带完整的标准请求头,包括Accept、Accept-Language、Accept-Encoding、Connection等,且请求头的排列顺序是固定的。多数脚本的HTTP库默认的请求头顺序和浏览器/Postman不同,且存在缺头的情况,这也是WAF的重要识别特征。另外Postman会自动保存服务端返回的Cookie并在后续请求自动携带,如果你的脚本没有维护Cookie会话,每次请求都是无状态的,也会被快速标记。
3. 请求时序特征异常
如果你是用脚本循环发起请求,默认的请求间隔通常是固定值甚至无间隔,这种高度规律的高频请求流量特征和人工操作Postman时随机波动的请求间隔差异极大,WAF的流量分析模块会直接将这类请求判定为自动化爬虫,触发封禁规则。
修复方案
- 替换默认HTTP库规避TLS指纹识别:Python可以使用
curl_cffi库直接模拟浏览器/Postman的JA3指纹,curl可以使用预编译的curl-impersonate版本,NodeJS可以使用对应指纹修改类库调整TLS指纹。 - 完整复刻请求头:从Postman的成功请求中导出所有请求头(包括头的顺序),原封不动配置到脚本中,同时使用会话对象维护Cookie,比如Python中使用
requests.Session(),确保和Postman的请求行为完全一致。 - 调整请求频率:给脚本请求添加1~3秒的随机延迟,避免固定间隔的高频请求。
内容的提问来源于stack exchange,提问作者Guanhua Li

