Python requests 代理
Python requests 配置代理:从跑通到踩完坑
从最小可运行代码开始,到 Session 复用、超时重试、SOCKS5 支持和常见报错的排查顺序。
最小可运行版本
requests 认 proxies 字典,键是协议名,值是代理地址。账号密码直接写在 URL 里。
注意 https 那一项的值也是 http:// 开头——它表示"用 HTTP 代理去访问 HTTPS 站点",不是笔误。写成 https:// 反而会要求代理本身支持 TLS,多数情况下会连不上。
- proxies = {"http": "http://user:pass@gateway:8000", "https": "http://user:pass@gateway:8000"}
- requests.get("https://api.ipify.org", proxies=proxies, timeout=15)
- 先用返回的 IP 确认代理确实生效了,再接你的业务代码
用 Session,不要每次都新建连接
每调一次 requests.get 就是一次全新的 TCP 握手加 TLS 握手。走代理时这个开销更明显,量大了会变成主要瓶颈。
换成 requests.Session(),把 proxies 挂在 session 上,连接池会自动复用。同时它还会帮你保持 Cookie——这对粘性会话场景是必须的。
超时和重试必须显式设置
requests 默认不超时。不写 timeout,一个卡住的请求可以让你的任务永远挂在那里。走代理时链路更长,卡住的概率比直连高。
timeout 建议写成元组,分别控制连接超时和读取超时,比如 (5, 30)。重试用 urllib3 的 Retry 挂到 HTTPAdapter 上,只对超时和 5xx 重试,4xx 不要重试——那通常是你自己的请求有问题,重试只是白烧流量。
要用 SOCKS5 得先装依赖
requests 本身不带 SOCKS 支持,需要 pip install "requests[socks]"。装好之后把 proxies 的值换成 socks5://user:pass@gateway:port 即可。
如果希望 DNS 解析也走代理(避免本地 DNS 泄露目标域名),用 socks5h:// 而不是 socks5://。这个 h 很容易漏掉。
常见报错的排查顺序
- 407 Proxy Authentication Required:账号密码错了,或者你的出口 IP 不在白名单里
- ProxyError / 连接被拒:网关地址或端口写错,先用 curl --proxy 单独验证一次
- SSLError:多数是本地 CA 证书问题,不要直接关 verify,先更新 certifi
- 返回的 IP 还是本机:proxies 字典的键写错了,或者被环境变量里的 NO_PROXY 命中
与其纠结,不如先测一次
读完还是拿不准,就用最小额度跑一遍真实目标站点。