社内プロキシは 1 つのアカウントを要求し、その先の Web サイトは別のアカウントを要求します。Requests にはこの 2 つの Basic 認証を別々に渡す入口があります。プロキシ URL に含める資格情報と、リクエストの auth 引数です。

from urllib.parse import quote
import requests

proxy_url = (
    f"http://{quote(proxy_user, safe='')}:"
    f"{quote(proxy_password, safe='')}@proxy.example:8080"
)
response = requests.get(
    "https://reports.example/private/",
    proxies={"https": proxy_url},
    auth=(site_user, site_password),
    timeout=(5, 20),
)
response.raise_for_status()

4 つのアカウント変数はアプリケーションの資格情報設定から取得します。プロキシのユーザー名とパスワードを個別にエンコードすることで、at 記号のような文字を URL の区切り文字に変えずに保てます。

辞書の https キーは、HTTPS の接続先に対してこの経路を選びます。値が今も http:// で始まるのは、このサンプルプロキシに到達するためのプロトコルがそれだからです。

この HTTPS リクエストでは、プロキシのログインは CONNECT のやり取りに属します。サイトのログインは、確立されたトンネルを通る後続のリクエストに属します。アダプタがプロキシ認証を自身の URL から導出すれば、それは該当するホップにとどまります。この Basic のケースでは複合認証クラスは不要です。

407 は中間者の要求を示します。サイトからの 401 は接続先の要求を示します。どちらの設定済みアカウントに手当てが必要かは、その応答で判断します。

関連記事