공공데이터 API 연동 함정

데이터 · 크롤링4분 읽기

공공데이터 API 연동은 문서만 보면 쉬워 보입니다. 키를 발급받고 엔드포인트를 호출하고 응답을 파싱하면 끝일 것 같습니다. 그런데 정책 공고 수집 파이프라인을 만들며 공공데이터포털과 지자체 API 10종을 실제로 붙여 보니, 교과서에 없는 함정이 줄줄이 나왔습니다. 이 글은 그 함정들과 우리가 정착시킨 대응을 정리한 것입니다.

함정 1: 공공데이터 API는 에러를 200으로 준다

공공데이터 API의 가장 유명한 함정입니다. 키가 만료되거나 쿼터를 초과해도 HTTP 상태 코드는 200으로 오고 에러는 응답 본문 안에 XML이나 텍스트로 담겨 있습니다. 상태 코드만 믿고 파싱을 시작하면 에러 메시지가 데이터로 둔갑해 DB에 들어갑니다.

그래서 우리는 파싱 앞에 응답 검증기를 별도 단계로 두었습니다. 본문이 기대한 구조인지, 에러 코드 패턴이 섞여 있지 않은지를 먼저 확인하고 통과한 응답만 파서로 넘깁니다. "성공처럼 생긴 실패"를 걸러내는 이 한 단계가 데이터 오염 사고를 막는 핵심이었습니다.

함정 2: 쿼터와 속도 제한

공공 API에는 일일 호출 한도와 분당 쿼터가 있습니다. 대량 수집을 돌리다 한도에 걸리면 그날 수집이 통째로 밀립니다. 대응은 두 겹입니다. 평상시에는 요청 속도를 분당 30회로 묶어 한도 근처에 가지 않게 하고 쿼터 초과 응답을 만나면 몇 초 단위에서 시작해 간격을 배로 늘리는 재시도로 물러섭니다. 일시 장애도 같은 원리로, 지수 백오프를 걸어 최대 6회까지 재시도한 뒤에야 실패로 기록합니다.

속도 제한은 우리를 지키는 장치이기도 합니다. 상대 서버에 부담을 주지 않는 완만한 수집은 차단을 예방하고 장기 운영에서 신뢰를 만듭니다.

함정 3: EUC-KR은 아직 살아 있다

공공기관 사이트와 일부 API는 여전히 EUC-KR이나 CP949 인코딩으로 응답합니다. UTF-8로 가정하고 읽으면 한글이 전부 깨집니다. 우리는 응답 인코딩을 감지해 UTF-8로 자동 변환하는 계층을 공통 HTTP 클라이언트에 넣어 소스별 코드가 인코딩을 신경 쓰지 않게 했습니다. 첨부파일로 내려오는 CSV와 엑셀도 마찬가지로 이 계층을 통과합니다.

함정 4: 같은 데이터, 제각각인 표기

여러 기관의 API를 한 스키마로 모으는 순간 표기 문제가 터집니다. 대표적인 것이 날짜입니다. "2026-04-04", "2026.4.4", "20260404" 같은 형식 차이는 애교이고 "상시", "예산 소진 시까지", "연중" 같은 값도 신청 기간 필드에 들어옵니다. 우리는 열 가지가 넘는 표기를 흡수하는 한국어 날짜 파서를 만들고 기간 표기는 시작일·종료일·상시 여부의 구조화된 형태로 정규화했습니다.

원본 표기정규화 결과
2026.4.42026-04-04
202604042026-04-04
상시 / 연중상시 플래그
예산 소진 시까지종료일 없음 + 조건 종료 플래그

표기 정규화는 수집기가 아니라 정규화 계층의 일입니다. 소스가 늘 때마다 파서를 복사하지 않고 한곳에서 규칙을 관리해야, 새 표기가 나타났을 때 한 번만 고치면 됩니다.

함정 5: 응답 구조를 믿지 말 것

문서와 실제 응답이 다른 경우, 필드가 어느 날 조용히 사라지는 경우도 있습니다. 우리는 모든 API 응답을 스키마 검증(zod)으로 받아 기대와 다른 구조가 오면 데이터로 적재하지 않고 실패로 기록하게 했습니다. 잘못된 데이터가 조용히 쌓이는 것보다 시끄럽게 실패하는 쪽이 낫습니다.

페이지네이션도 소스마다 다릅니다. 페이지 번호를 넘기는 API가 있는가 하면 시작·끝 인덱스를 받는 API(서울 열린데이터광장이 이 방식입니다)도 있어 순회 로직을 전 소스 공통으로 두면 반드시 어딘가에서 어긋납니다. 우리는 소스별 수집기가 자기 순회 방식을 갖고 공통 계층은 재시도와 속도 제한만 책임지도록 역할을 나눴습니다.

이 함정들은 API 연동만의 이야기이고 게시판 크롤링 쪽의 함정과 대응은 대규모 크롤러 운영 안정성에서 다룹니다. 이 모든 방어가 들어간 전체 시스템은 공공데이터 크롤링 자동화 사례에서 볼 수 있습니다.

자주 묻는 질문

공공데이터 API는 상태 코드로 성공을 판단하면 안 되나요?

안 됩니다. 상당수 공공 API가 키 만료나 쿼터 초과 같은 에러를 HTTP 200에 본문 메시지로 담아 반환합니다. 본문 구조와 에러 패턴을 확인하는 응답 검증 단계를 파싱 앞에 두어야 에러 메시지가 데이터로 적재되는 사고를 막을 수 있습니다.

호출 쿼터는 어떻게 관리하나요?

평상시 요청 속도를 분당 단위로 제한해 한도 근처에 가지 않게 하고 쿼터 초과 응답에는 간격을 배로 늘리는 재시도로 대응합니다. 대량 수집은 하루 한 번 새벽 배치로 몰아 호출량을 예측 가능하게 유지하는 것이 안전합니다.

기관마다 다른 데이터 형식은 어디서 통일하나요?

수집기가 아니라 별도 정규화 계층에서 통일합니다. 날짜·기간·인코딩·링크 경로 같은 표기 규칙을 한곳에 모아 두면, 새 소스가 늘거나 새 표기가 나타나도 규칙 한 곳만 고치면 됩니다.

공공데이터 API 키는 어떻게 관리해야 하나요?

코드와 분리해 환경변수나 시크릿 저장소에 둡니다. 저장소에 평문으로 커밋되지 않게 검사 절차도 둡니다. 키 만료는 조용히 찾아오므로, 에러를 200으로 주는 응답 검증 단계가 만료 신호를 걸러 주는 역할도 겸하게 됩니다.

공공데이터 API만으로 원하는 데이터를 다 모을 수 있나요?

대상에 따라 다르지만 대부분 부족합니다. 우리 사례에서도 API로 커버된 소스는 10종이고 나머지는 게시판 크롤링과 블로그 수집으로 채웠습니다. API 우선, 크롤링 보완의 혼합 구성이 현실적입니다.

#공공데이터API#데이터수집#API연동#데이터정규화

업무자동화 구축이 필요하신가요?

무료 상담 신청