일상적인 온라인 데이터 관리 및 웹 스크래핑 과정에서 오류가 있는 프록시 메시지를 접하는 것은 흔한 일입니다. 이러한 오류 코드는 프록시 관련 데이터 전달 문제의 중요한 지표이며, 문제 진단 및 해결에 핵심적인 역할을 합니다.
본 문서에서는 다양한 유형의 HTTP 프록시 오류 코드를 설명하며, 각 유형별 해석과 일반적으로 발생하는 상황을 다룹니다.
프록시 오류 코드
서버 다운타임이나 설정 불일치 등 다양한 이유로 프록시 오류가 발생할 수 있습니다. 이러한 세부 사항을 이해하면 문제의 원인을 파악하고 해결하기가 더 쉬워집니다.
다음 섹션에서는 다양한 프록시 코드와 효과적인 문제 해결 및 해결 방법을 알아보겠습니다.
3xx 코드: 리다이렉트
HTTP 3xx 상태 코드는 리디렉션을 나타내며, 사용자 에이전트가 요청을 완료하기 위해 추가 단계를 수행해야 함을 의미합니다. 일반적으로 이 코드는 편집 변경이나 웹사이트 재구축으로 인해 새로운 URL로 이동 중임을 시사합니다.
웹 스크래핑에서는 정확하고 효과적인 데이터 수집을 유지하기 위해 이러한 리디렉션을 처리해야 합니다.
301: 영구적으로 이동됨
301 오류를 받으면 찾고 있는 리소스가 영구적으로 이동된 것입니다. 이는 웹사이트가 리디자인이나 콘텐츠 재구성 같은 업데이트를 진행할 때 자주 발생합니다.
이 오류가 발생하면 스크레이퍼는 응답 헤더에서 제공되는 새 위치로 URL 참조를 전환해야 합니다:
response_data = requests.get('http://example.com/old-page')
if response_data.status_code == 301:
new_redirect_url = response_data.headers['Location']
response_data = requests.get(new_redirect_url)
이 코드에서는 스크래퍼가 헤더에서 오는 리다이렉트 위치를 가져오도록 지시합니다. 그런 다음 새 위치에서 콘텐츠에 접근합니다:

302: 발견됨 (임시 리다이렉트)
302 Found 상태 코드는 접근하려는 리소스가 일시적으로 다른 URL로 이동되었음을 나타냅니다. 이 경우 변경은 영구적이지 않으며, 원본 URL은 언젠가 다시 사용 가능해질 것으로 예상됩니다. 이는 웹사이트가 유지보수 중인 경우에 자주 발생합니다.
웹 스크래핑 시 리디렉션을 자동으로 처리하도록 스크립트를 구성하여 저장된 URL이 변경되지 않도록 하는 것이 중요합니다. Python requests와 같은 많은 HTTP 라이브러리가 302 리디렉션을 자동으로 처리하지만, 특히 원본 요청 메서드를 보존해야 하는 경우 이 동작이 스크래핑 목표와 일치하는지 확인하는 것이 중요합니다:

304: Not Modified
접속하려는 콘텐츠가 마지막으로 확인된 요청 이후 업데이트되지 않았다면 304 에러를 받게 됩니다. 이 에러는 불필요한 데이터 다운로드를 방지하여 웹 스크래핑 작업의 효율성을 높이는 데 도움이 됩니다.
스크레이퍼가 이미 다운로드된 페이지에 접근할 경우, If-Modified-Since 또는 If-None-Match와 같은 요청 헤더를 사용하여 콘텐츠가 변경되지 않았는지 확인할 수 있습니다:
import requests
# 올바른 헤더 형식 및 Python 구문
headers = {'If-Modified-Since': 'Sat, Oct 29 2024 19:43:31 GMT'}
# 헤더를 포함한 서버에 대한 GET 요청 수행
response = requests.get('http://example.com/page', headers=headers)
# 반환된 상태 코드가 304인지 확인
if response.status_code == 304:
print("콘텐츠가 변경되지 않았습니다.")
이 코드에서는 먼저 응답 코드가 304인지 테스트합니다. true인 경우 '콘텐츠가 변경되지 않았습니다.'라는 메시지를 출력하고, 아무 작업도 수행할 필요가 없습니다:

