在网络爬虫、API 调用或数据采集中,使用代理 IP 是绕过频率限制、隐藏真实 IP 或访问区域限制内容的常用手段。本文将系统讲解如何通过 Python requests 库配置 **HTTP、HTTPS、SOCKS5** 三大类代理,并提供可直接运行的完整代码示例。
import requests
# 定义代理字典:key 为协议,value 为代理地址
proxies = {
"http": "http://127.0.0.1:8080",
"https": "http://127.0.0.1:8080", # 注意:https 请求也可以走 http 代理隧道
}
response = requests.get(
"https://httpbin.org/ip",
proxies=proxies,
timeout=10
)
print(response.json())**关键说明**:
proxies 参数接受一个字典,http 和 https 分别对应不同协议的出口;如果代理服务器同时支持两者,通常写成相同地址即可。timeout=10 建议始终加上,防止代理不可用时程序无限挂起。import requests
proxies = {
"http": "http://127.0.0.1:8080",
"https": "http://127.0.0.1:8080",
}
# httpbin.org/ip 会返回请求来源 IP
r = requests.get("https://httpbin.org/ip", proxies=proxies, timeout=10)
print("当前出口 IP:", r.json()["origin"])如果返回的 IP 与本地公网 IP 不同,说明代理已生效。
商业代理服务通常需要提供用户名和密码。requests 支持将认证信息直接嵌入 URL:
import requests
# 格式:protocol://username:password@host:port
proxies = {
"http": "http://user123:pass456@proxy.example.com:8080",
"https": "http://user123:pass456@proxy.example.com:8080",
}
r = requests.get("https://httpbin.org/get", proxies=proxies, timeout=15)
print(r.status\_code)把密码明文写在代码里并不安全。更推荐的做法是:
import os
import requests
PROXY\_USER = os.getenv("PROXY\_USER")
PROXY\_PASS = os.getenv("PROXY\_PASS")
PROXY\_HOST = os.getenv("PROXY\_HOST", "proxy.example.com")
PROXY\_PORT = os.getenv("PROXY\_PORT", "8080")
proxies = {
"http": f"http://{PROXY\_USER}:{PROXY\_PASS}@{PROXY\_HOST}:{PROXY\_PORT}",
"https": f"http://{PROXY\_USER}:{PROXY\_PASS}@{PROXY\_HOST}:{PROXY\_PORT}",
}通过环境变量注入敏感信息,避免泄露到代码仓库。
requests 本身不支持 SOCKS5,需要额外安装 PySocks:
pip install requests[socks]
# 或者单独安装
pip install PySocksimport requests
# socks5:// 表示不通过代理解析 DNS(本地解析)
# socks5h:// 表示由代理服务器远程解析 DNS(推荐)
proxies = {
"http": "socks5h://127.0.0.1:1080",
"https": "socks5h://127.0.0.1:1080",
}
r = requests.get("https://httpbin.org/ip", proxies=proxies, timeout=15)
print(r.json())| 协议前缀 | DNS 解析位置 | 适用场景 |
|---------|-----------|---------|
| socks5:// | 客户端本地 | 本地能正常解析目标域名 |
| socks5h:// | 代理服务器远程 | 避免 DNS 污染、访问暗网或特殊网络 |
**生产环境强烈建议使用 socks5h://**,既防止本地 DNS 泄漏,也能解决某些域名在本地无法解析的问题。
import requests
proxies = {
"http": "socks5h://user:password@127.0.0.1:1080",
"https": "socks5h://user:password@127.0.0.1:1080",
}
r = requests.get("https://httpbin.org/ip", proxies=proxies, timeout=15)
print(r.json())Tor 默认监听 9150(Tor Browser)或 9050(Standalone):
import requests
# Tor 必须使用 socks5h,否则 .onion 地址无法解析
proxies = {
"http": "socks5h://127.0.0.1:9150",
"https": "socks5h://127.0.0.1:9150",
}
# 访问普通网站
r = requests.get("https://check.torproject.org", proxies=proxies, timeout=20)
print("Tor 状态:", "Congratulations" in r.text)如果整个脚本都需要走同一个代理,不必在每个 get/post 里重复写 proxies,可以挂载到 Session 对象上:
import requests
# 创建 Session
session = requests.Session()
session.proxies = {
"http": "http://127.0.0.1:8080",
"https": "http://127.0.0.1:8080",
}
session.headers.update({
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"
})
# 后续所有请求自动复用该代理和 Header
r1 = session.get("https://api.github.com")
r2 = session.get("https://httpbin.org/get")
session.close()优点:
requests 会自动读取系统环境变量中的代理配置,无需修改代码:
# Linux / macOS
export HTTP\_PROXY="http://127.0.0.1:8080"
export HTTPS\_PROXY="http://127.0.0.1:8080"
# SOCKS5 同样支持
export ALL\_PROXY="socks5h://127.0.0.1:1080"# Windows PowerShell
$env:HTTP\_PROXY="http://127.0.0.1:8080"
$env:HTTPS\_PROXY="http://127.0.0.1:8080"代码中只需关闭 trust\_env=False 才会忽略环境变量:
import requests
# 默认 trust\_env=True,自动读取环境变量中的代理
# 显式关闭后,即使系统设置了 HTTP\_PROXY 也不会生效
r = requests.get("https://httpbin.org/ip", trust\_env=False)大规模爬取时,单一 IP 容易被封禁。简单实现一个代理池:
import random
import requests
PROXY\_POOL = [
"http://192.168.1.10:3128",
"http://192.168.1.11:3128",
"http://192.168.1.12:3128",
"socks5h://192.168.1.20:1080",
]
def get\_proxy():
"""随机选取一个代理"""
return {"http": random.choice(PROXY\_POOL), "https": random.choice(PROXY\_POOL)}
for i in range(5):
proxy = get\_proxy()
try:
r = requests.get("https://httpbin.org/ip", proxies=proxy, timeout=5)
print(f"第{i+1}次请求成功,IP: {r.json()['origin']}")
except requests.exceptions.ProxyError as e:
print(f"第{i+1}次代理错误: {e}")
except requests.exceptions.Timeout:
print(f"第{i+1}次请求超时")进阶做法:结合 requests.adapters.HTTPAdapter + urllib3.util.retry.Retry 做失败重试与代理切换。
| 现象 | 可能原因 | 解决方案 |
|------|---------|---------|
| ProxyError / Cannot connect to proxy | 代理地址错误或代理服务未启动 | 检查 host、port、防火墙 |
| SSLError / certificate verify failed | HTTPS 代理中间人截获证书 | 尝试 verify=False(仅调试!)或更换代理 |
| SOCKS5 代理无效 | 未安装 PySocks | pip install requests[socks] |
| .onion 地址无法访问 | 使用了 socks5:// 而非 socks5h:// | 改为 socks5h:// 让代理远程解析 |
| 速度极慢 | 代理带宽不足或地理位置远 | 换更近的节点或增加 timeout |
| 仍然显示本机 IP | trust\_env=True 但环境变量未生效 / 代理未真正工作 | 先用 curl -x 命令行测试代理可用性 |
#!/usr/bin/env python3
"""
requests 代理配置全协议演示脚本
运行前请确保:
pip install requests PySocks
并根据实际情况修改下方的代理地址。
"""
import os
import requests
# ==================== 配置区 ====================
# 1) HTTP/HTTPS 代理(无需认证)
HTTP\_PROXY = "http://127.0.0.1:8080"
# 2) HTTP/HTTPS 代理(需认证)
# HTTP\_AUTH\_PROXY = "http://user:pass@proxy.example.com:8080"
# 3) SOCKS5 代理
SOCKS5\_PROXY = "socks5h://127.0.0.1:1080"
TEST\_URL = "https://httpbin.org/ip"
TIMEOUT = 15
# ==============================================
def test\_http\_proxy():
"""测试 HTTP/HTTPS 代理"""
proxies = {"http": HTTP\_PROXY, "https": HTTP\_PROXY}
try:
r = requests.get(TEST\_URL, proxies=proxies, timeout=TIMEOUT)
print(f"[HTTP 代理] 成功 -> 出口 IP: {r.json().get('origin')}")
except Exception as e:
print(f"[HTTP 代理] 失败 -> {type(e).\_\_name\_\_}: {e}")
def test\_socks5\_proxy():
"""测试 SOCKS5 代理"""
proxies = {"http": SOCKS5\_PROXY, "https": SOCKS5\_PROXY}
try:
r = requests.get(TEST\_URL, proxies=proxies, timeout=TIMEOUT)
print(f"[SOCKS5 代理] 成功 -> 出口 IP: {r.json().get('origin')}")
except Exception as e:
print(f"[SOCKS5 代理] 失败 -> {type(e).\_\_name\_\_}: {e}")
def test\_session\_proxy():
"""测试 Session 级别代理"""
session = requests.Session()
session.proxies = {"http": HTTP\_PROXY, "https": HTTP\_PROXY}
try:
r = session.get(TEST\_URL, timeout=TIMEOUT)
print(f"[Session 代理] 成功 -> 出口 IP: {r.json().get('origin')}")
except Exception as e:
print(f"[Session 代理] 失败 -> {type(e).\_\_name\_\_}: {e}")
finally:
session.close()
def test\_env\_proxy():
"""测试环境变量代理(需提前 export HTTP\_PROXY/HTTPS\_PROXY)"""
# 注意:若当前 shell 未设置,则此测试等价于直连
try:
# trust\_env=True 为默认值,自动读取环境变量
r = requests.get(TEST\_URL, timeout=TIMEOUT)
print(f"[环境变量代理] 响应 IP: {r.json().get('origin')} (若无代理则为本机IP)")
except Exception as e:
print(f"[环境变量代理] 失败 -> {type(e).\_\_name\_\_}: {e}")
if \_\_name\_\_ == "\_\_main\_\_":
print("=" \* 50)
print("Python requests 代理配置测试")
print("=" \* 50)
test\_http\_proxy()
test\_socks5\_proxy()
test\_session\_proxy()
test\_env\_proxy()
print("=" \* 50)
print("测试完成。请将上方代理地址替换为你自己的可用代理。")| 场景 | 推荐写法 |
|------|---------|
| 临时单次请求 | requests.get(url, proxies={...}) |
| 大量同域名请求 | session.proxies = {...} |
| CI/CD 或团队协作 | 环境变量 HTTP\_PROXY + trust\_env=True |
| 匿名/隐私需求高 | socks5h:// 让代理端解析 DNS |
| 多 IP 防封禁 | 自建代理池 + 随机轮换 |
掌握以上几种模式后,无论是日常接口调试还是大规模数据采集,都能灵活应对各种代理环境。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。