공공데이터포털( data.go.kr ) API 및 기타 API를 사용하면서 발생하는 다양한 에러 및 대처방법을 알아본다.
개요
공공데이터포털( data.go.kr ) API를 사용하다 보면 다양한 에러를 마주할 수 있다. SSL 에러부터 연결 에러, 파라미터 에러 등 종류가 매우 많다.
※ SSL에러는 Py) API(공공) SSL 에러 게시글을 참고 하자
Py) API(공공) 아파트 매매 실거래가 상세 게시글의 코드를 기반으로 API사용 시 발생하는 다양한 에러를 알아보자.
에러 유형
에러 유형은 에러 유발 요인에 따라 나뉘어지며 가장 큰 요인은 API호출 URL과 관련된 오타이다. 그래서 크게 오타로 인해 발생하는 에러와 그렇지 않은 에러로 나누어서 살펴보고자 한다.
코드 준비
우선 정상적으로 동작하는 코드를 준비한다(이하 기본 코드
). 참고로 API는 본인의 Encoding API키를 사용하도록 하며 “국토교통부 아파트 매매 실거래가 상세자료” API를 미리 사용신청 해야 한다.
1 | import requests |
제대로 실행을 했다면 아래와 같은 결과를 얻을 수 있다.
1 | res.status_code |
정상동작하는 상기 코드를 기준으로 다음 에러를 살펴보도록 하겠다.
오타로 인한 에러
일반적으로 API를 호출할 때 사용하는 URL의 구조를 살펴보도록 하자.
프로토콜
기본 코드
에서 “url_base”객체의 입력값을 약간 바꿔보자.
1 | url_base = "http:/apis.data.go.kr/1613000/RTMSDataSvcAptTradeDev/getRTMSDataSvcAptTradeDev" |
“http://“대신 “http:/“로 입력하였다. 이 “url_base” 객체를 사용하여 API를 호출하면 아래와 같은 에러가 발생한다.
1 | --------------------------------------------------------------------------- |
InvalidURL : Invalid URL ‘http:/apis.data.go.kr/1613000/RTMSDataSvcAptTradeDev/getRTMSDataSvcAptTradeDev?serviceKey=qSd6eaxxxxxxxxxxxxxxxXPn0SgGfh0YsRJEr%2FOr7wi%2BA%3D%3D&LAWD_CD=11110&DEAL_YMD=202501&pageNo=1&numOfRows=10’: No host supplied
잘못된 “URL”이라는 에러가 발생한다.
그리고 “https”와 “http” 중 지정된 프로토콜을 사용하지 않으면 SSL에러가 발생할 수 있다.
※ Py) API(공공) SSL 에러 게시글 참고
호스트
여기서 호스트(host)는 서버 도메인 주소 부분을 뜻한다.
이번에는 “url_base” 객체에 다음과 같이 주소를 할당해보자.
1 | url_base = "http://a.data.go.kr/1613000/RTMSDataSvcAptTradeDev/getRTMSDataSvcAptTradeDev" |
이번에는 “apis” 대신 “a”라고 입력을 하였다. 이 “url_base” 객체를 사용하여 API를 호출하면 아래와 같은 에러가 발생한다.
1 | --------------------------------------------------------------------------- |
ConnectionError: HTTPConnectionPool(host=’a.data.go.kr’, port=80): Max retries exceeded with url: /1613000/RTMSDataSvcAptTradeDev/getRTMSDataSvcAptTradeDev?serviceKey=qSd6eaxxxxxxxxxxxxxxxXPn0SgGfh0YsRJEr%2FOr7wi%2BA%3D%3D&LAWD_CD=11110&DEAL_YMD=202501&pageNo=1&numOfRows=10 (Caused by NameResolutionError(“<urllib3.connection.HTTPConnection object at 0x0000014255C07610>: Failed to resolve ‘a.data.go.kr’ ([Errno 11001] getaddrinfo failed)”))
이렇게 “ConnectionError”가 발생한다.
경로
경로(path)는 호스트 주소 이후 부터 쿼리 스트링이 시작되기 전까지의 주소를 뜻한다. 기존 “url_base”객체에서는 “9999999/RTMSDataSvcAptTradeDev/getRTMSDataSvcAptTradeDev” 부분이 경로에 해당한다.
다음과 같이 “url_base” 객체에 할당되는 주소를 바꿔보자.
1 | url_base = "http://apis.data.go.kr/9999999/RTMSDataSvcAptTradeDev/getRTMSDataSvcAptTradeDev" |
이번에는 “1613000” 대신 “9999999”로 입력하였다. 이 “url_base” 객체를 사용하여 API를 호출하면 바로 에러가 발생하지는 않는다. 단, 응답 결과를 살펴보면 뭔가 잘못되었다는 것을 알 수 있다.
1 | res.status_code |
응답 코드도 500으로 나오고, “Policy Falsified”라는 메시지가 나오는 것을 확인할 수 있다. 여기 500이라는 “HTTP 상태 코드”는 서버 내부 오류를 뜻한다. 즉, 서버에서는 “9999999”라는 경로가 존재하지 않기에 이런 에러가 발생한 것으로 추정된다.
파라미터
기본 코드에서 “url”객체의 내용을 바꿔보도록 하겠다. 다음과 같이 “url” 객체를 새로운 주소로 할당하여 코드를 실행해보자.
1 | url = f"{url_base}?serviceKey={key}&LAWD_cd={val_lawd_cd}&DEAL_YMD={val_deal_ymd}&pageNo=1&numOfRows=10" |
여기서는 파라미터 “LAWD_CD”를 “LAWD_cd”로 입력하였다. 이 “url” 객체를 사용하여 API를 호출하면 에러는 발생하지 않지만 다음과 같은 결과를 볼 수 있다.
1 | res.status_code |
여기서는 HTTP 상태코드도 200이고 “bs_res” 객체의 결과를 보면 “items” 태그에 내용이 없다. 이는 수집 과정에서 확인하지 않으면 제대로 수집이 되지 않는 것을 발견할 수 없으니 주의해야 한다. 그리고 이 API의 경우 에러가 발생하지 않았지만, 다른 API에서는 에러가 발생할 수 있다.
비슷하게 다음과 같이 파라미터에 할당되는 값을 호출 허용범위 이외의 값으로 할당해보자.
1 | val_deal_ymd = 209901 |
파라미터명을 잘못 입력한 경우와 같이 에러는 발생하지 않지만 결과가 없는 것을 확인할 수 있다.
1 | res.status_code |
그 외 에러
오타가 아닌 에러의 경우에는 크게 보안, 인터넷 연결, 인증키, 서버 문제로 나눌 수 있다.
보안
보안수준이 높은 조직 또는 회사에서 API를 사용할 때는 보안 정책에 따라 API호출이 제한될 수 있다. 이 경우에는 보안 정책을 확인하고 필요시 관리자에게 문의하여 해결해야 한다.
인터넷 연결
사용자가 사용하는 인터넷 환경에 따라 API호출이 제한될 수 있다. 이 경우에는 인터넷 연결 상태를 확인하고 필요시 관리자에게 문의하여 해결해야 한다. 보통 노트북으로 WIFI를 연결해서 API를 사용하는 와중에 WIFI가 끊겨있는 것을 모른채 API 호출을 시도 시 에러가 발생하는 경우가 많다.
인증키
인증키가 필요한 API의 경우 인증키 오타, 인증키 등록 지연, 인증키 만료 등 다양한 이유가 있을 수 있다. 각 상황에 따라 인증키를 확인하고 관리자에게 문의하여 해결해야 한다.
서버
API 서비스를 제공하는 서버가 다운되거나 기타 서버 문제로 인해 API호출이 제한될 수 있다. 이 경우에는 서버 상태를 확인하고 필요시 관리자에게 문의하여 해결해야 한다.