DRUNKEN KEVIN

OpenDart 활용기, XML파일 다운로드 안 받고 고유 번호(기업 코드) 불러오기

2021. 8. 6. 23:35

가상
반응형

 

 금융감독원 OpenDART에서는 다양한 재무 정보에 대해 조회할 수 있는 API를 제공한다. 정말 방대한 수의 기업과 그 재무정보를 내 입맛에 맞게 가공하기 위해서는 이 API의 활용이 필수이다.

 

 그 첫걸음으로 OpenDart에서 기업 정보를 불러오는 것을 해보기로 하자. 재무정보에 대한 API들을 호출하기 위해서는 기업 코드를 넣어서 호출을 해줘야 한다. 기업 코드를 받아오는 API가 있는데 해당 정보가 Zip File로 응답이 온다. 귀찮게..

 

 Zip File을 받아 압축을 풀어 그 안에 있는 XML 파일에서 정보를 추출하면 된다. 현재 개발 도구로 구글 Colab을 쓰고 있다. XML File을 구글 드라이브에 저장해서 쓰고 있는데, 처음으로 접속해서 프로그램을 실행하면 매번 구글 드라이브 인증을 해줘야 해서 매우 귀찮다.

 

 그래서 굳이 XML로 파일을 저장하지 않고, 바로 변수에 담아서 기업 코드를 받아오는 코드를 짜보았다. 굿바이 구글 드라이브 인증.

 

 먼저 Python으로 짠 전체 코드를 공개! 삼성전자의 기업 코드를 받아오는 예시이다.

 

import pandas as pd
import requests
import xml.etree.ElementTree as et
from io import BytesIO
from zipfile import ZipFile

### OPENDART 개발 가이드
# https://opendart.fss.or.kr/guide/main.do?apiGrpCd=DS001
api_key = 'OPEN DART에서 받은 값'

# OpenDART에서 Zipfile 받아와 객체에 저장하기
u = requests.get('https://opendart.fss.or.kr/api/corpCode.xml', params={'crtfc_key':api_key})
zipfile_bytes = u.content
zipfile_obj = ZipFile(BytesIO(zipfile_bytes))

# 압축을 풀어서 XML File을 string으로 담기
xmlfile_objs = {name: zipfile_obj.read(name) for name in zipfile_obj.namelist()}
xml_str = xmlfile_objs['CORPCODE.xml'].decode('utf-8')

# XML String을 가져와서 DataFrame에 담기
xroot = et.fromstring(xml_str)

df_cols = ["corp_code", "corp_name", "stock_code", "modify_date"]
rows = []

for node in xroot: 
    res = []
    for el in df_cols[0:]: 
        if node is not None and node.find(el) is not None:
            res.append(node.find(el).text)
        else: 
            res.append(None)
    rows.append({df_cols[i]: res[i] 
                  for i, _ in enumerate(df_cols)})

df = pd.DataFrame(rows, columns=df_cols)

# DataFrame 검색
df[(df['corp_name'] == '삼성전자')].iloc[0].corp_code

 

 디테일하게 이해하고 싶은 분들을 위해 코드를 하나 하나 뜯어보자. (관심 없으신 분들은 이제 Ctrl + W를 누릅니다.)

 

  • pandas는 Python에서 데이터 분석을 위해 쓰는 라이브러리로 DataFrame이 표 형태의 데이터를 다루기 편해 사용하였다.
  • requests는 OpenDart API를 호출하기 위한 HTTP 라이브러리
  • xml은 XML 형태의 데이터를 다루기 위한 라이브러리
  • BytesIO는 기업 코드를 받아오면 bytes 타입이 되는데 그것을 ZipFile 형태로 변환하기 위한 라이브러리이다.
  • ZipFile을 말 그대로 압축파일을 다루기 위한 라이브러리

 

requests를 통해 기업 코드를 불러오는 API를 호출한다. 파라미터 변수로는 crtfc_key에 OpenDART에서 발급받은 API KEY를 사용하면 된다. Response로 200(OK)을 받으면 성공!

 

앞서 말했듯이, 해당 API를 호출하면 Zip File → XML File → XML String로 변환해야 하는데, API로 반환받은 값은 bytes 타입이 된다. 이에 이걸 아래와 같이 ZilFile로 변환해준다.

 

ByteIO를 이용해 bytes 데이터를 ZipFile로 변환하였다. 이제 압축을 풀어보자.

 

ZipFile 데이터가 가지고 있는 파일을 열어보면 CORPCODE.xml 이라는 파일이 하나 들어있다. 이제 저 파일의 데이터를 뽑아보자.

 

데이터를 열어보니, 보인다! XML 내용이 보인다. 물론, 처음에 XML 데이터 형태로 불러오게 되니, decode 함수를 호출하여 문자열(str)로 변경하여 준다.

 

위의 코드는 XML 문자열을 가지고 각 요소에 맞게 분할해주는 코드이다. list 요소 안에는 각 기업의 코드(corp_code), 이름(corp_name), 주식 코드(stock_code), 수정 날짜(modify_date)로 이루어져 있다. 네 가지 요소로 하나의 DataFrame의 한 행을 만들어준다.

 

제대로 읽어서 변환이 되었는지 확인해보자.

 

87346개의 기업 정보를 불러왔다. 오예! 이제 아래와 같이 기업 코드를 불러와 재무제표 API를 호출해보자!

 

 

허나, 분명 표준화된 API임에도 불구하고 각 기업마다 재무제표의 값이 달라 디버깅이 많이 필요했다. 다음으론 재무제표에서 매출액, 영업이익, 당기순이익 등에 대한 값을 가져오는 것을 포스팅해보자.

 

반응형