<jupyter_start><jupyter_text>Financial Statement Crawling<jupyter_code>import dart_fss as dart

api_key='998bebe5acc23a9e8321f35d52181529440718e8'
dart.set_api_key(api_key=api_key)

# DART 에 공시된 회사 리스트 불러오기
corp_list = dart.get_corp_list()

# 삼성전자 검색
samsung = corp_list.find_by_corp_name('삼성전자', exactly=True)[0]

# 2012년부터 연간 연결재무제표 불러오기
fs = samsung.extract_fs(bgn_de='20120101', report_tp='quarter')

# 재무제표 검색 결과를 엑셀파일로 저장 ( 기본저장위치: 실행폴더/fsdata )
fs.save('samsumg_test')
fs.save(filename='samsung_test.xlsx')
# 연결재무상태표
df_bs = fs['bs'] # 또는 df = fs[0] 또는 df = fs.show('bs')
# 연결재무상태표 추출에 사용된 Label 정보
labels_bs = fs.labels['bs']

# 연결손익계산서
df_is = fs['is'] # 또는 df = fs[1] 또는 df = fs.show('is')
# 연결손익계산서 추출에 사용된 Label 정보
labels_is = fs.labels['is']

# 연결포괄손익계산서
df_ci = fs['cis'] # 또는 df = fs[2] 또는 df = fs.show('cis')
# 연결포괄손익계산서 추출에 사용된 Label 정보
labels_ci = fs.labels['cis']

# 현금흐름표
df_cf = fs['cf'] # 또는 df = fs[3] 또는 df = fs.show('cf')
# 현금흐름표 추출에 사용된 Label 정보
labels_cf = fs.labels['cf']

fs.show('fs',show_class=True, show_concept=True)<jupyter_output><empty_output><jupyter_text>stock price crawling<jupyter_code>import pandas as pd

stock_code = pd.read_excel('210509_kospi.xlsx',sheet_name='Sheet1', 
                          converters={'단축코드': str})
stock_code
stock_code=stock_code[['단축코드', '한글 종목약명']]
stock_code = stock_code.loc[lambda stock_code: stock_code['한글 종목약명'] == '현대차']
stock_code
# 네이버 금융 10년 주가 정보 수집 코드
import requests
from bs4 import BeautifulSoup
import xmltodict
import json

def get_daily_stock_price(stockCode, name, count):
    
    url = f'https://fchart.stock.naver.com/sise.nhn?symbol={stockCode}&timeframe=day&count={count}&requestType=0'
    
    rs = requests.get(url)
    dt = xmltodict.parse(rs.text)
    js = json.dumps(dt, indent=4)
    js = json.loads(js)
    
    data = pd.json_normalize(js['protocol']['chartdata']['item'])
    df = data['@data'].str.split('|', expand=True)
    df.columns = ['date', 'open', 'high', 'low', 'close', 'Volume']
    df['name'] = str(name) # 받아온 기업명 추가
    
    return df
tmp = []

for index, row in stock_code.iterrows():
    tmp.append(get_daily_stock_price(row['단축코드'], row['한글 종목약명'], '2500'))

tmp
df_final = pd.concat(tmp, ignore_index=True)
df_final
df_final.to_csv('HDMstockprice.csv', encoding='euc-kr')<jupyter_output><empty_output><jupyter_text>시총 가져오기<jupyter_code>import requests
from bs4 import BeautifulSoup

def get_market_price(pagecount):
    url = f'https://finance.naver.com/sise/sise_market_sum.nhn?sosok=0&page={pagecount}'
    
    res = requests.get(url)
    soup = BeautifulSoup(res.text, 'lxml')
    
    stock_list = soup.find("table", attrs={"class": "type_2"}).find("tbody").find_all("tr")
    
    tmp = []
    for stock in stock_list:
        if len(stock)>1:
            tmp.append(stock.get_text().split())

    
    tmp = pd.DataFrame(tmp).iloc[:,[1,6]]
    tmp = tmp.values.tolist()
    
    return tmp

pagecount = 9

tmp = []

for index in range(1,pagecount):
    index = str(index)
    tmp = tmp + get_market_price(index)
    
