真正要解决的是tls指纹暴露问题,而非仅换代理;requests默认tls指纹与浏览器差异极大,易被ja3/ja4检测直接403拦截,应改用curl_cffi等支持浏览器指纹模拟的库。

单纯换代理不是解法,是把问题往后拖——真正要解决的是“为什么刚发几个请求就被封”,而不是“换第几个代理能多撑两分钟”。
requests 里 proxy 参数写错导致代理根本没生效
很多人以为只要写了 proxies={"https": "http://x.x.x.x:8080"} 就走代理,但实际会因协议不匹配直接走本机 IP。HTTPS 目标站却配了 HTTP 协议的代理地址,requests 默认不会自动升级协议,结果所有请求仍从你本地出口。
- 必须严格匹配协议:
proxies={"http": "http://ip:port", "https": "https://ip:port"},注意不是都填http:// - 带认证的代理要写全:
"http://user:pass@ip:port",漏掉@或冒号位置错都会静默失败 - 验证是否真走代理:用
requests.get("http://httpbin.org/ip")看返回 JSON 中origin字段,必须等于你填的代理 IP,否则就是白配
代理池没做可用性验证就塞进 requests.Session
API 拿回来的代理列表,90% 以上在 5 分钟内失效。直接塞进 session.proxies,后续所有请求卡在 ProxyError 或超时,整个 session 废掉,还得重建连接。
快速生成专业的 Python 脚本和应用代码。一键创建完整项目结构,支持CLI、API、爬虫、Bot、Django等多种项目类型,包含完整的项目结构、配置文件、依赖管理、测试、README和文档。
- 验证必须轻量:只对
http://httpbin.org/ip发 GET,timeout=3,加stream=True避免读响应体 - 只认两种成功信号:
status_code == 200且返回 JSON 的origin包含该代理 IP 字符串 - 验证失败的代理立刻丢弃,别 retry、别缓存——污染池子比没池子更糟
重试时全局换代理引发并发冲突
用一个 current_proxy 变量,出错就改它,看似简单,但在多线程/异步场景下,A 线程刚换完,B 线程还没读到新值,结果两个请求共用一个失效代理,报错雪崩。
- 代理必须按请求粒度传入:
requests.get(url, proxies=proxy_dict),别设session.proxies - 用
queue.Queue或带锁的itertools.cycle管理代理轮转,确保每次取都是独立副本 - 只对明确由代理引发的异常重试:捕获
ProxyError、ConnectTimeout、ReadTimeout;HTTPError且 status=404 就不该换代理
忽略 TLS 指纹暴露 Python-requests 身份
2026 年多数中大型站点(贝壳、京东、知乎)已上线 JA3/JA4 检测。你 UA 换得再像 Chrome,TLS 握手参数一出来,服务器就知道你是 requests,直接 403,连代理都省得封。
- requests 默认 TLS 指纹和浏览器差异极大,伪装成本低的方案是换库:
curl_cffi或tls-client -
curl_cffi可直接复用 Chrome 的指纹:session = Session(impersonate="chrome120") - 不要自己拼凑 headers + requests 组合,那只是“看起来像”,不是“行为像”
最常被跳过的环节是 TLS 指纹验证——你花半天搭好代理池、UA 轮换、随机延时,结果第一请求就因 JA3 不匹配被拒,连代理是否生效都来不及判断。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










