JSON과 XML 차이 정리 | API 응답 포맷에 따라 파이썬 처리 방식이 달라지는 이유

API를 호출할 때 중요한 건 데이터를 받았다는 사실보다, 그 응답이 JSON인지 XML인지 먼저 구분하는 것이다.

같은 영화목록 API라도 JSON으로 받으면 파이썬의 dict/list처럼 다룰 수 있고, XML로 받으면 태그 구조를 기준으로 찾아 들어가야 한다. 즉, 정보 자체보다 포장 방식이 다르고, 그 차이 때문에 파이썬 처리 방식도 달라진다. 자료에서도 JSON은 json 패키지를 통해 파이썬 자료형으로 바꾸고 키값/정수 인덱스로 접근하며, XML은 BeautifulSoup를 통해 태그 중심으로 접근한다고 명확히 구분한다.

먼저 결론부터 정리하면

JSON과 XML의 가장 큰 차이는 이거다.

  • JSON: 파이썬 자료형으로 변환해서 접근
  • XML: 태그를 직접 찾아가며 접근

이 차이를 모르면, 같은 API 문서를 보고도 처리 코드를 전혀 다르게 짜야 하는 이유가 잘 안 보인다.


같은 KOBIS API도 JSON과 XML 두 방식으로 응답할 수 있다

KOBIS 영화목록 API는 요청 주소 끝부분만 바꾸면 응답 포맷을 바꿀 수 있다.

JSON 요청 예시

url_p1 = "<http://www.kobis.or.kr/kobisopenapi/webservice/rest/movie/searchMovieList.json>"
key = "발급받은_개인키"
url = url_p1 + "?key=" + key + "&itemPerPage=50"

XML 요청 예시

url_p1 = "<http://www.kobis.or.kr/kobisopenapi/webservice/rest/movie/searchMovieList.xml>"
key = "발급받은_개인키"
url = url_p1 + "?key=" + key + "&itemPerPage=50"

즉, 요청 대상 데이터는 비슷하지만 응답 포맷만 바뀌는 구조다. 자료에서도 동일한 영화목록 API를 .json과 .xml 엔드포인트로 각각 호출하는 예시가 나온다.


JSON은 dict/list 자료형으로 바꾸기 쉽다

JSON의 가장 큰 장점은 파이썬 자료형과 잘 맞는다는 점이다.

응답을 문자열로 받은 뒤 json.loads()를 거치면, 바로 dict와 list 구조로 다룰 수 있다.

import urllib.request
import json

url = "<http://www.kobis.or.kr/kobisopenapi/webservice/rest/movie/searchMovieList.json?key=발급받은_개인키&itemPerPage=50>"

movie_page = urllib.request.urlopen(url)
movie_data = json.loads(movie_page.read().decode("utf-8"))

print(type(movie_data))  # dict
print(movie_data.keys())

KOBIS JSON 구조는 보통 이런 흐름이다.

movieListResult
└── movieList
    └── [영화정보 dict, 영화정보 dict, ...]

실제 접근은 이렇게 한다.

movie_data["movieListResult"]["movieList"][0]["movieCd"]
movie_data["movieListResult"]["movieList"][0]["movieNm"]

즉, JSON은 키값 → 리스트 인덱스 → 키값 흐름으로 접근한다. 자료에서도 JSON은 파이썬 dict/list로 바꾼 뒤 정수 인덱스와 키값 중심으로 순차 접근한다고 설명한다.


XML은 태그 중심 언어라 접근 방식이 다르다

XML은 JSON처럼 dict/list로 바뀌는 게 아니라, <movieCd>, <movieNm> 같은 태그 묶음으로 들어온다.

그래서 파이썬에서 바로 ["movieCd"]처럼 접근하는 게 아니라, 태그를 찾는 방식으로 들어가야 한다.

자료에서는 XML을 “정보 전달 중심의 태그 언어”로 설명하고, BeautifulSoup를 이용해 XML을 태그 기준으로 다루는 흐름을 보여준다.

예를 들면:

import urllib.request
from bs4 import BeautifulSoup

url = "<http://www.kobis.or.kr/kobisopenapi/webservice/rest/movie/searchMovieList.xml?key=발급받은_개인키&itemPerPage=50>"

res = urllib.request.urlopen(url)
soup = BeautifulSoup(res, "xml")

이제부터는 dict가 아니라 soup 안의 태그를 찾는 방식이다.


JSON은 키값 접근, XML은 find/find_all 접근

이 차이가 가장 중요하다.

JSON 방식

movie_data["movieListResult"]["movieList"][0]["movieNm"]

XML 방식

soup.find_all("movie")[0].find("movieNm").text

즉,

  • JSON은 자료형 접근
  • XML은 태그 검색 접근

자료에서도 JSON은 movieListResult -> movieList -> 0번째 영화 -> movieCd처럼 순차 접근하고, XML은 find("movie"), find_all("movie"), find("movieCd").text 식으로 접근하는 흐름이 나온다.


XML에서 BeautifulSoup를 쓰는 이유

XML은 태그 중심 구조라서, 문자열 상태로는 다루기 불편하다.