df
df = pd.DataFrame(tmp, columns=['회사','시가총액(억)'])
#df['시가총액(억)']=pd.to_numeric(df['시가총액(억)'])
df.to_excel('KospiMarketPrice.xlsx', encoding='euc-kr')

stock_head = soup.find("thead").find_all("th")
data_head = [head.get_text() for head in stock_head]

print(data_head)<jupyter_output>['N', '종목명', '현재가', '전일비', '등락률', '액면가', '시가총액', '상장주식수', '외국인비율', '거래량', 'PER', 'ROE', '토론실']<jupyter_text>ETF 일봉 크롤링<jupyter_code>import pandas as pd

etf_code = pd.read_excel('210509_koretf.xlsx',sheet_name='Sheet1', 
                          converters={'단축코드': str})
etf_code
etf_code = etf_code[['단축코드', '한글종목약명']]
#etf_code = etf_code.loc[lambda etf_code: etf_code['한글종목약명'] == 'KODEX 200']
etf_code
# 네이버 etf 주가 정보 수집 코드
import requests
from bs4 import BeautifulSoup
import xmltodict
import json

def get_daily_etf_price(etfCode, name, start, end):
    
    url = f'https://fchart.stock.naver.com/siseJson.naver?symbol={etfCode}&requestType=1&startTime={start}&endTime={end}&timeframe=day'
    
    rs = requests.get(url)
    dt = xmltodict.parse(rs.text)
    js = json.dumps(dt, indent=4)
    js = json.loads(js)
    
    data = pd.json_normalize(js['protocol']['chartdata']['item'])
    df = data['@data'].str.split('|', expand=True)
    df.columns = ['date', 'open', 'high', 'low', 'close', 'Volume', 'foreign']
    df['name'] = str(name) # 받아온 기업명 추가
    
    return df

get_daily_etf_price(etf_code['단축코드'], etf_code['한글종목약명'],'20200302', '20210507')
etf_list

import xmltodict
import datetime
import requests
from bs4 import BeautifulSoup
from itertools import islice
from datetime import datetime
import numpy as np

def get_etf_info(etfCode, start, end):
    ## etf 주가 정보
    url = f'https://api.finance.naver.com/siseJson.naver?symbol={etfCode}&requestType=1&startTime={start}&endTime={end}&timeframe=day'
    rs = requests.get(url)

    soup = BeautifulSoup(rs.text, 'html.parser')
    soup = soup.get_text().split()

    # 필요 없는 문자 지우기
    for i in range(0, len(soup)):
        soup[i] = soup[i].replace('\t','').replace('\n','').replace('\'','').replace(',','').replace('[','').replace(']','').replace('\"','')

    # 두 날짜 차이 구하기
    time1 = 20200304
    time2 = 20210509
    time1 = datetime((int)(time1/10000), (int)(time1%10000/100), (int)(time1%100),0,0,0)
    time2 = datetime((int)(time2/10000), (int)(time2%10000/100), (int)(time2%100))
    financial_timediff = (int)((time2 - time1).days/30) * 20
    financial_timediff = 293

    df_size = np.zeros(((int)(len(soup)/7),7))
    df = pd.DataFrame(df_size)
    soup = pd.DataFrame(soup)
  
    # 2D array
    for i in range(0, (int)(len(soup)/7)):
        for j in range(0, 7):
            df.iloc[i,j] = soup.iloc[7*i+j]
            
    return df

df = get_etf_info('213630', '20200104', '20210510')
print(df)
soup = pd.DataFrame(temp)
#df['시가총액(억)']=pd.to_numeric(df['시가총액(억)'])
soup.to_excel('etftest.xlsx', encoding='euc-kr', index=False, header=False)<jupyter_output><empty_output><jupyter_text>1,3,6,12M 수익률<jupyter_code># etf
import requests
import re
import pandas as pd
from bs4 import BeautifulSoup

url = f'https://finance.naver.com/item/main.nhn?code=153130'
rs = requests.get(url)

soup = BeautifulSoup(rs.text, 'html.parser')
ret_soup = str(soup.find("table", attrs={"summary":"1개월 수익률 정보"}).find("tbody").find_all("tr"))

