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은 태그를 찾아가며 다뤄야 해서 파이썬 처리 방식이 완전히 달라진다.
'Data Analytics > 수집·크롤링' 카테고리의 다른 글
| BeautifulSoup HTML 파싱 정리 | 일반 웹사이트에서 태그와 속성으로 데이터 추출하는 방법 (1) | 2026.05.08 |
|---|---|
| BeautifulSoup XML 파싱 정리 | find와 find_all 차이부터 영화 정보 추출까지 (0) | 2026.05.08 |
| requests.get 정리 | params로 API URL 깔끔하게 보내는 방법 (0) | 2026.05.07 |
| JSON 데이터를 Pandas DataFrame으로 바꾸는 방법 | 리스트와 딕셔너리 구조 정리 (0) | 2026.05.06 |
| 파이썬 API 데이터 수집 정리 | urllib와 json으로 JSON 응답 받아 DataFrame 만들기 (0) | 2026.05.06 |
