본문 바로가기
Data Analysis

Crawling in NAVER Financial Summary, Make PEG/EPS Growth Rate/OPM Growth Rate etc: 네이버 파이낸셜서머리 크롤링해서 PEG, EPS성장율, 영업이익증가율 등 만들고 차트 그리기

by but_poor 2022. 4. 22.

 

 

이전에는 개별종목 스크리닝을 손으로 긁어와서 엑셀로 작업했었는데,

 

자동화 툴을 벼르고 벼르다가 이제야 만들었어요.

 

중점을 둔 부분은, EPS성장율, 영업이익증가율 등 성장중에 중요한데 서머리에서 제공안하는 지표를 추가한 점,

 

이를 바탕으로 PEG를 만들어보고 추가한 점입니다. 그외에 매출액, 영업이익, PER등 기본적인 상대비교 지표 등도 추출하니까 참고하시기 좋을 거에요.

 

바로 갈게요

 

라이브러리 임포트 합니다.

 

import matplotlib.pyplot as plt
import matplotlib.font_manager as fm 
import os, copy, sys, platform
import matplotlib as mpl
from matplotlib import rc
path = 'C:\\Windows\\Fonts\\Gothic.ttf' 
font_name = fm.FontProperties(fname=path, size=10).get_name()

from bs4 import BeautifulSoup
from selenium import webdriver
import pandas as pd
import numpy as np
import FinanceDataReader as fdr

rc('font', family=font_name)
rc('figure', figsize = (20,10))
rc('axes', grid = True)
rc('xtick', c = 'white')
rc('ytick', c = 'white')

 

위 코드블록 아래쪽에 들어가 있는 부분은 제 주피터 노트북이 다크모드여서 추가로 플롯 커스터마이징 한 부분인데요. 안하셔도 되구요. 음... figure size는 저정도로 하시는게 보시는게 좋을거에요. 저건 추천합니다. 나머지는 안하셔도 돼요. 오히려 플롯 라벨 폰트 칼라 저렇게 바꾸시면 하얀 글자라서 안보이실 수도...?

 

 

### 네이버 금융 Financial Summary 불러오기 ###
def Naver_FS(code, fin_type='0', freq_type='Q') :
# code: 종목코드
# fin_type = '0': 재무제표 종류 (0: 주재무제표, 1: GAAP개별, 2: GAAP연결, 3: IFRS별도, 4:IFRS연결)
# freq_type = 'Y': 기간 (Y:년, Q:분기)
    print('running : ', code, '...')
    url = f'https://navercomp.wisereport.co.kr/v2/company/c1010001.aspx?cmp_cd={code}&fin_typ={fin_type}&freq_typ={freq_type}'

    driver = webdriver.Chrome(r"C:\Users\chromedriver.exe")
    driver.get(url)
    driver.find_elements_by_xpath('//*[@class="schtab"][1]/tbody/tr/td[4]')[0].click()
    html = driver.page_source
    soup = BeautifulSoup(html, 'html.parser')
    table = soup.select('table')

    # html → 문자열
    table_html = str(table)

    # pandas의 read_html 로 테이블 정보 읽기
    table_df_list = pd.read_html(table_html)

    # Data Frame 선택
    fs = table_df_list[12] # 12 : Financial Summary
    
    fs.set_index(('주요재무정보','주요재무정보'), inplace=True)
    fs.index.rename('주요재무정보', inplace=True) #주요재무정보로 인덱싱
    fs.columns = fs.columns.droplevel(0) # 불필요한 열 제거
    
    driver.close()
    return fs

 

이 코드 보시면 좀 헷갈리는 부분이 있으실 수 있는데요.

 

아래 그림을 참고해주세요(위 코드랑 같은 코드에요 :)  설명용으로 캡쳐)

예전에는 네이버 파이낸셜 서머리에서 분기별 자료를 가져오려면

ⓐ요기 표시된 두 군데의 방법으로 저 주소로 가서 분기 파이낸셜 서머리를 가져왔었는데

 

지금은 자바스크립트 동적 웹이라서 그렇게 워킹을 안하더라구요.

 

그래서 ⓑ요기를 통해서 직접 분기 탭을 클릭하는 방식으로 바꿨어요ㅎㅎ

 

근데 ⓐ요기를 안 뺀거는 네이버에서 또 언제 페이지 디자인을 바꿀지 몰라서 그냥 뒀어요!ㅎㅎ 그래도 잘 돌아가니까 그냥 쓰셔도 될거에요 :)

 

#스크리닝할 종목 리스트화, Financial Summary 크롤링
screening_list = ['214150', '287410', '100120', '085370', '164060']
for i in range(len(screening_list)):
    globals()[f'df{i}'] = Naver_FS(screening_list[int(f'{i}')])

 