307: 임시 리다이렉트
임시 리디렉션(상태 코드 307)은 접근하려는 리소스가 일시적으로 다른 URL로 이동되었음을 알려줍니다. 이 경우 원래 요청의 HTTP 메서드와 본문을 리디렉션된 URL에 그대로 재사용할 수 있습니다. 이는 리디렉션된 URL이 다른 메서드와 본문을 사용할 수 있는 302와 다릅니다:
response = requests.post('http://examples.com/submit-form', data={'key': 'value'} )
if response.status_code == 307:
response = requests.post(response.headers['Location'], data={'key': 'value'})
웹 크롤러를 리다이렉트할 때는 순서를 유지해야 합니다. 이는 대상 웹사이트의 구조와 서버 시스템을 존중하면서 안정적이고 효과적인 데이터 수집을 보장하는 데 도움이 됩니다. 다음 코드는 응답 상태가 307인지 확인합니다. true인 경우, 응답 헤더에 지정된 새 Location으로 본문의 동일한 데이터를 재전송합니다:

4xx 코드: 클라이언트 측 오류
클라이언트 측 오류는 4xx 범위의 HTTP 상태 코드로 표시되며, 일반적으로 클라이언트가 수행한 요청의 문제로 인해 발생합니다. 이러한 오류는 종종 요청 매개변수의 수정이나 인증 메커니즘의 운영적 개선으로 해결됩니다.
400: 잘못된 요청
400 잘못된 요청 오류는 서버가 요청을 이해하지 못했음을 나타냅니다. 웹 스크래핑에서는 일반적으로 요청 헤더가 올바르게 작성되지 않았거나 일부가 누락된 경우 발생합니다.
예를 들어, 의도치 않게 잘못된 형식(예: JSON 대신 텍스트 전송)으로 정보를 전송하면 서버가 요청을 처리하지 못하고 거부합니다. 이 문제를 해결하려면 신중하게 유효성 검사를 수행하고 요청 구문이 서버의 기대에 부합하는지 확인해야 합니다.
웹 스크래핑에서 요청이 서버의 기대에 부합하는지 확인하기 위해 완료해야 할 몇 가지 단계가 있습니다. 먼저 대상 웹사이트의 구조를 이해해야 합니다. 브라우저 개발자 도구를 사용하여 요소를 검사하고 데이터가 어떻게 포맷되는지 파악할 수 있습니다. 또한 테스트 및 오류 처리를 구현하고 요청에 적절한 헤더를 사용해야 합니다:

401: Unauthorized
401 Unauthorized오류는 리소스 접근에 필요한 인증이 실패했거나 누락되었음을 나타냅니다. 웹 스크래핑에서 이는 인증된 콘텐츠에 접근할 때 흔히 발생합니다. 예를 들어, 잘못된 자격 증명으로 구독 기반 데이터에 접근하면 이 오류가 발생합니다. 이를 방지하려면 요청에 올바른 인증 헤더를 포함해야 합니다:

403: 접근 금지
403 Forbidden오류는 서버가 요청을 이해했지만 리소스 접근을 허용하지 않았음을 의미합니다. 접근 제어가 엄격한 웹사이트를 스크래핑할 때 흔히 발생합니다. 웹사이트의 접근 금지 영역에 진입할 때 이 오류가 자주 발생합니다. 예를 들어, 특정 사용자로 인증된 상태에서 다른 사용자의 게시물을 접근하려는 경우 권한이 없어 접근이 불가능합니다:

