파이썬을 배워서 실생활에 도움을 주거나 업무를 자동화하고 싶을 때, 가장 먼저 도전하는 것이 바로 '공공데이터 API 연동'입니다. 기상청 날씨, 버스 도착 시간, 부동산 실거래가 등 국가에서 무료로 제공하는 방대한 데이터를 내 컴퓨터로 가져와 활용할 수 있다는 점은 무척 매력적입니다.

하지만 처음에 책이나 블로그 글만 보고 코드를 그대로 복사해 실행했다가, 알 수 없는 에러 메시지를 마주하고 시작하자마자 포기하는 분들이 정말 많습니다. 저 역시 처음 API를 접했을 때 코드 한 줄 실행하는 데만 꼬박 이틀을 밤새운 기억이 있습니다. 알고 보면 아주 사소한 규칙 몇 가지만 놓치지 않으면 되는데 말이죠.

오늘은 파이썬으로 오픈 API를 처음 연결할 때 누구나 한 번은 겪게 되는 대표적인 실수 3가지와, 이를 깔끔하게 해결하는 예방 코드를 함께 알아보겠습니다.

[실수 1] 인증키(Service Key) 복사 붙여넣기 오류와 인코딩 문제

공공데이터포털 등에서 API 사용 신청을 하면 알파벳과 숫자가 길게 섞인 '인증키'를 받게 됩니다. 보통 '일반 인증키(Encoding)'와 '일반 인증키(Decoding)' 두 가지 버전이 제공되는데, 초보자들이 가장 자주 하는 실수가 바로 이 두 가지 중 아무거나 무작정 파이썬 코드에 넣는 것입니다.

파이썬의 requests 라이브러리를 사용할 때, 이미 인코딩(컴퓨터가 이해할 수 있는 형태로 변환)된 키를 다시 인코딩하여 서버로 전송하면 웹 서버는 "등록되지 않은 인증키"라는 에러(SERVICE_KEY_IS_NOT_REGISTERED_ERROR)를 뱉어냅니다.

이 문제를 해결하는 가장 안전한 방법은 '디코딩(Decoding)된 인증키'를 사용하는 것입니다. 파이썬 코드 내에서 requests.get() 함수를 호출할 때 인자를 주소창에 직접 더하지 말고, params라는 딕셔너리 형태로 전달하면 requests 라이브러리가 알아서 올바르게 키를 인코딩해 줍니다.

[실수 2] XML과 JSON 데이터 형식의 오해

공공데이터 API는 대개 데이터 응답 형식으로 XML이나 JSON을 지원합니다. 요즘은 가독성이 좋은 JSON 형식을 선호하지만, 국가 데이터의 상당수는 여전히 기본값이 XML로 설정되어 있는 경우가 많습니다.

많은 입문자가 데이터가 당연히 JSON 형태로 올 줄 알고 코드에 response.json()을 적었다가 JSONDecodeError를 만나곤 합니다. 서버가 보내준 진짜 데이터는 <?xml version=... 형식의 XML인데, 파이썬에게 이를 JSON으로 강제 해석하라고 하니 에러가 발생하는 것입니다.

이것을 방지하려면 API를 요청할 때 필수 파라미터에 데이터 타입을 명시해 주는 습관이 필요합니다. 공공데이터포털의 경우 대부분 파라미터에 _type: 'json' 또는 returnType: 'json'을 추가하면 JSON으로 안전하게 응답을 받아올 수 있습니다. 만약 이를 지원하지 않는다면 XML 파싱 라이브러리(BeautifulSoup 등)를 사용해야 합니다.

[실수 3] 네트워크 불안정과 예외 처리 부재

내 컴퓨터에서 코드가 잘 작동하다가도, 어느 날 갑자기 프로그램이 툭 멈춰버리는 경우가 있습니다. 공공데이터 서버가 일시적으로 점검 중이거나, 주말에 트래픽이 몰려 응답이 지연될 때 흔히 발생합니다.

초보자의 코드는 대개 서버가 항상 1초 안에 정상적인 데이터를 돌려줄 것이라 가정하고 작성됩니다. 하지만 서버 응답이 없으면 파이썬은 무한정 대기 상태에 빠지거나 코드가 강제 종료됩니다. 이를 방지하기 위해 요청을 보낼 때는 반드시 '타임아웃(Timeout)' 설정과 'try-except' 예외 처리 블록을 구성해야 합니다. 코드가 멈추는 대신 "서버 연결에 실패했습니다"라는 안내를 남기고 다음 단계로 안전하게 넘어가도록 설계해야 장기적으로 안정적인 자동화 프로그램을 만들 수 있습니다.

실수를 방지하는 파이썬 API 기본 연결 템플릿

아래 코드는 앞서 언급한 세 가지 실수를 모두 보완한 가장 표준적인 파이썬 API 요청 구조입니다. 새로운 API를 다룰 때 이 틀을 기반으로 시작하면 시행착오를 크게 줄일 수 있습니다.

Python
import requests

# 1. 디코딩된 인증키 사용
decoding_key = "여러분의_디코딩된_인증키_입력"
url = "http://apis.data.go.kr/1360000/VilageFcstInfoService_2.0/getUltraSrtNcst"

# 2. 파라미터 딕셔너리에 반환 타입(JSON) 명시
params = {
    'serviceKey': decoding_key,
    'pageNo': '1',
    'numOfRows': '10',
    'dataType': 'JSON',  # JSON 형식으로 명시적 요청
    'base_date': '20260709',
    'base_time': '0600',
    'nx': '55',
    'ny': '127'
}

try:
    # 3. 타임아웃을 10초로 제한하여 무한 대기 방지
    response = requests.get(url, params=params, timeout=10)
    
    # HTTP 상태 코드가 200(정상)이 아니면 에러 발생
    response.raise_for_status()
    
    # 정상적으로 JSON 데이터 추출
    data = response.json()
    print("데이터 수집 성공!")
    print(data)

except requests.exceptions.Timeout:
    print("에러: 서버 응답 시간이 초과되었습니다. 잠시 후 다시 시도하세요.")
except requests.exceptions.HTTPError as http_err:
    print(f"HTTP 에러 발생: {http_err}")
except ValueError:
    print("에러: JSON 형식으로 데이터를 읽을 수 없습니다. 응답 포맷을 확인하세요.")
except Exception as e:
    print(f"기타 에러 발생: {e}")

처음에는 API 문서의 복잡한 표와 긴 인증키에 압도되기 쉽습니다. 하지만 원리를 이해하고 데이터가 오고 가는 길목을 명확히 제어해 주면, 파이썬만큼 강력하고 재미있는 데이터 수집 도구도 없습니다. 오늘 소개해 드린 기본 패턴을 기억해 두신다면, 앞으로 어떤 API를 만나더라도 당황하지 않고 첫 단추를 잘 끼울 수 있을 것입니다.

핵심 요약

  • API 연동 시 에러가 나면 가장 먼저 '인증키 인코딩/디코딩' 상태와 params 전달 방식을 점검해야 합니다.

  • 서버가 제공하는 응답 타입(JSON/XML)을 명확히 인지하고, 요청 파라미터에 데이터 형식을 지정해 주는 것이 안전합니다.

  • 외부 서버와 통신하는 코드는 언제든 멈출 수 있으므로 타임아웃 설정과 예외 처리(try-except)를 필수로 추가해야 합니다.