Python Requests 프록시 가이드: 구문, 인증, 회전, 재시도

프록시 딕셔너리는 세 줄의 코드지만, Requests에서의 프록시 오류는 10년간 Stack Overflow를 채웠습니다. 여기 전체 설정 — 구문, 인증, 환경 변수, 회전, 재시도 및 SOCKS5 — 날카로운 모서리가 표시되어 있습니다.

Python Requests는 여전히 스크래핑 및 자동화의 기본 HTTP 클라이언트이며, 프록시에 지시하는 것은 세 줄의 작업입니다: proxies 딕셔너리를 전달하면 모든 요청이 귀하의 IP 대신 프록시의 IP에서 종료됩니다. 그러나 'python requests proxy 작동하지 않음'은 10년 넘게 상위 검색어로 남아 있습니다 — proxies 딕셔너리에 대한 원래 Stack Overflow 질문은 2011년으로 거슬러 올라가며, 상위 답변은 480개 이상의 투표를 받았고 2026년 1월에도 여전히 수정되고 있었습니다. 구문에는 날카로운 모서리가 있습니다: 누락된 스키마는 예외를 발생시키고, https 키 내부의 잘못된 스키마는 SSL 오류를 유발하며, 환경 변수는 코드를 조용히 무시합니다. 이 Python Requests 프록시 가이드는 모든 것을 다룹니다: 구문, 인증, 환경 변수, 회전, 재시도, SOCKS5 및 실제로 발생할 오류들.

프록시 딕셔너리: Python Requests 프록시 구문

proxies 인수는 프로토콜을 프록시 URL에 매핑합니다. 일반적인 스크래핑을 위해 두 개의 키가 필요합니다 — 하나는 일반 HTTP 대상용, 하나는 HTTPS 대상용 — 그리고 둘 다 일반적으로 동일한 프록시를 가리킵니다:

import requests

proxies = {
    "http": "http://USER:PASS@gate.quantumproxies.io:PORT",
    "https": "http://USER:PASS@gate.quantumproxies.io:PORT",
}

r = requests.get("https://httpbin.org/ip", proxies=proxies, timeout=(5, 30))
print(r.json())  # {'origin': '<proxy exit IP>'}

세 가지 규칙은 90%의 설정 실패를 방지합니다:

프록시 인증: 사용자 이름과 비밀번호

인증된 프록시는 URL에 포함된 HTTP 기본 인증을 사용합니다: http://USER:PASS@host:port. 비밀번호에 @, : 또는 /가 포함된 경우, urllib.parse.quote(password, safe="")로 먼저 URL 인코딩하세요 — 인코딩되지 않은 특수 문자는 URL을 잘못된 위치에서 분할하여 죽은 프록시처럼 보이는 인증 실패를 초래합니다. 407 Proxy Authentication Required 응답은 프록시 자체가 귀하를 거부했음을 의미합니다: 잘못된 자격 증명 또는 등록되지 않은 주소에서 호출된 IP 화이트리스트 계획. 두 경우 모두 407 문제 해결 가이드에서 해부됩니다. 일회성 스크립트를 넘어서는 경우, 프록시를 Session에 첨부하세요 — 연결 풀링, 쿠키 지속성 및 모든 것을 구성할 수 있는 한 장소를 얻을 수 있습니다.

import requests

session = requests.Session()
session.proxies = {
    "http": "http://USER:PASS@gate.quantumproxies.io:PORT",
    "https": "http://USER:PASS@gate.quantumproxies.io:PORT",
}
session.headers.update({"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"})

r = session.get("https://httpbin.org/ip", timeout=(5, 30))
print(r.status_code, r.json())

환경 변수와 trust_env