# 필요 없는 태그 지우기
ret_soup = re.sub('<.+?>','',ret_soup,0).strip()
ret_soup = ret_soup.replace('\n','').replace('\t','').replace(',','').replace('수익률','').replace('[','').replace(']','').split()

# 수익률 형태 맞추기
# soup = pd.DataFrame(soup)
# ret_dict = {"1개월 수익률":soup.iloc[1],"3개월 수익률":soup.iloc[3],"6개월 수익률":soup.iloc[5],"1년 수익률":soup.iloc[7]}
# ret_list = pd.DataFrame(ret_dict)

# 시가총액
agg_soup = str(soup.find("table", attrs={"summary":"시가총액 정보"})).find("tr", attrs={"class":"strong"})
#agg_soup = agg_soup.replace('\n','').replace('\t','').replace(',','').replace('[','').replace(']','').split()
agg_soup

# ret_list

# stock
import requests
import re
import pandas as pd
from bs4 import BeautifulSoup

url = f'https://navercomp.wisereport.co.kr/v2/company/c1010001.aspx?cmp_cd=006840&cn='
rs = requests.get(url)

soup = BeautifulSoup(rs.text, 'html.parser')
soup = str(soup.find("table", attrs={"class":"gHead"}).find("tbody").find_all("tr"))#.find_all("td",attrs={"class":"num noline-bottom"}))

# 필요 없는 태그 지우기
soup = re.sub('<.+?>','',soup,0).strip()
soup = soup.replace('\n','').replace('\t','').replace(',','').replace('수익률','').replace('[','').replace(']','').replace('(1M/3M/6M/1Y)','').replace('%/','%').replace('억원','').split()

# 시가총액 추출
agg_price = np.array(pd.DataFrame(soup).iloc[18])

# 모멘텀 형태 맞추기
ret_soup = np.array(pd.DataFrame(soup).iloc[27:])
ret_dict = {"시가총액(억원)":agg_price,"1개월 수익률":ret_soup[0],"3개월 수익률":ret_soup[1],"6개월 수익률":ret_soup[2],"1년 수익률":ret_soup[3]}
ret_list = pd.DataFrame(ret_dict)

ret_list

# stock
import pandas as pd
import requests
import re
import pandas as pd
import numpy as np
from bs4 import BeautifulSoup

stock_code = pd.read_excel('210509_kospi.xlsx',sheet_name='Sheet1', 
                          converters={'단축코드': str})
stock_code = stock_code[['단축코드', '한글 종목약명']]


def get_stock_momentum(etfCode, name):
    url = f'https://navercomp.wisereport.co.kr/v2/company/c1010001.aspx?cmp_cd={etfCode}&cn='
    rs = requests.get(url)

    soup = BeautifulSoup(rs.text, 'html.parser')
    soup = str(soup.find("table", attrs={"class":"gHead"}).find("tbody").find_all("tr"))#.find_all("td",attrs={"class":"num noline-bottom"}))

    # 필요 없는 태그 지우기
    soup = re.sub('<.+?>','',soup,0).strip()
    soup = soup.replace('\n','').replace('\t','').replace(',','').replace('수익률','').replace('[','').replace(']','').replace('(1M/3M/6M/1Y)','').replace('%/','%').replace('억원','').split()

    # 시가총액 추출
    agg_price = np.array(pd.DataFrame(soup).iloc[18])

    # 모멘텀 형태 맞추기
    ret_soup = np.array(pd.DataFrame(soup).iloc[27:])
    ret_dict = {"기업명":name,"시가총액(억원)":agg_price,"1개월 수익률":ret_soup[0],"3개월 수익률":ret_soup[1],"6개월 수익률":ret_soup[2],"1년 수익률":ret_soup[3]}
    ret_list = pd.DataFrame(ret_dict)

    return ret_list


temp_df = get_stock_momentum(stock_code['단축코드'][1], stock_code['한글 종목약명'][1])
for i in range(2, len(stock_code)):
    temp_df = pd.concat([temp_df, get_stock_momentum(stock_code['단축코드'][i], stock_code['한글 종목약명'][i])])

