プロジェクトでRequestsを利用できる状態なら、呼び出しにプロキシのマッピングを渡します。

import requests

proxies = {
    "http": "http://127.0.0.1:8080",
    "https": "http://127.0.0.1:8080",
}

response = requests.get(
    "https://example.com/",
    proxies=proxies,
    timeout=(5, 15),
)
response.raise_for_status()
print(response.status_code)

ループバックの接続先を、稼働中のプロキシか、このリクエストで試すHTTPプロキシ一覧の候補に置き換えてください。キーが表すのは宛先のスキームです。http はHTTPのURL、https はHTTPSのURLに対応します。値はプロキシの待受を表します。ネットワークが別経路を要求する場合は、異なる接続先でも構いません。

http:// のプロキシ値を https キーの下に置くのは意図的です。RequestsはHTTP待受にCONNECTトンネルを要求し、そこを通して宛先とのTLSを確立します。プロキシの宛先・ポートポリシーには従います。値を https:// にするとプロキシ自体へのTLSを要求するため、待受が平文HTTPを想定していれば失敗することがあります。

二つのタイムアウト値が意味するもの

timeout=(5, 15) は接続と読み取りのタイムアウトを設定します。全体を十五秒で打ち切る設定ではありません。定期的なデータ受信、複数アドレスや接続試行によって経過時間は延びることがあります。設定を省略するとRequestsは一般的なタイムアウトを設けないため、応答に合う上限を選び、厳密な総時間の予算が必要ならアプリケーション側に締め切りを追加してください。

失敗が発生した段階で対処する

try:
    response = requests.get(
        "https://example.com/",
        proxies=proxies,
        timeout=(5, 15),
    )
    response.raise_for_status()
except requests.exceptions.ProxyError as error:
    print("Proxy setup failed:", type(error).__name__)
except requests.exceptions.Timeout:
    print("A configured timeout expired")
except requests.exceptions.HTTPError as error:
    print("HTTP status:", error.response.status_code)

CONNECTが拒否されると、宛先の応答が存在する前に ProxyError が発生することがあります。HTTPError 分岐はエラーステータスの応答を受信した後、Timeout は設定した上限の期限切れを意味します。接続確立時の例外チェーンはローカルで調べ、共有前に認証情報入りの接続先や非公開URLを取り除いてください。

証明書検証は有効のままにします。認可されたネットワークでプライベートCAや管理下の通信傍受を使う場合は、検証を無効にせず、想定された信頼用の資料を指定してください。

明示したリクエスト単位の項目は、ここで渡した経路を制御します。ただし省略したスキームは、環境からのプロキシ検出の影響を受ける場合があります。再利用するSessionに呼び出しを移す際は、環境変数、Sessionの既定値、リクエスト単位の上書きをどう組み合わせるかを決めます。接続再利用と経路ポリシーは別々の選択です。

関連記事