전 블로그에서 전자공시 OPEN API를 사용하여 공시대상회사를 XML 포맷으로 가공하였다. xmltodict library를 사용하여 XML을 Python dictionary 타입으로 변경하고 추후에는 대상데이터를 pandas로 변환해본다.
관련 포스트 시리즈
- python - 다트.전자공시 Open API 활용(1), 전체 상장사(고유코드) 조회 - HTTP로 얻은 Stream zip파일 읽기
- python - 다트.전자공시 Open API 활용(2), 기업개황 응답데이터 JSON 핸들링( JSON 기초 )
- python - 다트.전자공시 Open API 활용(4), 공시대상회사 조회 - 대화형 콘솔 만들기
- 전자공시 Open API 활용(5), 기업 재무제표 조회 API ( 분기/반기/사업보고서 - 재무상태표, 손익계산서 )
- 전자공시 Open API 활용(6), pandas 기초 - 재무제표 json 데이터를 pandas DataFrame으로 변환
1. Install Library
pip install xmltodict
xmltodict는 xml을 python dictionary 포맷으로 컨버전해주는 외부 유틸라이브러리 이다.
https://github.com/martinblech/xmltodict
2. Source code
from urllib.request import urlopen # HTTP 요청처리
from zipfile import ZipFile # 공시회사정보 zipfile 처리
from io import BytesIO # stream 데이터를 메모리에 적재
import os # 현재 디렉토리 정보를 얻기 위해
import xmltodict # xml을 dict로 파싱
from pathlib import Path # file 존재유무 체크 유틸
def bind_params(params : dict):
url_params = []
for key in params:
url_params.append(key + '=' + params[key])
return url_params
def has_corpfile():
dirpath = os.getcwd()
if Path(dirpath + '\CORPCODE.xml').is_file():
return True
else:
return False
# 파일존재 체크 다른 방법들..
# if os.path.isfile(dirpath + '\CORPCODE.xml'):
# return True
# else:
# return False
# try:
# open(dirpath + '\CORPCODE.xml', 'r')
# return True
# except FileNotFoundError:
# return False
def get_corp_xml(url, params):
if has_corpfile():
dirpath = os.getcwd()
return open(dirpath + '\CORPCODE.xml', 'r').read()
else:
url = url + '&'.join(bind_params(params))
resp = urlopen(url)
# zip으로 저장할경우
# f = open( 'corpCode.zip', 'wb' )
# f.write(resp.read())
# f.close()
# zip파일내용을 풀어 저장한다.
zipfile = ZipFile(BytesIO(resp.read()))
print(zipfile.namelist())
for name in zipfile.namelist():
z = zipfile.open(name)
with open(name, 'w') as codefile:
for l in z.readlines():
codefile.write(l.decode())
dirpath = os.getcwd()
return open(dirpath + '\CORPCODE.xml', 'r').read()
""" Biz Start """
url = 'https://opendart.fss.or.kr/api/corpCode.xml?'
params = {
'crtfc_key':'Insert your crtfc_key', # API 인증키
}
corp_xml = get_corp_xml(url, params)
has_corpfile() 는 받아온 Zipfile이 존재하는 경우 API 중복 호출을 피하기 위해 설계되었다. 파일의 존재유무를 체크 하는 방법은 아래 블로그를 참조한다.
https://youngwonhan-family.tistory.com/9
위 소스코드의 결과는 다음과 같다. ( 콘솔로 프린트 하는경우 양이 많으므로 유의할 것 )
<result>
....
<list>
<corp_code>00434438</corp_code>
<corp_name>KTB에이플러스2호혼합형사모펀드</corp_name>
<stock_code> </stock_code>
<modify_date>20170630</modify_date>
</list>
<list>
<corp_code>00286877</corp_code>
<corp_name>비비앤씨</corp_name>
<stock_code> </stock_code>
<modify_date>20170630</modify_date>
</list>
....
</result>
위 XML 포맷을 Dictionary로 변환하기 위해 xmltodict의 parse 함수를 사용한다.
corp_dict = xmltodict.parse(corp_xml)
print(type(corp_dict))
print(corp_dict)
OUTPUT
<class 'collections.OrderedDict'>
....
OrderedDict([('corp_code', '00215824'), ('corp_name', '현대화섬'), ('stock_code', None), ('modify_date', '20170630')]), OrderedDict([('corp_code', '00409380'), ('corp_name', '미래에셋
오리엔탈주식혼합형펀드'), ('stock_code', None), ('modify_date', '20170630')]), OrderedDict([('corp_code', '00471730'), ('corp_name', '태양약품'), ('stock_code', None), ('modify_date', '20170630')])
....
- OrderedDict 는 순서가 있는 dictionary 이다. Regualr Dict와의 차이점은 아래 사이트 참고
https://pymotw.com/2/collections/ordereddict.html
Dictionary로 변환해 성공했다. 마지막으로 대상데이터 중 종목코드(stock_code)가 None이 아닌 대상만 추출해보자.
# reulst > list 추출
corp_list = corp_dict['result']['list']
# stock_code가 None이 아닌 대상만 다시 추출한다.
corp_list_has_stockcode = [x for x in corp_list if x['stock_code'] is not None]
print(len(corp_list_has_stockcode))
OUTPUT
3179
블로그 작성일 기준 3179개의 종목코드를 갖는 회사가 추출되었다.
다음 장에는 추출된 상장회사 목록을 활용하여 콘솔에서 회사명을 입력받아 회사의 기본정보를 추출하는 대화형 프로그래밍을 개발해보도록 한다.
반응형