temp_df
temp_df.to_excel('stock_momentum_test.xlsx', encoding='euc-kr', index=False)<jupyter_output><empty_output><jupyter_text>가치 지표 크롤링 - 유동비율 :- 부채비율 : - 이자보상비율 :- 영업이익 증가율 :- EPS 증가율 :- 영업이익률 :- ROA- ROE - ROIC- 순운전자본회전율 :- PER :- PCR : - PSR : - PBR :- EV/EBITDA :- FCFF : https://www.queeneconomy.com/15<jupyter_code>import pandas as pd
import requests
import re
import pandas as pd
import numpy as np
from bs4 import BeautifulSoup

# Financial Ratio Soup
ratio_url = f'http://comp.fnguide.com/SVO2/ASP/SVD_FinanceRatio.asp?pGB=1&gicode=A005930&cID=&MenuYn=Y&ReportGB=&NewMenuID=104&stkGb=701'
ratio_rs = requests.get(ratio_url)
ratio_soup = BeautifulSoup(ratio_rs.text, 'html.parser')

# Investment Index Soup
index_url = f'http://comp.fnguide.com/SVO2/ASP/SVD_Invest.asp?pGB=1&gicode=A005930&cID=&MenuYn=Y&ReportGB=&NewMenuID=105&stkGb=701'
index_rs = requests.get(index_url)
index_soup = BeautifulSoup(index_rs.text, 'html.parser')


''' 재무 비율 '''
'''----------------- 안정성 비율 -------------------------'''
# 유동 비율
liquid_ratio = str(ratio_soup.find("div", attrs={"class":"ul_col2wrap pd_t25"}).find("tr", attrs={"id":"p_grid1_1","class":"rwf acd_dep_start_close"}).find_all("td"))
liquid_ratio = re.sub('<.+?>','',liquid_ratio,0).strip()
liquid_ratio = liquid_ratio.replace('[','').replace(']','').replace(',','').split()

# 부채비율
liab_ratio = str(ratio_soup.find("div", attrs={"class":"ul_col2wrap pd_t25"}).find("tr", attrs={"id":"p_grid1_3","class":"rwf acd_dep_start_close"}).find_all("td"))
liab_ratio = re.sub('<.+?>','',liab_ratio,0).strip()
liab_ratio = liab_ratio.replace('[','').replace(']','').replace(',','').split()

# 이자보상배율
int_compen_ratio = str(ratio_soup.find("div", attrs={"class":"ul_col2wrap pd_t25"}).find("tr", attrs={"id":"p_grid1_6","class":"rwf acd_dep_start_close"}).find_all("td"))
int_compen_ratio = re.sub('<.+?>','',int_compen_ratio,0).strip()
int_compen_ratio = int_compen_ratio.replace('[','').replace(']','').replace(',','').split()

'''----------------- 성장성 비율 -------------------------'''
# 영업이익 증가율
opincome_growth_ratio = str(ratio_soup.find("div", attrs={"class":"ul_col2wrap pd_t25"}).find("tr", attrs={"id":"p_grid1_10","class":"rwf acd_dep_start_close"}).find_all("td"))
opincome_growth_ratio = re.sub('<.+?>','',opincome_growth_ratio,0).strip()
opincome_growth_ratio = opincome_growth_ratio.replace('[','').replace(']','').replace(',','').split()

# EPS 증가율
eps_growth_ratio = str(ratio_soup.find("div", attrs={"class":"ul_col2wrap pd_t25"}).find("tr", attrs={"id":"p_grid1_12","class":"rwf acd_dep_start_close"}).find_all("td"))
eps_growth_ratio = re.sub('<.+?>','',eps_growth_ratio,0).strip()
eps_growth_ratio = eps_growth_ratio.replace('[','').replace(']','').replace(',','').split()

'''----------------- 수익률 비율 -------------------------'''
# 영업이익률
opincome_ratio = str(ratio_soup.find("div", attrs={"class":"ul_col2wrap pd_t25"}).find("tr", attrs={"id":"p_grid1_15","class":"rwf acd_dep_start_close"}).find_all("td"))
opincome_ratio = re.sub('<.+?>','',opincome_ratio,0).strip()
opincome_ratio = opincome_ratio.replace('[','').replace(']','').replace(',','').split()

