본문 바로가기
데이터분석/Pandas

[Python] Pandas 06 _ kobis_api_xml

by nemonemonemo 2025. 8. 20.

API에서 XML양식으로 요청하고 받아서 하는 부분을 동일하게 진행

  • xml과 같은 스타일 html에서도 거의 유사함
  • xml : 정보 전달 중심 // html 웹에서 보여주기.
  • xml 양식 → Tag 중심의 언어!!!
    • <tag이름> 해당tag에 대한 값 </tag이름>
    • <tag이름></tag이름>
    • <tag이름/>
#필요한 기능
import pandas as pd
import urllib.request
#html..xml-> tag 중심 언어 BeautifulSoup
from bs4 import BeautifulSoup

#통신
res = urllib.request.urlopen(url)
# ===> res: xml 양식으로 되어있는 친구
#      bs4의 패키지 활용해서 : tag 중심으로 접근할 수 있도 파싱!!!
soup = BeautifulSoup(res, "xml") # 일반 사이트 : html.parser
soup

# 좀 더 예쁘게 보고 싶다면 이 방법이 있긴 함
# 트리 구조로 보여주는 양식인데 그닥임...
# 그냥 옆에 브라우저 켜놓고 보는게 훨씬 낫다
print(soup.prettify())

JSON 패키지

  • json 양식 언어 → 파이썬 자료형
  • ⇒ 정보 접근: 정수 인덱스, 키값
  • ⇒ 정보에 대한 접근을 바로 갈 수 없음

bs 패키지

  • tag 중심의 언어(xml, html etc…)
  • ⇒ 직접 tag 중심으로 접근이 용이하도록 제공
  • → 파이썬의 기본 자료형으로 변경하는 것이 아님
  • → find(찾을테그명)
    • 여러 테그가 있어서 해당되도 맨 처음만
  • → find_all(찾을테그명)
    • 해당하는 테그에 대한 정보다 다 줘
    • 결과가 0개로 없어도,,,[] 빈리스트
    • --> 에러 처리에 용이할 듯!!!
soup.find("movie")
# ==> 결과물에 대한 양식 : xml양식!!! --> find/find_all
#<movie><movieCd>2025A806</movieCd><movieNm>구룡성채: 철권고영</movieNm><movieNmEn>Kowloon Walled City</movieNmEn><prdtYear>2021</prdtYear><openDt/><typeNm>장편</typeNm><prdtStatNm>기타</prdtStatNm><nationAlt>중국</nationAlt><genreAlt>액션</genreAlt><repNationNm>중국</repNationNm><repGenreNm>액션</repGenreNm><directors/><companys/></movie>

soup.find("movieeeeeeeeeeeeeeeeeeeeeeeeeee")
# ==> 없는 테그에 대해서는 반응이 없음 -> 에러처리가 좀 불편하다

soup.find_all("movieeeeee")
#[]

soup.find_all("movie")[0]
#<movie><movieCd>2025A806</movieCd><movieNm>구룡성채: 철권고영</movieNm><movieNmEn>Kowloon Walled City</movieNmEn><prdtYear>2021</prdtYear><openDt/><typeNm>장편</typeNm><prdtStatNm>기타</prdtStatNm><nationAlt>중국</nationAlt><genreAlt>액션</genreAlt><repNationNm>중국</repNationNm><repGenreNm>액션</repGenreNm><directors/><companys/></movie>
# --> 내가 받은 영화 중 처음 영화에 대한 정보!!!
# 0번째 영화에 대한 코드값
soup.find_all("movie")[0].find("movieCd")
##<movieCd>2025A806</movieCd>

soup.find_all("movie")[0].find("movieCd").text
##2025A806

soup.find_all("movie")[0].find("movieCd").get_text()
##2025A806

# 참고) json으로 했던 스타일 대로 순차적인 접근도 가능은 함 (가끔 필요)
soup.movie.movieCd.text
##2025A806

