Python requests 配置 HTTP、HTTPS、SOCKS5 代理:参数、认证与排错
在 Python 接口联调、网络排障和页面可用性测试中,requests 配置代理是一个常见需求。很多示例只给出一段 proxies={...},但真实项目里更容易出错的地方是协议写法、认证格式、DNS 解析、超时参数和错误分类。
本文讨论 requests 的代理配置和调试方法,不涉及任何非授权访问或高频请求场景。

一、requests 代理配置的基本结构
requests 通过 proxies 参数指定不同协议使用的代理出口:
import requests
proxies = {
"http": "http://127.0.0.1:8080",
"https": "http://127.0.0.1:8080",
}
response = requests.get(
"https://httpbin.org/ip",
proxies=proxies,
timeout=(5, 15),
)
print(response.status_code)
print(response.text)
这里最容易误解的是 "https" 这个键。它表示“访问 HTTPS URL 时使用哪个代理”,不代表代理服务器本身一定要用 https:// 连接。
很多 HTTP 代理访问 HTTPS 站点时,会通过 CONNECT 方法建立隧道,所以代理地址仍然可能是:
"https": "http://127.0.0.1:8080"
是否支持 https://proxy-host:port,要看代理服务端和客户端库是否支持客户端到代理之间的 TLS。
二、带用户名密码的代理怎么写
如果代理需要认证,可以把用户名和密码写入代理 URL:
from urllib.parse import quote
username = quote("user@example")
password = quote("p@ss:word")
proxy_url = f"http://{username}:{password}@127.0.0.1:8080"
proxies = {
"http": proxy_url,
"https": proxy_url,
}
这里使用 quote() 是为了处理用户名或密码里的特殊字符。否则 @、:、# 等字符可能导致 URL 解析错误。
实际项目中,不建议把账号密码直接写入代码。更常见的方式是从环境变量读取:
import os
proxy_url = os.getenv("PROXY_URL")
proxies = {"http": proxy_url, "https": proxy_url} if proxy_url else None
三、SOCKS5 代理需要额外依赖
requests 默认不直接支持 SOCKS。使用 SOCKS5 前,需要安装额外依赖:
pip install "requests[socks]"
配置示例:
import requests
proxies = {
"http": "socks5h://127.0.0.1:1080",
"https": "socks5h://127.0.0.1:1080",
}
response = requests.get(
"https://httpbin.org/ip",
proxies=proxies,
timeout=(5, 15),
)
print(response.json())
socks5:// 和 socks5h:// 的区别主要在 DNS:
| 写法 | DNS解析位置 |
|---|---|
socks5:// |
通常由本地客户端解析 |
socks5h:// |
通常交给代理端解析 |
如果你希望目标域名由代理端解析,通常应使用 socks5h://。
四、Session 复用适合一组连续请求
如果同一个任务要连续访问多个 URL,可以使用 requests.Session() 复用连接和默认配置:
import requests
proxy_url = "http://127.0.0.1:8080"
with requests.Session() as session:
session.proxies.update({
"http": proxy_url,
"https": proxy_url,
})
for url in [
"https://httpbin.org/ip",
"https://httpbin.org/headers",
]:
response = session.get(url, timeout=(5, 15))
print(url, response.status_code)
Session 适合连续请求,但不要误解为“请求一定使用同一个出口”。出口是否变化取决于代理服务本身的调度规则。
五、超时参数建议分开设置
不要只写 timeout=30。更建议使用二元组:
timeout=(5, 15)
含义是:
- 5 秒连接超时;
- 15 秒读取超时。
这样更容易判断问题发生在哪一层。如果连接阶段就超时,通常要检查代理地址、端口、认证和链路;如果读取阶段超时,说明连接已经建立,但目标响应或中间链路过慢。
六、错误类型怎么排查
可以按下面方式捕获错误:
import requests
try:
response = requests.get(
"https://httpbin.org/ip",
proxies=proxies,
timeout=(5, 15),
)
print("status:", response.status_code)
except requests.exceptions.ProxyError as exc:
print("proxy error:", exc)
except requests.exceptions.ConnectTimeout as exc:
print("connect timeout:", exc)
except requests.exceptions.ReadTimeout as exc:
print("read timeout:", exc)
except requests.exceptions.SSLError as exc:
print("ssl error:", exc)
except requests.RequestException as exc:
print("request error:", type(exc).__name__, exc)
常见含义如下:
| 错误 | 常见原因 |
|---|---|
ProxyError |
代理地址、端口、认证或协议不正确 |
ConnectTimeout |
连接代理或连接目标站点超时 |
ReadTimeout |
连接已建立,但读取响应超时 |
SSLError |
TLS 握手或证书链异常 |
| HTTP 407 | 代理认证失败 |
| HTTP 429 | 请求频率或目标接口限制 |
不要把所有异常都写成 except Exception 后直接忽略。错误类型本身就是排查线索。
七、一个最小可复用函数
下面函数适合放在测试脚本里,用于快速验证代理配置。
import requests
def fetch_with_proxy(url: str, proxy_url: str | None = None) -> dict:
proxies = None
if proxy_url:
proxies = {
"http": proxy_url,
"https": proxy_url,
}
try:
response = requests.get(
url,
proxies=proxies,
timeout=(5, 15),
)
return {
"ok": True,
"status_code": response.status_code,
"text": response.text[:200],
}
except requests.RequestException as exc:
return {
"ok": False,
"error_type": type(exc).__name__,
"error": str(exc),
}
调用方式:
result = fetch_with_proxy(
"https://httpbin.org/ip",
"http://127.0.0.1:8080",
)
print(result)
八、调试时建议记录这些字段
为了后续复盘,建议把结果记录成结构化日志:
target_url
proxy_scheme
status_code
elapsed_ms
error_type
timestamp
如果涉及 SOCKS5,还可以记录使用的是 socks5:// 还是 socks5h://,避免 DNS 解析位置造成误判。
九、总结
requests 配置代理并不复杂,真正容易出错的是协议理解、认证格式、DNS 解析和错误分类。
开发测试时建议做到三点:代理地址从环境变量读取,超时参数分连接和读取两段设置,异常日志按类型记录。这样后续排查会比只看“请求失败”清楚得多。
更多推荐


所有评论(0)