# ROA
roa = str(ratio_soup.find("div", attrs={"class":"ul_col2wrap pd_t25"}).find("tr", attrs={"id":"p_grid1_17","class":"rwf acd_dep_start_close"}).find_all("td"))
roa = re.sub('<.+?>','',roa,0).strip()
roa = roa.replace('[','').replace(']','').replace(',','').split()

# ROE
roe = str(ratio_soup.find("div", attrs={"class":"ul_col2wrap pd_t25"}).find("tr", attrs={"id":"p_grid1_18","class":"rwf acd_dep_start_close"}).find_all("td"))
roe = re.sub('<.+?>','',roe,0).strip()
roe = roe.replace('[','').replace(']','').replace(',','').split()

# ROIC
roic = str(ratio_soup.find("div", attrs={"class":"ul_col2wrap pd_t25"}).find("tr", attrs={"id":"p_grid1_19","class":"rwf acd_dep_start_close"}).find_all("td"))
roic = re.sub('<.+?>','',roic,0).strip()
roic = roic.replace('[','').replace(']','').replace(',','').split()

'''----------------- 활동성 비율 -------------------------'''
# 순운전자본 회전율
workcapital_turnover = str(ratio_soup.find("div", attrs={"class":"ul_col2wrap pd_t25"}).find("tr", attrs={"id":"p_grid1_23","class":"rwf acd_dep_start_close"}).find_all("td"))
workcapital_turnover = re.sub('<.+?>','',workcapital_turnover,0).strip()
workcapital_turnover = workcapital_turnover.replace('[','').replace(']','').replace(',','').split()


''' 투자 지표 '''
'''----------------- Multiples -------------------------'''
# PER
per = str(index_soup.find("table", attrs={"class":"us_table_ty1 h_fix zigbg_no"}).find("tr", attrs={"id":"p_grid1_9","class":"rwf acd_dep_start_close"}).find_all("td"))
per = re.sub('<.+?>','',per,0).strip()
per = per.replace('[','').replace(']','').replace(',','').split()

# PCR
pcr = str(index_soup.find("table", attrs={"class":"us_table_ty1 h_fix zigbg_no"}).find("tr", attrs={"id":"p_grid1_10","class":"rwf acd_dep_start_close"}).find_all("td"))
pcr = re.sub('<.+?>','',pcr,0).strip()
pcr = pcr.replace('[','').replace(']','').replace(',','').split()

# PSR
psr = str(index_soup.find("table", attrs={"class":"us_table_ty1 h_fix zigbg_no"}).find("tr", attrs={"id":"p_grid1_11","class":"rwf acd_dep_start_close"}).find_all("td"))
psr = re.sub('<.+?>','',psr,0).strip()
psr = psr.replace('[','').replace(']','').replace(',','').split()

# PBR
pbr = str(index_soup.find("table", attrs={"class":"us_table_ty1 h_fix zigbg_no"}).find("tr", attrs={"id":"p_grid1_12","class":"rwf acd_dep_start_close"}).find_all("td"))
pbr = re.sub('<.+?>','',pbr,0).strip()
pbr = pbr.replace('[','').replace(']','').replace(',','').split()

# EV/EBITDA
ev_ebitda = str(index_soup.find("table", attrs={"class":"us_table_ty1 h_fix zigbg_no"}).find("tr", attrs={"id":"p_grid1_14","class":"rwf acd_dep_start_close"}).find_all("td"))
ev_ebitda = re.sub('<.+?>','',ev_ebitda,0).strip()
ev_ebitda = ev_ebitda.replace('[','').replace(']','').replace(',','').split()

'''----------------- FCF -------------------------'''
# FCFF
fcff = str(index_soup.find("table", attrs={"class":"us_table_ty1 h_fix zigbg_no"}).find_all("tr", attrs={"class":"rwf"}))#.find_all("td"))
fcff = re.sub('<.+?>','',fcff,0).strip()
fcff = fcff.replace('[','').replace(']','').replace(',','').split()
fcff = fcff[-5:]

## aggregating
temp_agg = liquid_ratio + liab_ratio + int_compen_ratio + opincome_growth_ratio + eps_growth_ratio + opincome_ratio + roa + roe + roic + workcapital_turnover + per + pcr + psr + pbr + ev_ebitda + fcff
temp_agg = pd.DataFrame(temp_agg).transpose()

