在 Python Requests 库中使用代理,需要向 proxies 参数传入一个字典,把 "http"、"https" 等协议方案映射到代理服务器的 URL。这一配置让开发者可以隐藏源 IP、绕过区域封锁,并把请求分散到多个节点上以规避速率限制。在生产环境中,健壮的实现还需要处理认证、使用 SOCKS5 协议并配置基于会话的连接保持。
Requests 中的基础代理配置
requests 库通过标准的字典结构简化了代理集成。当您发起请求时,库会检查该字典以判断流量是否需要经由中间节点转发。最基础的用法就是定义代理 URL,并直接传给 get() 或 post() 方法。
import requests
proxies = {
'http': 'http://10.10.1.10:3128',
'https': 'http://10.10.1.10:1080',
}
response = requests.get('https://api.ipify.org?format=json', proxies=proxies)
print(response.json())
在这个示例中,HTTP 流量走一条路径,HTTPS 流量走另一条。如果您的代理服务器同时支持两者,两个键可以使用同一个 URL。如果您使用 GProxy 这样的服务商,通常会拿到一个网关地址,由它替您完成后端路由,字典也就简化为单一入口。
处理代理认证
多数专业代理服务都要求认证以防止未授权使用。Requests 支持在代理 URL 内直接内联基本认证,格式遵循标准的 http://user:password@host:port 语法。这是最高效的认证方式,因为它避免了额外请求头或自定义认证处理器的开销。
proxies = {
'http': 'http://user123:[email protected]:8000',
'https': 'http://user123:[email protected]:8000',
}
如果密码中含有 @、: 或 / 等特殊字符,必须进行 URL 编码。不编码这些字符会导致库错误解析 URL 结构,进而出现连接错误或 407 Proxy Authentication Required 响应。

协议差异:HTTP、HTTPS 与 SOCKS
选择哪种协议取决于具体使用场景。HTTP 代理常用于基础的网页抓取,而 SOCKS5 代理提供更底层的连接,可承载包括 UDP 和 DNS 查询在内的任意类型流量,因此更难被复杂的反爬系统识别。
要在 Requests 中使用 SOCKS5 代理,必须安装 pysocks 依赖,它并未包含在核心库中,可通过 pip install requests[socks] 安装。安装完成后配置几乎不变,只需把协议前缀改为 socks5 或 socks5h(后缀 "h" 表示由代理服务器端完成 DNS 解析,对匿名性更有利)。
| 协议 | 速度 | 匿名级别 | 最佳使用场景 |
|---|---|---|---|
| HTTP | 高 | 低到中 | 常规网页浏览、简单的 API 调用。 |
| HTTPS (SSL) | 中 | 高 | 安全数据传输、绕过深度包检测。 |
| SOCKS5 | 高 | 很高 | 抓取敏感目标、非 HTTP 流量、UDP。 |
| SOCKS5h | 高 | 最高 | 以匿名为首要目标时防止 DNS 泄露。 |
进阶会话管理与连接保持
对高性能应用来说,为每个请求新建连接效率低下。requests.Session() 对象允许您在多个请求之间保留特定参数,包括代理设置。它利用 urllib3 的连接池复用与代理服务器之间的底层 TCP 连接,可大幅降低延迟。
session = requests.Session()
session.proxies = {
'http': 'http://proxy.gproxy.com:8000',
'https': 'http://proxy.gproxy.com:8000',
}
# 之后所有使用 'session' 的请求都会使用已定义的代理
for i in range(5):
response = session.get(f'https://example.com/page/{i}')
print(f"Request {i}: {response.status_code}")
在使用支持"粘性会话"的 GProxy 住宅代理时,会话对象尤其有用。通过在代理认证字符串中传入特定的会话 ID 或令牌,您可以在设定时长内(例如 10 到 30 分钟)保持同一个 IP 地址,这对需要用户登录或多步表单提交的任务至关重要。
配置超时以保证代理稳定性
代理会在网络路径中增加一跳,自然也增加了延迟风险。若不显式设置超时,一旦某个代理节点无响应,您的 Python 脚本可能会无限期挂起。请始终定义超时元组:第一个值用于连接阶段,第二个值用于读取阶段。
# 等待 5 秒连接代理,等待 15 秒接收数据
response = requests.get('https://target.com', proxies=proxies, timeout=(5, 15))