403 오류를 받으면 키나 자격 증명을 확인하여 인증을 검증하세요. 인증이 불가능하고 유효한 자격 증명이 없다면, 웹사이트의 접근 정책을 준수하기 위해 해당 콘텐츠의 스크래핑을 자제하는 것이 좋습니다.
404: Not Found
서버가 요청된 리소스를 찾을 수 없을 때 404 Not Found 오류를 반환합니다.
이는 웹 스크래핑에 사용된 URL이 변경되거나 손상된 경우(예: 제품 페이지 삭제 또는 리디렉션/업데이트 없이 URL 변경)에 자주 발생합니다.
이 문제를 해결하려면 스크래핑 스크립트의 URL을 확인하고 필요에 따라 현재 웹사이트 구조에 맞게 업데이트하십시오.

코드에서 404 오류를 처리하는 것이 항상 권장됩니다.
Python을 사용 중이고 서버가 리소스를 찾지 못한 경우, 오류 발생 시 코드가 중단되지 않도록 다음 코드 블록을 통과하도록 지시할 수 있습니다:
import requests
# 가져올 URL 목록
urls = [
"http://example.com/nonexistentpage.html", # 404 발생 예상
"http://example.com" # 성공 예상
]
for url in urls:
try:
response = requests.get(url)
if response.status_code == 404:
print(f"Error 404: URL not found: {url}")
# 목록의 다음 URL로 진행
continue
print(f"Successfully retrieved data from {url}")
print(response.text[:200]) # 응답 내용의 첫 200자 출력
except requests.exceptions.RequestException as e:
print(f"{url} 가져오기 중 오류 발생: {e}")
continue # 요청 예외 발생 시에도 다음 URL로 진행
print("모든 URL 처리 완료.")
다음 코드에서는 URL 배열을 반복 처리하며 페이지 콘텐츠를 가져오려 시도합니다. 400 오류로 실패할 경우, 코드는 배열의 다음 URL로 진행합니다.
407: 프록시 인증 필요
407 프록시 인증 필요오류는 클라이언트가 요청을 진행하기 위해 프록시 서버에 인증해야 할 때 발생합니다. 이 오류는 프록시 서버가 인증을 요구하는 웹 스크래핑 과정에서 흔히 발생합니다. 이는 대상 웹사이트 관련 데이터 접근 시 인증이 필요한401오류와는 다릅니다.
예를 들어, 대상 웹사이트의 데이터에 접근하기 위해 프라이빗 프록시를 사용할 때 이 오류가 발생하면 인증이 되지 않은 상태입니다. 이 문제를 해결하려면 요청에 유효한 프록시 인증 정보를 추가해야 합니다:

408: 요청 시간 초과
408 요청 시간 초과상태 코드는 서버가 요청을 너무 오래 기다렸음을 나타냅니다. 이 오류는 스크레이퍼가 너무 느리거나, 특히 피크 시간대에 서버가 과부하 상태일 때 발생할 수 있습니다.
요청 타이밍을 최적화하고 지수적 백오프 메커니즘으로 재시도를 구현하면 서버가 응답할 충분한 시간을 확보하여 이 문제를 최소화할 수 있습니다:

429: 요청 초과
429 요청 과다오류는 사용자가 짧은 시간 내에 너무 많은 요청을 보냈을 때 발생합니다. 이는 웹사이트의 스크래핑 속도 제한을 초과할 때 흔히 발생하는 현상입니다. 예를 들어, 웹사이트를 자주 쿼리하면 속도 제한이 활성화되어 데이터 스크래핑이 차단됩니다.
대상 웹사이트 API 속도 제한을 준수하고 요청 지연과 같은 스크래핑 모범 사례를 적용하여 이 문제를 방지하고 필요한 리소스에 대한 접근을 유지하세요:

5xx 코드: 서버 측 문제
5xx 시리즈 HTTP 상태 코드는 서버 측 문제를 나타내며, 내부 문제로 인해 서버가 요청을 처리할 수 없음을 의미합니다. 웹 스크래핑에서 이러한 오류는 클라이언트 측 오류 처리와 다른 접근 방식이 필요한 경우가 많으므로 반드시 이해해야 합니다.
500: 내부 서버 오류
500 내부 서버 오류는 서버에서 특정 요청을 완료하지 못하게 하는 비정상적인 상황이 발생했음을 알리는 일반적인 응답입니다. 이 문제는 클라이언트의 오류가 아닌 서버 자체의 문제임을 의미합니다.
예를 들어, 데이터를 스크래핑할 때 서버의 특정 페이지에 접근하는 과정에서 이 오류가 발생할 수 있습니다. 문제를 해결하려면 나중에 다시 시도하거나, 웹 스크래핑 작업을 서버 부하가 적은 시간대(피크 시간대 외)에 수행하도록 계획하세요:

501: Not Implemented
501 Not Implemented 오류는 서버가 요청 메서드를 인식하지 못하거나 해당 메서드를 완료하지 못할 때 발생합니다. 일반적으로 크롤러의 메서드를 사전에 테스트하므로 웹 스크래핑에서 이 오류가 발생하는 경우는 드뭅니다. 다만 비표준 HTTP 메서드를 사용할 경우 발생할 수 있습니다.
예를 들어, 스크레이퍼가 서버에서 지원하지 않는 메서드(예: PUT 또는 DELETE)를 사용하도록 구성되어 있고 이러한 메서드가 웹 스크래핑 기능에 필수적인 경우 501 오류를 받게 됩니다. 이를 방지하려면 스크래핑 스크립트가 HTTP 메서드를 사용하는 경우 해당 메서드가 모든 곳에서 요구되는지 확인하세요:

502: Bad Gateway
502 Bad Gateway오류는 서버가 게이트웨이 또는 프록시 역할을 수행 중임에도 불구하고 대상 서버로부터 부적절한 응답을 받아 요청을 처리할 수 없음을 나타냅니다. 이는 중간 서버와의 통신 문제 발생을 의미합니다.
웹 스크래핑 시, 사용 중인 프록시 서버가 대상 서버로부터 적절한 응답을 받지 못할 경우 502 오류가 발생할 수 있습니다. 이를 해결하려면 프록시 서버의 상태와 구성이 정상적으로 작동하며 대상 서버와 통신할 수 있는지 확인하십시오. 프록시 서버의 CPU, 메모리, 네트워크 대역폭 사용량을 모니터링할 수 있습니다. 또한 프록시 서버의 오류 로그를 확인하여 요청 처리 시 문제가 있는지 파악할 수 있습니다:

503: 서비스 이용 불가
503 서비스 이용 불가오류는 서버가 바빠 요청을 처리할 수 없음을 나타냅니다. 이는 서버 유지보수 또는 과부하로 인해 발생할 수 있습니다.
웹 스크래핑 시 유지보수 중이거나 피크 시간대에 접근이 불가능한 사이트에 접속할 때 이 오류가 자주 발생합니다. 서버 문제를 나타내는 500 오류와 달리, 503 오류는 서버가 가동 중이지만 현재 이용 불가능함을 의미합니다.
이 오류를 방지하려면 지수적 백오프를 사용하는 재시도 전략을 구현해야 합니다. 재시도할 때마다 백오프 간격을 늘려야 합니다. 이렇게 하면 다운타임 중에도 요청이 서버 포화를 유발하지 않습니다:

504: 게이트웨이 시간 초과
504 게이트웨이 시간 초과오류는 게이트웨이 또는 프록시 역할을 하는 서버가 상위 서버로부터 제때 응답을 받지 못할 때 발생합니다. 이 오류는 시간 초과 문제이며502오류의 변형입니다.
웹 스크래핑 시 이 오류는 대상 서버가 프록시에 응답하는 속도가 너무 느릴 때(즉, 120초 이상 소요될 때) 자주 발생합니다. 해결하려면 스크래퍼의 타임아웃 설정을 조정하여 대기 시간을 늘리거나 프록시 서버의 상태 및 응답성을 확인하세요:

505: HTTP 버전 미지원
505 HTTP 버전 미지원 오류는 서버가 요청에 지정된 HTTP 프로토콜 버전을 인식하지 못할 때 발생합니다. 웹 스크래핑에서는 흔하지 않지만, 대상 서버가 특정 버전의 HTTP 프로토콜만 지원하도록 설정된 경우 발생할 수 있습니다. 예를 들어, 스크래핑 요청이 너무 최신이거나 너무 오래된 버전으로 전송되면 서버가 이를 수락하지 않습니다.
이 오류를 방지하려면 HTTP 요청 헤더에 대상 서버가 허용하는 버전을 명시해야 합니다. 가장 일반적으로 지원되는 HTTP/1.1 또는 HTTP/2 버전을 사용하는 것이 좋습니다:

일반적인 프록시 오류 방지 팁
프록시 오류는 짜증나지만, 웹 스크레이퍼에 몇 가지 특정 전략을 구현하면 많은 프록시 오류를 우회할 수 있습니다.
요청 재시도
많은 프록시 문제는 일시적인 네트워크 중단이나 서버의 사소한 장애와 같은 단기적인 문제로 인해 발생합니다. 문제가 자연스럽게 해결된 경우 요청을 재시도하면 문제를 우회할 수 있습니다.
Python의 requests 라이브러리와 urllib3 재시도 로직을 사용하여 스크래핑 스크립트에 재시도를 구현하는 방법은 다음과 같습니다:
import requests
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry
def requests_retry_session(
retries=3,
backoff_factor=0.3,
status_forcelist=(500, 502, 503, 504),
session=None,
):
session = session or requests.Session()
retry = Retry(
total=retries,
read=retries,
connect=retries,
backoff_factor=backoff_factor,
status_forcelist=status_forcelist,
)
adapter = HTTPAdapter(max_retries=retry)
session.mount('http://', adapter)
session.mount('https://', adapter)
return session
s = requests_retry_session()
try:
response = s.get('http://example.com', proxies={"http": "http://proxy_address:port"})
print(response.text)
except requests.exceptions.HTTPError as e:
print('HTTPError:', e)
이 코드는 백오프 계수를 적용한 재시도 메커니즘을 설정합니다. 즉, 요청이 실패할 경우 동일한 요청을 최대 세 번까지 재시도하며, 다음 시도 전마다 대기 시간을 점차 늘립니다.
프록시 설정 확인
잘못된 프록시 설정은 다양한 오류를 유발할 수 있습니다. 예를 들어, 프록시 포트, IP 주소 또는 인증 정보를 잘못 입력하면 이러한 오류가 발생할 수 있습니다. 요청이 목적지에 도달할 수 있도록 네트워크 요구 사항에 따라 설정이 올바른지 반드시 확인하십시오.
문서 및 지원 참조
프록시 서비스나 라이브러리 사용 중 문제가 발생하면 항상 공식 문서를 첫 번째 해결책으로 참고하십시오. 문서에서 원하는 정보를 찾을 수 없다면 해당 서비스나 라이브러리의 Slack 또는 Discord 채널이 있는지 확인하여 참여하십시오. 마지막으로 지원 채널에 티켓을 열거나 문의 사항과 세부 정보를 이메일로 보내 답변을 요청할 수 있습니다.
결론
본 글에서는 다양한 프록시 오류 코드와 그 의미를 모두 다루어, 웹 스크래핑 중 발생하는 각 오류를 식별하고 문제를 해결하는 방법을 알려드렸습니다. 또한 일반적인 오류가 발생하지 않도록 사전에 예방하는 유용한 팁도 소개했습니다.
프록시 오류로 어려움을 겪고 있다면 Bright Data의 프록시 서비스 활용을 고려해 보세요. 당사 프록시는 오류 발생 빈도를 줄여 더 효율적인 데이터 스크래핑 프로세스를 가능하게 합니다. 전문가든 초보자든 Bright Data의 프록시 도구 모음은 웹 스크래핑 역량을 강화하는 데 도움이 될 것입니다.