[Python] 웹에서 XML 포맷 데이터를 Python으로 읽어와서 DataFrame으로 만들기
Python 분석과 프로그래밍/Python 데이터 전처리 2019. 9. 4. 23:38지난번 포스팅에서는 웹에서 JSON 포맷 파일을 읽어와서 pandas DataFrame으로 변환하는 방법에 대해서 소개하였습니다.
이번 포스팅에서는 JSON과 함께 웹 애플리케이션에서 많이 사용하는 데이터 포맷인 XML (Extensible Markup Language) 을 Python을 사용하여 웹으로 부터 읽어와서 파싱(parsing XML), pandas DataFrame으로 변환하여 분석과 시각화하는 방법을 소개하겠습니다.
XML (Extensible Markup Language) 인간과 기계가 모두 읽을 수 있는 형태로 문서를 인코딩하는 규칙의 집합을 정의하는 마크업 언어(Markup Language) 입니다. XML의 설계 목적은 단순성, 범용성, 인터넷에서의 활용성을 강조점을 둡니다. XML은 다양한 인간 언어들을 유니코드를 통해 강력하게 지원하는 텍스트 데이터 포맷입니다. 비록 XML의 설계가 문서에 중점을 두고는 있지만, XML은 임의의 데이터 구조를 띠는 웹 서비스와 같은 용도의 재표현을 위한 용도로 광범위하게 사용되고 있습니다.- from wikipedia (https://en.wikipedia.org/wiki/XML) -
XML 은 아래와 같이 생겼는데요, HTML, JSON과 왠지 비슷하게 생겼지요?
[ XML format data 예시 ]
<CATALOG> <CD> </CATALOG> - source: https://www.w3schools.com/xml/cd_catalog.xml - |
[ Python으로 웹에서 XML 데이터를 읽어와서 pandas DataFrame으로 만들기 코드 예제 ]
(1) Import Libraries
먼저 XML 을 파싱하는데 필요한 xml.etree.ElementTree 모듈과 웹 사이트에 접속해서 XML 파일을 읽을 수 있도록 요청하는 urllib 모듈을 불러오겠습니다. XML 데이터를 나무(Tree)에 비유해서 뿌리(root)부터 시작하여 줄기, 가지, 잎파리까지 단계적으로 파싱한다는 의미에서 모듈 이름이 xml.etree.ElementTree 라고 생각하면 됩니다.
import pandas as pd import xml.etree.ElementTree as ET import sys if sys.version_info[0] == 3: from urllib.request import urlopen else: from urllib import urlopen |
Python 3.x 버전에서는 'from urllib.request import urlopen'으로 urllib 모듈의 request 메소드를 import해야 하며, 만약 Python 3.x 버전에서 아래처럼 'from urllib import urlopen' 을 사용하면 'ImportError: cannot import name 'urlopen'' 이라는 ImportError가 발생합니다.
# If you are using Python 3.x version, then ImportError will be raised as below from urllib import urlopen --------------------------------------------------------------------------- ImportError Traceback (most recent call last) <ipython-input-2-dbf1dbb53f94> in <module>() ----> 1 from urllib import urlopen ImportError: cannot import name 'urlopen' |
(2) Open URL and Read XML data from Website URL
이제 "https://www.w3schools.com/xml/cd_catalog.xml" 사이트에서 XML 포맷의 CD catalog 정보를 문자열(string)로 읽어와보겠습니다.
url = "https://www.w3schools.com/xml/cd_catalog.xml" response = urlopen(url).read() xtree = ET.fromstring(response) xtree <Element 'CATALOG' at 0x00000219E77DCCC8>
|
(3) Parsing XML data into text by iterating through each node of the tree
다음으로 for loop을 돌면서 나무의 노드들(nodes of tree)에서 필요한 정보를 찾아 파싱(find and parse XML data)하여 텍스트 데이터(text)로 변환하여 사전형(Dictionary)의 키, 값의 쌍으로 차곡차곡 저장(append)을 해보겠습니다.
rows = [] # iterate through each node of the tree for node in xtree: n_title = node.find("TITLE").text n_artist = node.find("ARTIST").text n_country = node.find("COUNTRY").text n_company = node.find("COMPANY").text n_price = node.find("PRICE").text n_year = node.find("YEAR").text
rows.append({"title": n_title, "artist": n_artist, "country": n_country, "company": n_company, "price": n_price, "year": n_year})
|
(4) Convert XML text data into pandas DataFrame
# convert XML data to pandas DataFrame columns = ["title", "artist", "country", "company", "price", "year"] catalog_cd_df = pd.DataFrame(rows, columns = columns) catalog_cd_df.head(10)
|
(5) Change data type from string object to float64, int32 for numeric data
아래에 df.dtypes 로 각 칼럼의 데이터 형태를 확인해보니 전부 문자열 객체(string object)입니다. astype()을 이용하여 칼럼 중에서 price는 float64, year는 int32로 변환을 해보겠습니다.
catalog_cd_df.dtypes title object
artist object
country object
company object
price object
year object
dtype: object import numpy as np catalog_cd_df = catalog_cd_df.astype({'price': np.float, 'year': int}) catalog_cd_df.dtypes title object
artist object
country object
company object
price float64
year int32
dtype: object |
(6) Calculate mean value of price by Country and plot bar plot it
country_mean = catalog_cd_df.groupby('country').price.mean() country_mean country
EU 9.320000
Norway 7.900000
UK 8.984615
USA 9.385714
Name: price, dtype: float64 country_mean_df = pd.DataFrame(country_mean).reset_index() import seaborn as sns sns.barplot(x='country', y='price', data=country_mean_df) plt.show()
|
이상으로 웹에서 XML 데이터를 Python으로 읽어와서 파싱 후 pandas DataFrame으로 변환하는 방법에 대한 소개를 마치겠습니다.
Python으로 JSON 파일 읽기, 쓰기는 https://rfriend.tistory.com/474 를 참고하세요.
Python으로 YAML 파일 읽기, 쓰기는 https://rfriend.tistory.com/540 를 참고하세요.
많은 도움이 되었기를 바랍니다.
이번 포스팅이 도움이 되었다면 아래의 '공감~'를 꾹 눌러주세요. :-)