df_agg = pd.DataFrame(np.zeros([16,5]))
for i in range(0, 16):
    for j in range(0, 5):
        df_agg.iloc[i,j] = temp_agg[5*i+j]
df_agg.columns = ["2016","2017","2018","2019","2020"]
df_agg.rename(index = {0:"유동비율", 1:"부채비율", 2:"이자보상배율", 3:"영업이익증가율",4:"EPS증가율", 5:"영업이익률", 6:"ROA", 7:"ROE", 8:"ROIC", 9:"순운전자본회전율", 10:"PER", 11:"PCR", 12:"PSR", 13:"PBR", 14:"EV/EBITDA", 15:"FCFF"}, inplace=True)
df_agg = df_agg.transpose()
df_agg.iloc[4,:]
import pandas as pd
import requests
import re
import pandas as pd
import numpy as np
from bs4 import BeautifulSoup

def get_stock_ratio(etfCode, name):
    # 시가총액 크롤링
    url = f'https://navercomp.wisereport.co.kr/v2/company/c1010001.aspx?cmp_cd={etfCode}&cn='
    rs = requests.get(url)

    soup = BeautifulSoup(rs.text, 'html.parser')
    soup = str(soup.find("table", attrs={"class":"gHead"}).find("tbody").find_all("tr"))#.find_all("td",attrs={"class":"num noline-bottom"}))

    # 필요 없는 태그 지우기
    soup = re.sub('<.+?>','',soup,0).strip()
    soup = soup.replace('\n','').replace('\t','').replace(',','').replace('수익률','').replace('[','').replace(']','').replace('(1M/3M/6M/1Y)','').replace('%/','%').replace('억원','').split()

    # 시가총액 추출
    agg_price = np.array(pd.DataFrame(soup).iloc[18])

    # Financial Ratio Soup
    ratio_url = f'http://comp.fnguide.com/SVO2/ASP/SVD_FinanceRatio.asp?pGB=1&gicode=A{etfCode}&cID=&MenuYn=Y&ReportGB=&NewMenuID=104&stkGb=701'
    ratio_rs = requests.get(ratio_url)
    ratio_soup = BeautifulSoup(ratio_rs.text, 'html.parser')

    # Investment Index Soup
    index_url = f'http://comp.fnguide.com/SVO2/ASP/SVD_Invest.asp?pGB=1&gicode=A{etfCode}&cID=&MenuYn=Y&ReportGB=&NewMenuID=105&stkGb=701'
    index_rs = requests.get(index_url)
    index_soup = BeautifulSoup(index_rs.text, 'html.parser')


    ''' 재무 비율 '''
    '''----------------- 안정성 비율 -------------------------'''
    # 유동 비율
    liquid_ratio = str(ratio_soup.find("div", attrs={"class":"ul_col2wrap pd_t25"}).find("tr", attrs={"id":"p_grid1_1","class":"rwf acd_dep_start_close"}).find_all("td"))
    liquid_ratio = re.sub('<.+?>','',liquid_ratio,0).strip()
    liquid_ratio = liquid_ratio.replace('[','').replace(']','').replace(',','').split()

    # 부채비율
    liab_ratio = str(ratio_soup.find("div", attrs={"class":"ul_col2wrap pd_t25"}).find("tr", attrs={"id":"p_grid1_3","class":"rwf acd_dep_start_close"}).find_all("td"))
    liab_ratio = re.sub('<.+?>','',liab_ratio,0).strip()
    liab_ratio = liab_ratio.replace('[','').replace(']','').replace(',','').split()

    # 이자보상배율
    int_compen_ratio = str(ratio_soup.find("div", attrs={"class":"ul_col2wrap pd_t25"}).find("tr", attrs={"id":"p_grid1_6","class":"rwf acd_dep_start_close"}).find_all("td"))
    int_compen_ratio = re.sub('<.+?>','',int_compen_ratio,0).strip()
    int_compen_ratio = int_compen_ratio.replace('[','').replace(']','').replace(',','').split()

    '''----------------- 성장성 비율 -------------------------'''
    # 영업이익 증가율
    opincome_growth_ratio = str(ratio_soup.find("div", attrs={"class":"ul_col2wrap pd_t25"}).find("tr", attrs={"id":"p_grid1_10","class":"rwf acd_dep_start_close"}).find_all("td"))
    opincome_growth_ratio = re.sub('<.+?>','',opincome_growth_ratio,0).strip()
    opincome_growth_ratio = opincome_growth_ratio.replace('[','').replace(']','').replace(',','').split()

    # EPS 증가율
    eps_growth_ratio = str(ratio_soup.find("div", attrs={"class":"ul_col2wrap pd_t25"}).find("tr", attrs={"id":"p_grid1_12","class":"rwf acd_dep_start_close"}).find_all("td"))
    eps_growth_ratio = re.sub('<.+?>','',eps_growth_ratio,0).strip()
    eps_growth_ratio = eps_growth_ratio.replace('[','').replace(']','').replace(',','').split()

    '''----------------- 수익률 비율 -------------------------'''
    # 영업이익률
    opincome_ratio = str(ratio_soup.find("div", attrs={"class":"ul_col2wrap pd_t25"}).find("tr", attrs={"id":"p_grid1_15","class":"rwf acd_dep_start_close"}).find_all("td"))
    opincome_ratio = re.sub('<.+?>','',opincome_ratio,0).strip()
    opincome_ratio = opincome_ratio.replace('[','').replace(']','').replace(',','').split()

    # ROA
    roa = str(ratio_soup.find("div", attrs={"class":"ul_col2wrap pd_t25"}).find("tr", attrs={"id":"p_grid1_17","class":"rwf acd_dep_start_close"}).find_all("td"))
    roa = re.sub('<.+?>','',roa,0).strip()
    roa = roa.replace('[','').replace(']','').replace(',','').split()

    # ROE
    roe = str(ratio_soup.find("div", attrs={"class":"ul_col2wrap pd_t25"}).find("tr", attrs={"id":"p_grid1_18","class":"rwf acd_dep_start_close"}).find_all("td"))
    roe = re.sub('<.+?>','',roe,0).strip()
    roe = roe.replace('[','').replace(']','').replace(',','').split()

    # ROIC
    roic = str(ratio_soup.find("div", attrs={"class":"ul_col2wrap pd_t25"}).find("tr", attrs={"id":"p_grid1_19","class":"rwf acd_dep_start_close"}).find_all("td"))
    roic = re.sub('<.+?>','',roic,0).strip()
    roic = roic.replace('[','').replace(']','').replace(',','').split()

    '''----------------- 활동성 비율 -------------------------'''
    # 순운전자본 회전율
    workcapital_turnover = str(ratio_soup.find("div", attrs={"class":"ul_col2wrap pd_t25"}).find("tr", attrs={"id":"p_grid1_23","class":"rwf acd_dep_start_close"}).find_all("td"))
    workcapital_turnover = re.sub('<.+?>','',workcapital_turnover,0).strip()
    workcapital_turnover = workcapital_turnover.replace('[','').replace(']','').replace(',','').split()


    ''' 투자 지표 '''
    '''----------------- Multiples -------------------------'''
    # PER
    per = str(index_soup.find("table", attrs={"class":"us_table_ty1 h_fix zigbg_no"}).find("tr", attrs={"id":"p_grid1_9","class":"rwf acd_dep_start_close"}).find_all("td"))
    per = re.sub('<.+?>','',per,0).strip()
    per = per.replace('[','').replace(']','').replace(',','').split()

    # PCR
    pcr = str(index_soup.find("table", attrs={"class":"us_table_ty1 h_fix zigbg_no"}).find("tr", attrs={"id":"p_grid1_10","class":"rwf acd_dep_start_close"}).find_all("td"))
    pcr = re.sub('<.+?>','',pcr,0).strip()
    pcr = pcr.replace('[','').replace(']','').replace(',','').split()

    # PSR
    psr = str(index_soup.find("table", attrs={"class":"us_table_ty1 h_fix zigbg_no"}).find("tr", attrs={"id":"p_grid1_11","class":"rwf acd_dep_start_close"}).find_all("td"))
    psr = re.sub('<.+?>','',psr,0).strip()
    psr = psr.replace('[','').replace(']','').replace(',','').split()

    # PBR
    pbr = str(index_soup.find("table", attrs={"class":"us_table_ty1 h_fix zigbg_no"}).find("tr", attrs={"id":"p_grid1_12","class":"rwf acd_dep_start_close"}).find_all("td"))
    pbr = re.sub('<.+?>','',pbr,0).strip()
    pbr = pbr.replace('[','').replace(']','').replace(',','').split()

    # EV/EBITDA
    ev_ebitda = str(index_soup.find("table", attrs={"class":"us_table_ty1 h_fix zigbg_no"}).find("tr", attrs={"id":"p_grid1_14","class":"rwf acd_dep_start_close"}).find_all("td"))
    ev_ebitda = re.sub('<.+?>','',ev_ebitda,0).strip()
    ev_ebitda = ev_ebitda.replace('[','').replace(']','').replace(',','').split()

    '''----------------- FCF -------------------------'''
    # FCFF
    fcff = str(index_soup.find("table", attrs={"class":"us_table_ty1 h_fix zigbg_no"}).find_all("tr", attrs={"class":"rwf"}))#.find_all("td"))
    fcff = re.sub('<.+?>','',fcff,0).strip()
    fcff = fcff.replace('[','').replace(']','').replace(',','').split()
    fcff = fcff[-5:]

    ## aggregating
    temp_agg = liquid_ratio + liab_ratio + int_compen_ratio + opincome_growth_ratio + eps_growth_ratio + opincome_ratio + roa + roe + roic + workcapital_turnover + per + pcr + psr + pbr + ev_ebitda + fcff
    temp_agg = pd.DataFrame(temp_agg).transpose()
    
    df_agg = pd.DataFrame(np.zeros([16,5]))
    if temp_agg.shape[1] != 80: 
        print("Not enough data, may unavailable in 2016!")
        return df_agg;

    for i in range(0, 16):
        for j in range(0, 5):
