在爬虫开发、API调用或数据采集过程中,使用代理IP是绕过频率限制、隐藏真实IP的常用手段。Python的requests库提供了简洁的代理配置方式,本文将从基础到进阶,带您完整掌握requests设置代理的实战技巧。
一、基础代理配置:一行代码搞定
requests通过proxies参数指定不同协议使用的代理出口。最基本的写法如下:
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建议始终加上,防止代理不可用时程序无限挂起。这里最容易误解的是
"https"这个键——它表示“访问HTTPS URL时使用哪个代理”,不代表代理服务器本身一定要用https://连接。很多HTTP代理访问HTTPS站点时通过CONNECT方法建立隧道,所以代理地址仍然可能是http://。
验证代理是否生效:访问httpbin.org/ip会返回请求来源IP。如果返回的IP与本地公网IP不同,说明代理已生效。
r = requests.get("https://httpbin.org/ip", proxies=proxies, timeout=10)
print("当前出口IP:", r.json()["origin"])
二、带身份认证的代理
商业代理服务通常需要用户名和密码认证。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}",
}
特殊字符处理:如果用户名或密码包含@、:等特殊字符,需要使用urllib.parse.quote()进行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"
三、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解析位置 |
|---|---|
socks5:// |
由本地客户端解析 |
socks5h:// |
交给代理端解析 |
如果希望目标域名由代理端解析,通常应使用socks5h://。
带认证的SOCKS5代理写法:
proxies = {
"http": "socks5h://username:password@proxy_ip:1080",
"https": "socks5h://username:password@proxy_ip:1080",
}
四、通过环境变量配置代理(全局生效)
除了在代码中显式传递proxies参数,requests默认也会读取系统环境变量中的代理配置:
Linux/macOS:
export HTTP_PROXY="http://10.10.1.10:3128" export HTTPS_PROXY="http://10.10.1.10:3128" python your_script.py
Windows (CMD):
set HTTP_PROXY=http://10.10.1.10:3128 set HTTPS_PROXY=http://10.10.1.10:3128 python your_script.py
在Python代码中设置:
import os
import requests
os.environ['http_proxy'] = 'http://127.0.0.1:8080'
os.environ['https_proxy'] = 'http://127.0.0.1:8080'
response = requests.get('https://httpbin.org/ip')
requests同时支持大小写变体(HTTP_PROXY和http_proxy),小写优先。
五、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适合连续请求,但出口是否变化取决于代理服务本身的调度规则。
六、代理轮换:应对高频请求
当需要大量请求时,单个IP容易被限制。以下是一个简单的代理轮换实现:
import random
import requests
# 代理列表(从代理API获取或手动配置)
proxy_list = [
"http://user:pass@ip1:port",
"http://user:pass@ip2:port",
"http://user:pass@ip3:port",
]
def get_random_proxy():
proxy = random.choice(proxy_list)
return {"http": proxy, "https": proxy}
# 每次请求随机选择一个代理
for i in range(10):
proxies = get_random_proxy()
try:
response = requests.get(
"https://httpbin.org/ip",
proxies=proxies,
timeout=(5, 10)
)
print(f"请求{i+1} 出口IP: {response.json()['origin']}")
except Exception as e:
print(f"请求{i+1} 失败: {e}")
更完善的方案是从代理服务商的API动态获取代理IP池,并结合有效性校验自动剔除失效IP。
七、超时参数:别再只写一个数字
不要只写timeout=30。更建议使用二元组:
# 连接超时5秒,读取超时15秒 timeout=(5, 15)
连接超时:如果连接阶段就超时,通常要检查代理地址、端口、认证和链路
读取超时:如果读取阶段超时,说明连接已经建立,但目标响应或中间链路过慢
八、常见踩坑与解决方案
坑1:只配置了单协议
问题:只配置了"http"而没有配置"https",访问HTTPS网站时请求直接走本地IP,代理未生效。
解决:必须同时填写http和https两个键。
proxies = {
"http": "http://proxy:8080",
"https": "http://proxy:8080", # 两个都要!
}
坑2:curl能通但requests不通
问题:代理链路本身没问题,但curl -x能通而Python requests不通。
原因:curl和requests在五个维度上行为不同——默认请求头、CA证书库、环境变量读取规则、凭据编码方式和TLS指纹。
最常见的解决:修改User-Agent。requests默认会带python-requests/2.31.0这个UA,被大量站点直接列入拦截规则:
session = requests.Session()
session.headers.update({
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"Accept-Language": "zh-CN,zh;q=0.9",
})
坑3:407 Proxy Authentication Required
问题:代理服务器收到了请求,但认证信息不正确或根本没有带认证信息。
排查步骤:
确认账号密码是否正确
确认账号密码是否包含特殊字符(如
@、:),如有则需URL编码确认
http与https两个代理配置项是否都补齐
坑4:代理失效导致程序卡死
解决:始终添加timeout参数。
response = requests.get(url, proxies=proxies, timeout=(5, 15))
九、实战:从代理API获取IP并轮换
结合前面所学,以下是一个完整的实战示例——从代理服务商API获取代理IP列表,然后轮换使用:
import requests
import random
import time
# 1. 从代理API获取IP列表(以实际服务商API地址为准)
PROXY_API_URL = "https://api.proxy provider.com/get_proxy" # 替换为实际API
def fetch_proxies_from_api():
"""从代理API获取一批代理IP"""
try:
resp = requests.get(PROXY_API_URL, timeout=10)
data = resp.json()
# 假设API返回格式为 {"proxies": ["http://user:pass@ip:port", ...]}
return data.get("proxies", [])
except Exception as e:
print(f"获取代理失败: {e}")
return []
# 2. 轮换使用代理
def fetch_with_proxy_rotation(url, max_retries=3):
proxies_list = fetch_proxies_from_api()
if not proxies_list:
print("没有可用代理")
return None
for attempt in range(max_retries):
proxy = random.choice(proxies_list)
proxies = {"http": proxy, "https": proxy}
try:
response = requests.get(
url,
proxies=proxies,
timeout=(5, 15),
headers={"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"}
)
if response.status_code == 200:
return response
else:
print(f"状态码异常: {response.status_code}, 尝试下一个代理")
except Exception as e:
print(f"代理 {proxy} 失败: {e}")
continue
return None
# 使用
result = fetch_with_proxy_rotation("https://httpbin.org/ip")
if result:
print(result.json())
十、总结
| 场景 | 推荐配置 |
|---|---|
| 基础代理 | proxies={"http": "http://ip:port", "https": "http://ip:port"} |
| 认证代理 | proxies={"http": "http://user:pass@ip:port", ...} |
| SOCKS5代理 | pip install requests[socks]+socks5h://... |
| 全局代理 | 设置HTTP_PROXY/HTTPS_PROXY环境变量 |
| 连续请求 | 使用requests.Session()复用 |
| 高频请求 | 代理轮换 + 超时控制 + 异常重试 |
在正式使用前,建议先通过各代理平台提供的免费测试服务验证IP质量和稳定性,再投入生产环境。
关键词标签:Python requests设置代理,requests代理教程,Python爬虫代理IP,SOCKS5代理Python,requests认证代理,代理IP轮换Python,requests环境变量代理,Python代理踩坑
📌 相关资源导航
全网低价IP官网:https://socks5ip.com.cn
价格中心(免费测试):https://socks5ip.com.cn/jiagezhongxin
代理工具中心(配置教程):https://socks5ip.com.cn/dailigongjuzhongxin
客服微信:17720135827 |QQ:878989347
Slogan:全网低价IP | 专业代理IP资源平台,聚合注册中心


