一つの 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 プロキシ一覧から候補を選んでプロキシ接続を比較します。サービスが許可していれば、HTTPS の接続先にはCONNECT 経由で到達できます。待ち受け側のプロトコルと認証への対応がハンドラーに合っていることを確認してください。

デフォルトの opener は変更しない

経路を担当するオブジェクトを通じて direct.open または proxied.open を呼び出します。install_opener は urllib の簡易関数が使うプロセス全体のデフォルトを変更するため、ライブラリ内で使うと無関係なコードにも影響します。上記の独立した opener には不要です。

timeout 引数は操作の設定であり、各転送全体の実経過時間を制限する期限ではありません。読み取りは処理に必要なデータに絞り、総時間に厳密な制約があるなら、より上位の仕組みで期限を設けてください。

これらの opener オブジェクトは、別のライブラリのクライアント、既存のプロセス、ブラウザーのプロキシ設定を変更しません。

関連記事