본문 바로가기
개발일지

파이썬 데이터분석 3주차 정리 (OpenDart의 API다루기)

by 디지털뚜이 2022. 12. 18.

스파르타코딩클럽 파이썬 데이터분석 공부 3주차 개발일지 기록

dart-fss (재무제표 일괄추출) 라이브러리 이용

!pip install dart-fss # dart-fss (재무제표 일괄추출) 라이브러리 설치 (구글에서 검색해보고 도큐먼트 참고해서 스스로 연구)
import dart_fss as dart_fss
import pandas as pd

api_key = 'a574aa79b901e3f02c2a84c380caa3d257fee7de' #발급받은 API키 입력
# OpenDart사이트 > 인증키신텅/관리 > 오픈API이용현황

dart_fss.set_api_key(api_key=api_key) #API키 세팅

corp_list = dart_fss.get_corp_list() #회사리스트를 받아서 변수에 값을 넣음

corp_list.corps #회사명 
 
all = dart_fss.api.filings.get_corp_code() 
# dart-fss 사이트 도큐먼트보고 가져온것 
# 기능 : DART에 등록되어있는 공시대상회사의 고유번호,회사명,대표자명,종목코드, 최근변경일자 다운로드

all[0#반복되는 데이터이니 첫번째값만 불러서 어떤 형식인지 확인
 
pd.DataFrame(all) #판다스 표식화로 편하게 확인
 
# stock_code가 주식종목코드인데 비상장사(None)가 많아서 분류

df = pd.DataFrame(all)

df_listed = df[df['stock_code'].notnull()] # None은 문자열이 아닌 비어있다는 뜻
# 비어있지 않은 조건은 .notnull()로 씀
df_non_listed = df[df['stock_code'].isnull()] #값이 들어있다는 조건

df_non_listed.count() #비상장회사 몇개인지 보기
 

 

엑셀로 불러오기

df_listed.to_excel('상장종목.xlsx')
df_non_listed.to_excel('비상장종목.xlsx')

 

 

corp_code = df_listed[df_listed['corp_name'] == '카카오'].iloc[0,0#회사명이 카카오의 회사코드를 변수에 입력 (회사코드는 1열에 있음)

dart_fss.api.filings.get_corp_info(corp_code) # dart-fss의 기업 개황 조회 기능 복사 (도큐먼트에 회사코드를 넣으라고 해서 위에 회사코드를 변수로 빼온것임)

# 무엇인지 잘 모르는 항목은 OpenDart사이트 > 개발가이드 > 공시정보 > 기업개황에서 확인가능

 

# 정기보고서(사업, 분기, 반기보고서) 내에 미등기임원 보수현황을 제공합니다.
# dart_fss.api.info.unrst_exctv_mendng_sttus(corp_code, bsns_year, reprt_code, api_key=None)

data = dart_fss.api.info.unrst_exctv_mendng_sttus(corp_code, '2021''11011'# 항목적는 방법 사이트에 있음
pd.DataFrame(data['list']) # 주요정보가 list열에 포함됨
# 임원, 주요 주주 소유 보고
data = dart_fss.api.shareholder.elestock(corp_code)
pd.DataFrame(data['list'])
# 위의 임원및주주 중특정사람 정보

df_temp = pd.DataFrame(data['list'])
df_temp[df_temp['repror'] == '김범수']
 
# 연봉왕 보기

def get_salary_top(name):
  corp_code = df_listed[df_listed['corp_name'] == name].iloc[0,0]
  data = dart_fss.api.info.indvdl_by_pay(corp_code, '2021''11011')
  
  df_temp = pd.DataFrame(data['list'])
  df_temp = df_temp[['corp_name','nm','ofcps','mendng_totamt']]
  df_temp.columns = ['기업명','이름','역할','보수']
  df_temp['보수'] = pd.to_numeric(df_temp['보수'].str.replace(',','')) # 보수가 ,를 포함한 문자열로 인식되어 ','를 ''로 바꾸고 숫자로 바꿈
  df_temp = df_temp.sort_values(by='보수',ascending=False#위에서 숫자로 바꿨기 때문에 정렬가능
  
  return df_temp
# 여러회사 연봉왕 뽑기

names = ['삼성전자','LG에너지솔루션','SK하이닉스','NAVER','삼성바이오로직스','삼성전자우','카카오','삼성SDI','현대차','LG화학','기아','POSCO홀딩스','KB금융','카카오뱅크','셀트리온','신한지주','삼성물산','현대모비스','SK이노베이션','LG전자','카카오페이','SK','한국전력','크래프톤','하나금융지주','LG생활건강','HMM','삼성생명','하이브','두산중공업','SK텔레콤','삼성전기','SK바이오사이언스','LG','S-Oil','고려아연','KT&G','우리금융지주','대한항공','삼성에스디에스','현대중공업','엔씨소프트','삼성화재','아모레퍼시픽','KT','포스코케미칼','넷마블','SK아이이테크놀로지','LG이노텍','기업은행']

dfs = [] #df들을 넣을 배열변수 선언

for name in names:
  try:
    df = get_salary_top(name)
    dfs.append(df)
  except:
    print(f'없음 - {name}')

df_result = pd.concat(dfs) # 엑셀로 비유하면 여러 시트(표데이터)가 들어있어 dataframe하면 테이블이 나열
# pd.concat을 쓰면 여러 표데이터를 공통되는 항목으로 묶어서 하나의 표같이 다 표현
df_result.sort_values(by='보수',ascending=False).head(30)

 

최대 주주의 주식 변동 모아보기

def get_shareholders(corp_code):
  data = dart_fss.api.info.hyslr_sttus(corp_code, '2021''11011')
  df = pd.DataFrame(data['list'])

  df = df[['corp_name','nm','relate','bsis_posesn_stock_qota_rt','trmend_posesn_stock_qota_rt','rm']]
  df.columns = ['회사명','이름','관계','기초지분율','기말지분율','비고']

  df = df[df['관계'].notnull()]

  df['기초지분율'] = pd.to_numeric(df['기초지분율'])
  df['기말지분율'] = pd.to_numeric(df['기말지분율'])

  return df.sort_values(by='기초지분율',ascending=False).head(3)
 
corp_code = df_listed[df_listed['corp_name'] == '카카오'].iloc[0,0]

get_shareholders(corp_code)
 
 

상장 종목 중 10개만 추려내기 (증감이 큰 순서대로 정렬하기)


corp_codes = list(df_listed.sample(10)['corp_code'])

dfs = []
for corp_code in corp_codes:
  try:
    df = get_shareholders(corp_code)
    dfs.append(df)
  except:
    print(f'error - {corp_code}')

df_result = pd.concat(dfs)

df_result['증감'] = df_result['기말지분율'] - df_result['기초지분율']

df_result.sort_values(by='증감',ascending=False)

 

돈 많이 번 회사 찾기 (재무제표)

def get_profit(corp_name):
  corp_code = df_listed[df_listed['corp_name'] == corp_name].iloc[0,0]
  data = dart_fss.api.finance.fnltt_singl_acnt(corp_code, '2021''11011')
  df = pd.DataFrame(data['list'])

  df = df[df['fs_div'] == 'CFS']

  df['name'] = corp_name
  cond = df['account_nm'] == '이익잉여금'
  df = df[cond]

  df = df[['name','thstrm_amount','frmtrm_amount']]
  df.columns = ['이름','당기','전기']

  df['당기'] = pd.to_numeric(df['당기'].str.replace(',',''))
  df['전기'] = pd.to_numeric(df['전기'].str.replace(',',''))

  df['증감'] = df['당기'] - df['전기']
  df['증감율'] = abs(df['증감'])/abs(df['전기'])

  return df
 
names = list(df_listed.sample(10)['corp_name'])

dfs = []
for name in names:
  try:
    df = get_profit(name)
    dfs.append(df)
  except:
    print(f'error - {name}')

df_result = pd.concat(dfs)
df_result.sort_values(by='증감율',ascending=False)
 

비상장 종목 분석하기 (사업보고서 주요정보만 분석가능)

# 배당 항목을 통해 당기순이익을 확인
def get_earning(name):
  corp_code = df_non_listed[df_non_listed['corp_name'] == name].iloc[0,0]
  data = dart_fss.api.info.alot_matter(corp_code, '2021''11011')
  df = pd.DataFrame(data['list'])

  df = df[df['se'] == '(연결)당기순이익(백만원)'][['corp_name','thstrm','frmtrm','lwfr']]

  df.columns = ['기업명','2021','2020','2019']
  df['2021'] = pd.to_numeric(df['2021'].str.replace(',',''))
  df['2020'] = pd.to_numeric(df['2020'].str.replace(',',''))
  df['2019'] = pd.to_numeric(df['2019'].str.replace(',',''))

  return df
 
get_earning('야놀자')
names = list(df_non_listed.sample(10)['corp_name'])

dfs = []
for name in names:
  try:
    df = get_earning(name)
    dfs.append(df)
  except:
    print(f'error - {name}')

df_result = pd.concat(dfs)
df_result

#정보가 없어서 10개중 1개도 안나와 에러날 가망성 큼