Requests는 또한 환경에서 프록시 설정을 읽습니다 — curl 및 대부분의 Unix 도구가 존중하는 동일한 변수들: HTTP_PROXY, HTTPS_PROXY, ALL_PROXYNO_PROXY (제외할 호스트의 쉼표 목록, 예: localhost,127.0.0.1,.internal). 이는 Requests를 내부적으로 사용하는 타사 라이브러리를 코드에 손대지 않고 프록시하는 가장 깔끔한 방법입니다. 우선 순위는 명시적이 암시적을 이깁니다: 호출 시 proxies= 인수가 승리하고, 그 다음은 session.proxies, 그 다음은 환경입니다. 관련 도구 두 가지는 알아둘 가치가 있습니다: session.trust_env = False는 모든 환경 조회를 끕니다 — 회사 프록시 변수가 스크래퍼를 납치할 때의 해결책입니다 — 그리고 urllib.request.getproxies()는 Requests가 기대하는 딕셔너리 형태로 OS 수준의 프록시 설정을 반환합니다 (macOS 및 Windows 시스템 구성 포함).

Python Requests 프록시 흐름의 다이어그램: proxies 딕셔너리는 각 요청을 회전하는 게이트웨이 CONNECT 터널을 통해 대상 사이트로 라우팅합니다
딕셔너리는 경로를 선택하고, 게이트웨이는 종료 IP를 제공합니다. 요청별 회전으로, 동일한 두 줄의 구성으로 매 호출마다 새로운 IP를 얻을 수 있습니다.

회전: 하나의 게이트웨이가 프록시 목록을 이깁니다

전통적인 회전 레시피 — IP 목록을 로드하고, 요청별로 random.choice()를 사용하고, 죽은 것을 제거하는 — 더 이상 구축할 필요가 없는 기계입니다. 회전 게이트웨이는 서버 측에서 이를 수행합니다: 하나의 엔드포인트를 구성하면 공급자가 매 요청마다 풀에서 새로운 종료 IP를 할당합니다. 회전 주거 프록시를 통해 그 풀은 200개 이상의 국가에 걸쳐 90M+ 가구 IP로 구성되어 있어, 천 개의 요청이 천 개의 다른 방문자로 보입니다, 회전 로직 한 줄 없이:

import requests

proxies = {
    "http": "http://USER:PASS@gate.quantumproxies.io:PORT",
    "https": "http://USER:PASS@gate.quantumproxies.io:PORT",
}

for _ in range(3):
    r = requests.get("https://httpbin.org/ip", proxies=proxies, timeout=(5, 30))
    print(r.json()["origin"])  # a different exit IP on each iteration

흐름이 여러 요청에 걸쳐 있을 때 — 로그인, 장바구니 추가, 결제 — 요청별 회전은 세션을 깨뜨립니다. 스티키 세션이 이를 해결합니다: 프록시 사용자 이름의 세션 매개변수가 설정된 창 동안 하나의 종료 IP를 고정한 다음 회전합니다. 동일한 엔드포인트, 문자열 하나의 변경. 간단한 루프를 넘어서 확장하는 경우, httpx 또는 aiohttp를 사용한 비동기 Python이 처리량을 곱하고, Scrapy의 미들웨어 시스템은 회전, 재시도 및 차단 처리를 프레임워크 구성으로 제공합니다.

나쁜 종료를 견디는 재시도 및 시간 초과

프리미엄 풀조차도 때때로 느리거나 죽어가는 종료를 제공합니다, 따라서 프로덕션 코드는 두 가지 보호 장치가 필요합니다: 각 요청에 대한 시간 초과 (Requests는 기본적으로 영원히 기다립니다) 및 백오프가 있는 자동 재시도. 시간 초과는 (connect, read) 튜플을 사용합니다 — 도달할 수 없는 프록시에 대해 빠르게 실패하고, 느린 페이지 읽기를 허용합니다. 재시도는 urllib3를 통해 전송 계층에서 마운트됩니다:

import requests
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry

retry = Retry(
    total=4,
    backoff_factor=1,  # exponential backoff between attempts
    status_forcelist=[429, 500, 502, 503, 504],
    allowed_methods=["GET", "HEAD"],
)

session = requests.Session()
session.mount("http://", HTTPAdapter(max_retries=retry))
session.mount("https://", HTTPAdapter(max_retries=retry))
session.proxies = {
    "http": "http://USER:PASS@gate.quantumproxies.io:PORT",
    "https": "http://USER:PASS@gate.quantumproxies.io:PORT",
}

r = session.get("https://httpbin.org/ip", timeout=(5, 30))