그래서 BeautifulSoup(res, "xml")로 파싱한 뒤 태그 단위 접근이 가능하게 만든다.

from bs4 import BeautifulSoup

soup = BeautifulSoup(res, "xml")
print(soup.find("movie"))
print(soup.find_all("movie")[0].find("movieCd").text)

자료에서도 JSON 패키지는 자료형 변환용이고, bs4는 XML/HTML 같은 태그 중심 언어에 직접 접근할 수 있게 해주는 도구라고 구분해서 설명한다.


find와 find_all 차이도 XML 쪽에서 중요하다

XML을 다룰 때 자주 쓰는 메서드는 find와 find_all이다.

find

  • 처음 하나만 반환

find_all

  • 해당 태그 전부를 리스트로 반환

예시:

soup.find("movie")
soup.find_all("movie")

자료에서는 이 차이를 꽤 중요하게 다룬다. 특히 없는 태그를 찾았을 때 find_all()은 []를 반환해 예외 처리하기 쉬운 반면, find()는 반응이 애매해서 다루기 불편할 수 있다고 설명한다.


JSON은 DataFrame과 호환이 더 쉬운 편이다

이 부분이 실전에서 꽤 크다.

JSON은 이미 dict/list 구조라서, 응답 일부를 그대로 pd.DataFrame()에 넣기 쉬운 편이다.

import pandas as pd

df = pd.DataFrame(movie_data["movieListResult"]["movieList"])
print(df.head())

자료에서도 JSON은 Pandas DataFrame과 상호 호환이 용이하다고 설명하고, 실제로 pd.DataFrame(result["movieListResult"]["movieList"])처럼 바로 테이블로 만드는 흐름이 나온다.

물론 directors 같은 중첩 구조는 후처리가 필요하지만, 기본적으로는 XML보다 DataFrame 연결이 빠르다.


XML도 결국 DataFrame으로 만들 수는 있다

XML이 불편하다고 해서 DataFrame으로 못 옮기는 건 아니다.

다만 JSON처럼 바로 넘기기보다는, 태그를 찾아서 필요한 값만 직접 모아야 한다.

예시:

movie_list = []

for data in soup.find_all("movie"):
    i_dict = {
        "code": data.find("movieCd").text,
        "title": data.find("movieNm").text,
        "e-title": data.find("movieNmEn").text,
        "openD": data.find("openDt").text,
        "dirName": data.find("peopleNm").text if data.find_all("peopleNm") != [] else "X"
    }
    movie_list.append(i_dict)

df = pd.DataFrame(movie_list)

자료에서도 XML 응답에서 movie 태그 단위로 반복문을 돌며 movieCd, movieNm, movieNmEn, openDt, peopleNm을 추출해 dict로 쌓은 뒤 DataFrame으로 바꾸는 예시가 나온다.

즉, XML도 정리하면 DataFrame으로 갈 수 있지만, 중간 추출 과정이 더 명시적이다.


정보가 다른 게 아니라 포장지가 다르다

이 문장이 이 글의 핵심이다.

예를 들어 영화 코드, 제목, 개봉일, 감독명 같은 정보는 JSON에도 있고 XML에도 있다.

차이는 그 정보가 어떤 방식으로 감싸져 있느냐이다.

  • JSON → 키와 리스트로 감쌈
  • XML → 태그로 감쌈

자료와 녹취에서도 “정보가 달라지는 게 아니라 어떻게 포장할 거냐가 다르다”는 설명이 반복해서 나온다. 즉, 포맷 차이가 곧 처리 방식 차이로 이어진다는 의미다.


언제 JSON이 더 편하고, 언제 XML을 보게 될까

JSON이 더 편한 경우

  • Python 자료형처럼 바로 다루고 싶을 때
  • DataFrame으로 빨리 넘기고 싶을 때
  • API 응답을 구조적으로 후처리할 때

XML을 보게 되는 경우

  • 해당 API가 XML 포맷을 기본 제공할 때
  • 공공데이터나 레거시 시스템에서 XML 응답이 남아 있을 때
  • 태그 구조를 기준으로 특정 값만 직접 찾을 때

즉, JSON이 보통 더 실용적이지만, XML도 여전히 자주 만난다.


구현 관점에서 기억할 포인트

1. JSON은 자료형 변환이 먼저다

json.loads() 또는 res.json()으로 dict/list로 바꾸는 게 시작이다.

2. XML은 파싱 후 태그 탐색이 시작이다

BeautifulSoup(..., "xml")로 만든 뒤 find, find_all, .text를 사용한다.

3. JSON은 DataFrame으로 직행하기 쉽다

바로 pd.DataFrame()으로 넘길 수 있는 경우가 많다.

4. XML은 태그 개수와 누락값 예외 처리를 더 신경 써야 한다

특히 find_all("peopleNm") != [] 같은 체크가 자주 들어간다.


한 줄 정리

같은 API 응답이라도 JSON은 dict/list처럼 다루고, XML은 태그를 찾아가며 다뤄야 해서 파이썬 처리 방식이 완전히 달라진다.