BeautifulSoup XML 파싱 정리 | find와 find_all 차이부터 영화 정보 추출까지

XML API를 파이썬에서 처리할 때 핵심은 데이터를 dict처럼 접근하는 게 아니라, 태그를 찾아 들어가는 방식으로 접근해야 한다는 것이다.

이때 가장 많이 쓰는 도구가 BeautifulSoup이고, 특히 find()와 find_all()의 차이를 이해하는 것이 XML 파싱의 기본이다.


XML은 태그 중심 구조다

JSON이 key-value 구조라면,

XML은 <tag>value</tag> 형태의 태그 구조다.

예시:

<movie>
  <movieCd>123</movieCd>
  <movieNm>영화이름</movieNm>
</movie>

이 구조에서는 "movieCd" 같은 key 접근이 아니라,

👉 movieCd 태그를 찾아야 한다


BeautifulSoup로 XML 파싱하기

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")

👉 핵심

  • "xml" 파서 사용
  • 이후는 전부 태그 기반 탐색

find vs find_all 핵심 차이

이 부분이 가장 중요하다.

함수 결과

find() 첫 번째 태그 하나
find_all() 모든 태그 리스트

find 사용

soup.find("movie")
  • 첫 번째 <movie>만 반환
  • 단일 객체

find_all 사용

soup.find_all("movie")
  • 모든 <movie> 반환
  • 리스트 형태

왜 find_all이 더 많이 쓰일까

실전에서는 대부분 여러 데이터(row)를 반복 처리해야 한다.

movies = soup.find_all("movie")

이렇게 받은 뒤 반복문을 돌린다.

👉 즉, DataFrame 만들려면 거의 무조건 find_all


실제 데이터 추출 흐름

KOBIS XML 구조 기준으로 보면:

movie_list = []

for data in soup.find_all("movie"):
    movie_cd = data.find("movieCd").text
    movie_nm = data.find("movieNm").text
    movie_nm_en = data.find("movieNmEn").text
    open_dt = data.find("openDt").text

    movie_list.append([movie_cd, movie_nm, movie_nm_en, open_dt])

👉 핵심 패턴

find_all → 반복문 → find → .text

감독 정보 추출 (중요 포인트)

XML에서도 중첩 구조가 있다.

<directors>
  <director>
    <peopleNm>감독이름</peopleNm>
  </director>
</directors>

이 경우 이렇게 접근한다.

if data.find_all("peopleNm") != []:
    director = data.find("peopleNm").text
else:
    director = ""

👉 JSON이랑 똑같이 빈 값 예외 처리 필요


find의 단점 (실전에서 중요)

find()는 태그가 없을 때 문제가 생긴다.

  • None 반환
  • .text 접근 시 에러 가능

반면 find_all()은:

[]

👉 빈 리스트 반환

그래서 조건 처리하기 쉽다.


find vs find_all 사용 기준

find

  • 단일 값이 확실할 때
  • 구조가 고정일 때

find_all

  • 반복 처리할 때
  • 데이터 개수가 여러 개일 때
  • 예외 처리까지 고려할 때

👉 실전에서는 대부분 find_all + 반복문


XML → DataFrame 변환

import pandas as pd

df = pd.DataFrame(movie_list, columns=[
    "movieCd", "movieNm", "movieNmEn", "openDt"
])

print(df.head())

구현 관점 핵심 포인트

1. XML은 dict처럼 접근 안 된다

→ 무조건 태그 기반 접근


2. find_all → 반복문 구조가 기본

for data in soup.find_all("movie")

3. .text로 값 추출

data.find("movieCd").text

4. 빈 태그 예외 처리 필요

if data.find_all("peopleNm") != []

5. JSON보다 DataFrame 변환이 번거롭다

→ 직접 구조를 풀어줘야 함


XML 파싱은 dict 접근이 아니라, find_all → find → text 흐름으로 태그를 찾아가며 데이터를 추출하는 방식이다.