install_opener()을 두 번 호출해도 두 번째 opener가 첫 번째에 추가되지는 않습니다. 모듈의 기본 opener를 교체합니다. 한 객체가 프록시를 알고 다른 객체가 웹사이트 로그인을 안다면, 필요한 핸들러를 담은 단일 opener를 만드세요.

import os
from urllib.request import (ProxyHandler, HTTPBasicAuthHandler,
                            HTTPPasswordMgrWithDefaultRealm, build_opener)

passwords = HTTPPasswordMgrWithDefaultRealm()
passwords.add_password(None, 'https://example.com/private/',
                       os.environ['SITE_USER'], os.environ['SITE_PASSWORD'])
opener = build_opener(
    ProxyHandler({'https': 'http://203.0.113.10:8080'}),
    HTTPBasicAuthHandler(passwords),
)
with opener.open('https://example.com/private/report', timeout=10) as response:
    body = response.read()

프록시와 대상은 예시입니다. 공개 HTTP 프록시를 통해 도달할 수 있는 공개 서비스의 경우 HTTP 프록시 목록이 라우팅 핸들러용 후보 엔드포인트를 제공합니다. 이 opener는 HTTPS 요청을 HTTP 프록시를 통해 라우팅하고 대상의 Basic 챌린지를 처리합니다. 프록시 인증은 구성하지 않습니다.

프록시에도 로그인이 필요하다면 지원되는 프록시 인증 방식을 별도로 선택하세요. CONNECT 시점의 407은 대상이 자체 챌린지를 보내기 전에 발생합니다. 비밀번호 관리자에 웹사이트 자격 증명을 추가해도 그 이전 교환을 충족할 수 없습니다.

opener.open()을 직접 호출하면 구성이 작업과 함께 유지됩니다. 애플리케이션이 모든 편의 호출이 이 opener를 공유하기를 의도적으로 원하지 않는 한 모듈 전체 기본값을 바꿀 필요가 없습니다.

관련 글