이제 요거 돌리면 자동으로 파이낸셜 서머리 테이블을 크롤링해오구요...

 

제 로컬 데이터 나오는 부분만 가린거에요ㅎㅎ

지금 제가 써놓은 저 종목 코드들은 이번에 관심있게 보고 있는 의료미용기기 5개 종목이구요.

 

보고싶은 종목 코드 넣으면 갯수에 관계없이 알아서 크롤링 해오게 만들었어요ㅎㅎ

 

#영업이익증가율 만들어서 DF에 추가하는 함수 선언 및 실행
def OPGR(df) :
    new_data = [np.NaN]
    for i in range(len(df.columns)) :
        if i == 7 :
            pass
        else : 
            if df.iloc[1, i] < 0 : 
                x = 1
                new_data.append(round((df.iloc[1, i + 1] - df.iloc[1, i]) / x * 100, 2))
            else :
                x = df.iloc[1, i]
                new_data.append(round((df.iloc[1, i + 1] - df.iloc[1, i]) / x * 100, 2))
    df.loc['영업이익증가율'] = new_data
    return df

for i in range(len(screening_list)) :
    OPGR(globals()[f'df{i}'])
    
#EPS성장율 만들어서 DF에 추가하는 함수 선언 및 실행
def EPSGR(df) :
    new_data = [np.NaN]
    for i in range(len(df.columns)) :
        if i == 7 :
            pass
        else : 
            if df.iloc[25, i] < 0 : 
                x = 1
                new_data.append(round((df.iloc[25, i + 1] - df.iloc[25, i]) / x * 100, 2))
            else :
                x = df.iloc[25, i]
                new_data.append(round((df.iloc[25, i + 1] - df.iloc[25, i]) / x * 100, 2))
    df.loc['EPS성장율'] = new_data
    return df

for i in range(len(screening_list)) :
    EPSGR(globals()[f'df{i}'])
    
#PEG 만들어서 DF에 추가하는 함수 선언 및 실행
def PEG(df) :
    new_data = []
    for i in range(len(df.columns)) :
        if df.iloc[34, i] < 0 or df.iloc[34, i] == np.NaN: 
            x = 1
            new_data.append(round(df.iloc[26, i] / x, 2))
        else :
            x = df.iloc[34, i]
            new_data.append(round(df.iloc[26, i] / x, 2))
    df.loc['PEG'] = new_data
    return df

for i in range(len(screening_list)) :
    PEG(globals()[f'df{i}'])

 

이제 이 부분에선 영업이익증가율, EPS증가율, PEG를 계산해서 데이터프레임에 추가하는 함수들을 선언하고 실행하는 기능을 수행해요.

 

이제 본격적으로 차트를 뽑아보면

 

#매출액 PLOT 만들기
revenue = pd.DataFrame()
for j, i in enumerate(screening_list) : 
    revenue[f'{i}'] = globals()[f'df{j}'].loc['매출액']
revenue.plot()

revenue

이렇게 출력되게 해놨어요

 

나머지 부분은 출력은 빼고 코드만 적을게요

 

#영업이익 PLOT 만들기
opm = pd.DataFrame()
for j, i in enumerate(screening_list) : 
    opm[f'{i}'] = globals()[f'df{j}'].loc['영업이익']
opm.plot(figsize = (20,10))
#영업이익율 PLOT 만들기
opmr = pd.DataFrame()
for j, i in enumerate(screening_list) : 
    opmr[f'{i}'] = globals()[f'df{j}'].loc['영업이익률']
opmr.plot()
#ROE PLOT 만들기
roe = pd.DataFrame()
for j, i in enumerate(screening_list) : 
    roe[f'{i}'] = globals()[f'df{j}'].loc['ROE(%)']
roe.plot()
#EPS PLOT 만들기
eps = pd.DataFrame()
for j, i in enumerate(screening_list) : 
    eps[f'{i}'] = globals()[f'df{j}'].loc['EPS(원)']
eps.plot()
#PER PLOT 만들기
per = pd.DataFrame()
for j, i in enumerate(screening_list) : 
    per[f'{i}'] = globals()[f'df{j}'].loc['PER(배)']
per.plot()
#PEG PLOT 만들기
peg = pd.DataFrame()
for j, i in enumerate(screening_list) : 
    peg[f'{i}'] = globals()[f'df{j}'].loc['PEG']
peg.plot()
#영업이익증가율 PLOT 만들기
opgr = pd.DataFrame()
for j, i in enumerate(screening_list) : 
    opgr[f'{i}'] = globals()[f'df{j}'].loc['영업이익증가율']
opgr.plot(figsize = (20,10))

 

성투하세요!!! ♥

댓글