实现代理轮换与重试
使用静态代理很容易被识别。要模拟真人行为并扩大数据采集规模,就必须轮换 IP。虽然 GProxy 提供了在其侧自动完成轮换的 back-connect 代理,但有时您仍需要在代码中管理一份具体的代理 IP 列表。
一种有韧性的实现方式是把 urllib3 的 Retry 对象集成到 Requests 的 HTTPAdapter 中。这样的配置会在遇到特定 HTTP 状态码(如 429 Too Many Requests 或 502 Bad Gateway)或连接错误时自动重试请求。
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry
proxy_list = [
"http://proxy1.gproxy.com:8000",
"http://proxy2.gproxy.com:8000",
"http://proxy3.gproxy.com:8000"
]
def get_resilient_session(proxy_url):
session = requests.Session()
retry_strategy = Retry(
total=3,
status_forcelist=[429, 500, 502, 503, 504],
allowed_methods=["HEAD", "GET", "OPTIONS"],
backoff_factor=1
)
adapter = HTTPAdapter(max_retries=retry_strategy)
session.mount("http://", adapter)
session.mount("https://", adapter)
session.proxies = {"http": proxy_url, "https": proxy_url}
return session
# 结合轮换逻辑的使用示例
import random
current_proxy = random.choice(proxy_list)
safe_session = get_resilient_session(current_proxy)
这种做法可确保临时的网络抖动或代理端限流不会让整条自动化流水线崩溃。把 GProxy 高可用的住宅 IP 池与本地重试逻辑结合起来,即便面对防护严密的目标,也能获得接近 100% 的成功率。
环境级别的代理配置
在某些部署场景中,把代理硬编码进脚本并不现实。Requests 被设计为可自动从环境变量中读取代理设置。如果代码中省略了 proxies 参数,库会查找 HTTP_PROXY、HTTPS_PROXY 和 NO_PROXY。
- HTTP_PROXY:用于 http:// 请求。
- HTTPS_PROXY:用于 https:// 请求。
- NO_PROXY:以逗号分隔的主机名列表,这些主机将绕过代理(例如 "localhost,internal.corp")。
在 Linux 或 macOS 终端中,您可以在运行脚本前设置它们:
export HTTP_PROXY="http://user:[email protected]:8000"
export HTTPS_PROXY="http://user:[email protected]:8000"
python scraper.py
这在 Docker 环境中特别有用——无需修改源代码即可在开发与生产的代理配置之间切换。请注意,在代码中显式传入 proxies 字典始终会覆盖这些环境变量。
常见代理错误排查
在 Python 中调试代理问题,关键是区分"无法连上代理"与"代理无法连上目标"这两种失败。以下是最常见的情形:
- ProxyError(Max retries exceeded):通常说明代理服务器本身宕机,或 IP/端口填写有误。请核对您的 GProxy 凭据和网关状态。
- 407 Proxy Authentication Required:您的凭据缺失、在 URL 中格式有误,或者您的 IP 地址未在 GProxy 控制台加入白名单。
- 403 Forbidden:目标网站已把该代理 IP 判定为机器人。这是一个信号,提示您改用住宅代理或提高轮换频率。
- SSLError:常见于使用拦截型代理却未正确配置证书的情况。如果您信任该代理,可以设置
verify=False,但生产环境不建议这样做。
若想更清楚地观察握手过程,可以为 Requests 内部使用的 urllib3 库启用底层日志:
import logging
import http.client
http.client.HTTPConnection.debuglevel = 1
logging.basicConfig()
logging.getLogger().setLevel(logging.DEBUG)
requests_log = logging.getLogger("requests.packages.urllib3")
requests_log.setLevel(logging.DEBUG)
requests_log.propagate = True
要点回顾
掌握 Python Requests 中的代理,是在简洁配置与健壮错误处理之间取得平衡。从基础字典进阶到基于会话的管理和自动重试,您就能构建既快速又有韧性的爬虫与自动化工具。与 GProxy 这样的高质量服务商集成,可在基础设施层面处理 IP 轮换和 geo-targeting 的复杂性,进一步简化工作。
- 使用会话:始终优先选择
requests.Session()而非逐次调用requests.get(),以享受连接池带来的性能提升。 - 设置超时:切勿让请求没有超时;在使用代理时,5 秒连接超时加 15 秒读取超时通常是安全的默认值。
- 保护您的凭据:用环境变量或
.env文件保存代理凭据,而不要硬编码进脚本,以防安全泄露。