#이런식으로 해도 괜찮을까??
#지금 데이터는 괜찮지만...
soup.find_all("movieCd")[0]
# 안 괜찮음!!!! X X X
# why?
# openDt 이런 친구들은 밀릴 수 있음
##<movieCd>2025A806</movieCd>

# Q) 받은 영화의 정보가 몇 개인가?
# Q) 0번 영화의 코드값,국문제목, 영문제목, 개봉일자, 감독이름1번 이름만...
# ===> 1번, 2번,,
#      규칙이 보이시면 for문으로 출력!!!!!!!

len(soup.find_all("movieCd"))
##50

len(soup.find_all("peopleNm"))
##18
# ---> tag가 없다면,,,순서가 밀릴수 있다!!!!

soup.find_all("movie")[0].find("movieCd").text
#2025A806

soup.find_all("movie")[0].find_all("movieCd").text #오류남
'''
AttributeError: ResultSet object has no attribute "text". You're probably treating a list of elements like a single element. Did you call find_all() when you meant to call find()?

'''

soup.find_all("movie")[0].find_all("movieCd")[0].text
#2025A806

#cf) 나중에 일을 할 때에는 이런 에러 체크도 하나씩 다 하는 것을 추천
# => 대신 수업은 적당하게 에러 처리만 하는 것이니 감안해서 봐주십시오
soup.find_all("movie")[0].find("movieNm").text
#구룡성채: 철권고영

soup.find_all("movie")[0].find("movieNmEn").text
#Kowloon Walled City

soup.find_all("movie")[0].find("openDt").text
# --> tag는 정확히 있었기에 에러가 없이 진행이 되고 값은 빈 문자열

soup.find_all("movie")[0].find("peopleNm").text
#오류남
#AttributeError: 'NoneType' object has no attribute 'text'

if soup.find_all("movie")[0].find("peopleNm") != []:
    print(soup.find_all("movie")[0].find("peopleNm").text)
else:
    print("감독이름X")
    
    

idx = 4
print(soup.find_all("movie")[idx].find_all("movieCd")[0].text)
print(soup.find_all("movie")[idx].find("movieNm").text)
print(soup.find_all("movie")[idx].find("movieNmEn").text)
print(soup.find_all("movie")[idx].find("openDt").text)
if soup.find_all("movie")[idx].find_all("peopleNm")!= []:
    print(soup.find_all("movie")[idx].find("peopleNm").text )
else:
    print("감독이름X")
'''
20257190
챕터:로브
Chapter: love

감독이름X
'''

# soup.find_all("movie")[idx] ==> 롤링하자.

movie_list = []
for idx, data in enumerate( soup.find_all("movie") ) :
    # idx : 개별 영화의 정수인덱스,,,==> 진행 상황 체크..if idx % 1000 ==0 etc
    # data : 개별 영화에 대한 xml 형식의 자료!!!
    i_dict = {"code":"", "title":"", "e-title":"", "openday":"", "dir_name":""}
    # -=-->
    i_dict["code"] = data.find_all("movieCd")[0].text
    i_dict["title"] = data.find("movieNm").text
    i_dict["e-title"] = data.find("movieNmEn").text
    i_dict["openday"] = data.find("openDt").text
    if data.find_all("peopleNm")!= []:
        i_dict["dir_name"] = data.find("peopleNm").text
    # ----------
    movie_list.append( i_dict )
print("Done!!!")
pd.DataFrame(movie_list)

'데이터분석 > Pandas' 카테고리의 다른 글

[Python] Pandas 08 _ dart_site  (5) 2025.08.21
[Python] Pandas 07 _ json_kobis_api  (2) 2025.08.20
[Python] pandas 05_kobis_api_json  (0) 2025.08.19
[Python] Pandas 04 _ json  (0) 2025.08.19
[Python] Pandas 03 _ pandas_2D_DataFrame  (3) 2025.08.19