#             if temp_agg[5*i+j].empty:
#                 df_agg.iloc[i,j] = "N/A"
#             else:
                df_agg.iloc[i,j] = temp_agg[5*i+j]
            
    df_agg.columns = ["2016","2017","2018","2019","2020"]
    df_agg.rename(index = {0:"유동비율", 1:"부채비율", 2:"이자보상배율", 3:"영업이익증가율",4:"EPS증가율", 5:"영업이익률", 6:"ROA", 7:"ROE", 8:"ROIC", 9:"순운전자본회전율", 10:"PER", 11:"PCR", 12:"PSR", 13:"PBR", 14:"EV/EBITDA", 15:"FCFF"}, inplace=True)
    df_agg = df_agg.transpose()
    df_agg = df_agg.iloc[4,:]
    df_agg["기업 명"] = name
    df_agg["시가총액 (억원)"] = agg_price

    return df_agg

print(pd.DataFrame(get_stock_ratio('027410', 'BGF')))
from tqdm import tqdm
import pdb

print(stock_code['한글 종목약명'][1])
temp_df = get_stock_ratio(stock_code['단축코드'][1], stock_code['한글 종목약명'][1])
for i in tqdm(range(2, len(stock_code))):
    print(stock_code['한글 종목약명'][i])
    temp_df = pd.concat([temp_df, get_stock_ratio(stock_code['단축코드'][i], stock_code['한글 종목약명'][i])])


temp_df
%debug(get_stock_ratio)
stock_code<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.2551458670988655, 'fraction_numerical': 0.026904376012965966, 'mean_word_length': 5.0109595713589865, 'pattern_counts': {'":': 119, '<': 60, '<?xml version=': 0, '>': 61, 'https://': 9, 'lorem ipsum': 0, 'www.': 1, 'xml': 6}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '6', 'dir': 'jupyter-structured-clean-dedup', 'id': '522809', 'license': 'MIT', 'n_tokens_mistral': 11130, 'n_tokens_neox': 11416, 'n_words': 1337, 'path': 'crawling.ipynb', 'repo_name': 'klee30810/FinanceHub', 'size': '24680'}