회전 게이트웨이와 함께 이 조합은 조용히 강력합니다: 각 재시도는 자동으로 다른 종료 IP를 통해 이동하므로, 하나의 불안정한 주소가 연속으로 네 번 요청을 실패하게 할 수 없습니다.

Requests와 함께하는 SOCKS5 프록시

SOCKS 지원은 추가 기능입니다: pip install requests[socks]로 설치하세요. 그런 다음 딕셔너리 구문은 동일합니다 — 스키마만 변경됩니다. socks5h://socks5://보다 선호하세요: h는 DNS 해석을 프록시로 밀어내어, 실제 네트워크에서의 DNS 누출을 방지하고 종료 위치에서 지리적으로 제한된 호스트 이름을 해석합니다. 모든 QuantumProxies 계획은 동일한 게이트웨이에서 HTTP와 SOCKS5 프록시를 모두 노출하므로, 프로토콜 전환은 스키마 교체이지 새로운 구매가 아닙니다:

proxies = {
    "http": "socks5h://USER:PASS@gate.quantumproxies.io:PORT",
    "https": "socks5h://USER:PASS@gate.quantumproxies.io:PORT",
}
작동하는 Python Requests 프록시 구성을 다섯 가지 일반적인 실수와 비교한 체크리스트
다섯 가지 실수가 대부분의 실패를 유발합니다: 누락된 스키마, https 키에 https://, 인코딩되지 않은 비밀번호, 누락된 SOCKS 추가 기능, 그리고 시간 초과 없음.

일반적인 Python Requests 프록시 오류, 해독됨

스택 추적과 그 근본 원인을 더 깊이 탐색하려면, Requests에서 ProxyError, SSLError 및 ConnectTimeout 디버깅을 참조하세요.

자주 묻는 질문

Python Requests에서 프록시를 어떻게 사용하나요?

httphttps 키가 포함된 proxies 딕셔너리를 모든 요청 메서드에 전달하세요: requests.get(url, proxies={...}). 각 값은 스키마를 포함한 전체 프록시 URL이며, 자격 증명은 http://user:pass@host:port로 포함됩니다. 동일한 딕셔너리를 Session에 첨부하여 모든 요청에 자동으로 적용하세요.

왜 내 Python Requests 프록시가 작동하지 않나요?

네 가지 일반적인 용의자를 순서대로 확인하세요: 프록시 URL에 http:// 스키마가 누락된 경우, https 키 내부에 https://가 사용된 경우, URL 인코딩되지 않은 비밀번호의 특수 문자, 그리고 코드보다 환경 변수가 우선하는 경우. 동일한 자격 증명을 curl로 테스트하세요 — curl이 성공하면 문제는 딕셔너리에 있습니다.

Python Requests는 SOCKS5 프록시를 지원하나요?

예, 추가 종속성을 pip install requests[socks]로 설치한 후 지원합니다. socks5h:// 스키마를 proxies 딕셔너리에 사용하여 DNS 해석이 프록시 측에서 이루어지도록 하세요 — 일반 socks5:// 스키마는 로컬에서 호스트 이름을 해석하여 DNS 쿼리를 누출하고 지리적으로 타겟팅된 스크래핑을 방해할 수 있습니다.

환경 변수로 프록시를 어떻게 설정하나요?

전체 프록시 URL로 HTTP_PROXYHTTPS_PROXY를 내보내고, 선택적으로 제외할 호스트에 대해 NO_PROXY를 설정하세요. Requests는 이를 자동으로 감지하여, Requests를 기반으로 구축된 타사 라이브러리도 프록시합니다. 코드가 환경을 완전히 무시하도록 하려면, session.trust_env = False를 설정하세요.

그것이 전체 도구 키트입니다: 두 개의 키 딕셔너리, URL에 자격 증명, 한 번 마운트된 재시도, 그리고 코드 대신 게이트웨이에서 처리되는 회전. 구문으로 해결할 수 없는 한 가지는 IP 품질입니다 — 완벽하게 구성된 데이터센터 프록시도 주거 종료가 통과할 때 차단됩니다. 깨끗한 코드와 깨끗한 IP를 결합하면 Requests는 놀랍도록 큰 작업량을 처리할 것입니다.

첫 시도에 작동하는 주거 프록시를 얻으세요