Python urllib:为单个 opener 禁用代理
使用 ProxyHandler({}) 创建直连的 urllib opener,同时保持其他客户端和进程环境不变。
若只想让一个 urllib opener 直接连接,请向 ProxyHandler 传入空映射:
from urllib.request import ProxyHandler, build_opener
direct = build_opener(ProxyHandler({}))
with direct.open("https://example.com/", timeout=10) as response:
print(response.status)
空字典不提供任何代理路由。若省略映射,处理器则会从环境和平台设置中发现代理。这两种构造方式表达的是不同策略。
示例使用 Python 标准库,并保留正常的 HTTPS 验证。with 代码块会关闭响应,即使因异常离开代码块也一样。
在同一应用中同时使用直连和代理请求
两个 opener 可以分别承载两种策略,无须在两次调用间修改环境变量:
from urllib.request import ProxyHandler, build_opener
direct = build_opener(ProxyHandler({}))
proxied = build_opener(ProxyHandler({
"http": "http://127.0.0.1:8080",
"https": "http://127.0.0.1:8080",
}))
with proxied.open("https://example.com/", timeout=10) as response:
print(response.status)
将回环地址替换为你的 HTTP 代理,或从 HTTP 代理列表中选择候选来比较代理请求。如果服务允许,它可以通过 CONNECT承载 HTTPS 目标连接。请确保监听端的协议和认证支持与处理器匹配。
保留默认 opener
通过负责对应路由的对象调用 direct.open 或 proxied.open。install_opener 会修改 urllib 便捷调用所使用的进程级默认 opener,因此库调用它可能影响无关代码。上面隔离使用的 opener 不需要它。
timeout 参数是单项操作设置,不是每次传输从开始到结束的完整时间上限。只读取任务所需的数据;若任务有严格的总耗时预算,请使用更高层的截止时间。
这些 opener 对象不会修改其他库的客户端、已有进程或浏览器的代理设置。