在Python企业级应用或网络请求开发中,使用代理是实现网络路由规划、统一网关接入和安全审计的常用手段。虽然第三方库如 requests 提供了极其简便的代理配置接口,但在某些对依赖控制严格的环境下,掌握Python标准库 urllib 和 http.client 的代理配置方法就显得尤为重要。
本文将深入探讨如何使用这两个标准库配置 HTTP 和 HTTPS 代理。
urllib.request 配置代理urllib.request 是 Python 提供的一个高级网络请求库。配置代理最正规的做法是使用 ProxyHandler,然后通过它构建一个自定义的 Opener。
import urllib.request
# 1. 定义代理服务器的地址和端口
proxy_host = '127.0.0.1:8080'
# 2. 创建一个 ProxyHandler 字典,映射协议到代理地址
proxies = {
'http': f'http://{proxy_host}',
'https': f'http://{proxy_host}' # 注意:即使是https目标,代理服务器地址通常也是 http:// 开头
}
proxy_handler = urllib.request.ProxyHandler(proxies)
# 3. 创建自定义的 opener
opener = urllib.request.build_opener(proxy_handler)
# 4. 可选:将这个 opener 安装为全局默认,之后直接调用 urllib.request.urlopen 也生效
# urllib.request.install_opener(opener)
# 5. 发起请求
url = 'http://httpbin.org/ip'
try:
response = opener.open(url, timeout=10)
print(response.read().decode('utf-8'))
except urllib.error.URLError as e:
print(f"请求失败: {e}")许多企业级代理网关需要进行身份安全认证。由于 ProxyHandler 支持在 URL 中嵌入账密,因此配置起来十分直观:
import urllib.request
username = 'your_username'
password = 'your_password'
proxy_host = '127.0.0.1:8080'
# 代理 URL 格式:http://username:password@ip:port
proxy_url = f'http://{username}:{password}@{proxy_host}'
proxies = {
'http': proxy_url,
'https': proxy_url
}
proxy_handler = urllib.request.ProxyHandler(proxies)
opener = urllib.request.build_opener(proxy_handler)
response = opener.open('http://httpbin.org/ip')
print(response.read().decode('utf-8'))http.client 配置代理相比 urllib,http.client 是一个更底层的库(实际上 urllib 底层也是调用的它)。在 http.client 中配置代理,你需要了解 HTTP 代理的工作原理:
import http.client
proxy_host = '127.0.0.1'
proxy_port = 8080
target_url = "http://httpbin.org/ip"
# 1. 连接到代理服务器,而不是目标服务器
conn = http.client.HTTPConnection(proxy_host, proxy_port)
# 2. 发起请求时,路径部分必须是完整的绝对 URL (Absolute URL)
conn.request("GET", target_url)
# 3. 获取响应
response = conn.getresponse()
print("Status:", response.status)
print(response.read().decode('utf-8'))
conn.close()从 Python 3.2 开始,http.client.HTTPSConnection 提供了 set_tunnel() 方法,完美解决了 HTTPS 代理的问题。
import http.client
proxy_host = '127.0.0.1'
proxy_port = 8080
target_host = 'httpbin.org'
# 1. 连接到代理服务器(如果是普通的HTTP代理服务器,这里用 HTTPConnection 即可)
# 注意:即使目标是 HTTPS,代理服务器自身通常是基于 HTTP 的,所以先建立普通的连接
conn = http.client.HTTPConnection(proxy_host, proxy_port)
# 2. 建立 CONNECT 隧道到目标服务器的 443 端口
conn.set_tunnel(target_host, 443)
# 3. 发起请求,这里的路径就变成相对路径了
conn.request("GET", "/ip")
# 4. 获取响应
response = conn.getresponse()
print("Status:", response.status)
print(response.read().decode('utf-8'))
conn.close()如果代理服务器需要认证,我们需要手动构造 Proxy-Authorization 请求头:
import http.client
import base64
proxy_host = '127.0.0.1'
proxy_port = 8080
target_host = 'httpbin.org'
# 构造 Proxy-Authorization 头
auth_str = "your_username:your_password"
auth_b64 = base64.b64encode(auth_str.encode('ascii')).decode('ascii')
headers = {
'Proxy-Authorization': f'Basic {auth_b64}'
}
conn = http.client.HTTPConnection(proxy_host, proxy_port)
# 将认证头传递给 set_tunnel
conn.set_tunnel(target_host, 443, headers=headers)
conn.request("GET", "/ip")
response = conn.getresponse()
print(response.read().decode('utf-8'))
conn.close()如果你希望代码零侵入,Python 的 urllib 默认会读取系统的环境变量(如 HTTP_PROXY, HTTPS_PROXY):
# 在 Linux / macOS 终端中
export HTTP_PROXY="http://127.0.0.1:8080"
export HTTPS_PROXY="http://127.0.0.1:8080"
export NO_PROXY="localhost,127.0.0.1" # 配置不走代理的局域网域名当配置了上述环境变量后,即使代码中只写了最简单的 urllib.request.urlopen("http://httpbin.org/ip"),请求也会自动通过代理发出。
特性 |
|
|
|---|---|---|
抽象层级 | 高级,使用 | 低层,需手动管理连接和隧道 |
易用性 | 极高,代码少,逻辑清晰 | 较低,需要理解 HTTP CONNECT 原理 |
HTTPS代理 | 自动处理隧道搭建 | 需手动调用 |
身份认证 | 支持直接将账密写在 URL 中 | 需手动构造 |
适用场景 | 绝大多数数据请求、内网服务集成 | 需深度控制 HTTP 协议细节、定制长连接池底层等 |
在日常开发中,强烈建议首选 urllib.request 的方式进行代理配置,它能帮你隐藏底层繁琐的协议细节,使得代码更加健壮。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。