본문 바로가기
[업무 지식]/Crawling

[HTTP 통신 오류] HTTP 상태 코드 & 파이썬에서 오류 처리하기

by 에디터 윤슬 2025. 1. 1.
상태 코드 설명
100 Continue 요청이 연결돼 있습니다.
200 OK 요청이 성공했습니다
301 Moved Permanently 요청한 리소스가 영구적으로 이동했습니다
302 Found 요청한 리소스가 일시적으로 이동했습니다.
304 Not Modified 요청한 리소스가 변경되지 않았습니다
400 Bad Request 클라리언트의 요청에 문제가 있으므로 처리할 수 없습니다
401 Unauthorized 인증되지 않았으므로 처리할 수 없습니다
403 Forbidden 요청이 허가되지 않습니다
404 Not Found 요청한 리소스가 존재하지 않습니다
408 Request Timeout(*) 일정 시간 내에 요청이 완료되지 않았습니다
500 Internal Server Error(*) 서버 내부에 문제가 발생했습니다
502 Bad Gateway(*) 게이트웨이 서버가 백엔드 서버로부터 오류를 받았습니다
503 Service Unavailable(*) 서버가 일시적으로 요청을 처리할 수 없는 상태입니다
504 Gateway Timeout(*) 게이트웨이 서버에서 백엔드 서버로의 요청이 타임아웃됐습니다

 

파이썬에서 오류 처리하기

  • 아래 코드에서 접근할 URL('http://httpbin.org/status/200,404,503')은 무작위로 200, 404, 503의 상태 코드를 반환합니다.
  • 200과 404가 반환될 때는 Response 객체를 반환하고, 503이 반환될 때는 다시 시도합니다
import time

import requests
# 일시적인 오류를 나타내는 상태 코드를 지정합니다.
TEMPORARY_ERROR_CODES = (408, 500, 502, 503, 504)  

def main():
    """
    메인 처리입니다.
    """
    response = fetch('http://httpbin.org/status/200,404,503')
    if 200 <= response.status_code < 300:
        print('Success!')
    else:
        print('Error!')

def fetch(url):
    """
    지정한 URL에 요청한 뒤 Response 객체를 반환합니다.
    일시적인 오류가 발생하면 최대 3번 재시도합니다.
    """
    max_retries = 3  # 최대 3번 재시도합니다.
    retries = 0  # 현재 재시도 횟수를 나타내는 변수입니다.
    while True:
        try:
            print('Retrieving {0}...'.format(url))
            response = requests.get(url)
            print('Status: {0}'.format(response.status_code))
            if response.status_code not in TEMPORARY_ERROR_CODES:
                return response  # 일시적인 오류가 아니라면 response를 반환합니다.
        except requests.exceptions.RequestException as ex:
            # 네트워크 레벨 오류(RequestException)의 경우 재시도합니다.
            print('Exception occured: {0}'.format(ex))
            retries += 1
            if retries >= max_retries:
                # 재시도 횟수 상한을 넘으면 예외를 발생시켜버립니다.
                raise Exception('Too many retries.')  
            # 지수 함수적으로 재시도 간격을 증가합니다(**는 제곱 연산자입니다).
            wait = 2**(retries - 1)  
            print('Waiting {0} seconds...'.format(wait))
            time.sleep(wait)  # 대기합니다.

if __name__ == '__main__':
    main()

 

retrying을 이용한 재시도 처리

import requests
from retrying import retry  # pip install retrying
import time
# 일시적인 오류를 나타내는 상태 코드를 지정합니다.
TEMPORARY_ERROR_CODES = (408, 500, 502, 503, 504)  

def main():
    """
    메인 처리입니다.
    """
    response = fetch('http://httpbin.org/status/200,404,503')
    if 200 <= response.status_code < 300:
        print('Success!')
    else:
        print('Error!')

# stop_max_attempt_number로 최대 재시도 횟수를 지정합니다.
# wait_exponential_multiplier로 특정한 시간 만큼 대기하고 재시도하게 합니다. 단위는 밀리초로 입력합니다.
@retry(stop_max_attempt_number=3, wait_exponential_multiplier=1000)
def fetch(url):
    """
    지정한 URL에 접근한 뒤 Response 객체를 반환합니다.
    일시적인 오류가 발생할 경우 3번까지 재시도합니다.
    """
    print('Retrieving {0}...'.format(url))
    response = requests.get(url)
    print('Status: {0}'.format(response.status_code))
    if response.status_code not in TEMPORARY_ERROR_CODES:
        # 오류가 없다면 response를 반환합니다.
        return response
    # 오류가 있다면 예외를 발생시킵니다.
    raise Exception('Temporary Error: {0}'.format(response.status_code))

if __name__ == '__main__':
    main()