Skip to content

Instantly share code, notes, and snippets.

@KimMyungSam
Created July 16, 2017 10:15
Show Gist options
  • Save KimMyungSam/dbbca9787a9517ccebc09a7cc7602e4a to your computer and use it in GitHub Desktop.
Save KimMyungSam/dbbca9787a9517ccebc09a7cc7602e4a to your computer and use it in GitHub Desktop.
네이버재무제표 가져오기 2017.07.16
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"deletable": true,
"editable": true,
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"네이버 파이낸스에서 재무제표 데이터를 크롤링 하기 위해 알아야 할 정보는 아래 URL이 전부다.\n",
"\n",
"http://companyinfo.stock.naver.com/v1/company/ajax/cF1001.aspx?cmp_cd=105560&fin_typ=0&freq_typ=Y\n",
"\n",
"URL을 구성하는 파라미터의 의미는 다음과 같다.\n",
"\n",
"인자 | 의미 | 값\n",
"-- | -- | --\n",
"cmp_cd | 종목코드 | 005930 (종목코드)\n",
"fin_typ | 재무제표 타입 | 0: 주재무제표, 1: GAAP개별, 2: GAAP연결, 3: IFRS별도, 4:IFRS연결\n",
"freq_typ | 기간 | Y:년, Q:분기"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"import re\n",
"from datetime import datetime\n",
"import pandas as pd\n",
"import requests\n",
"from bs4 import BeautifulSoup\n",
"import mysql.connector\n",
"import sqlalchemy\n",
"from sqlalchemy import create_engine\n",
"import pandas as pd\n",
"\n",
"\n",
"# get_date_str(s) - 문자열 s 에서 \"YYYY/MM\" 문자열 추출\n",
"def get_date_str(s):\n",
" date_str = ''\n",
" r = re.search(\"\\d{4}/\\d{2}\", s)\n",
" if r:\n",
" date_str = r.group()\n",
" date_str = date_str.replace('/', '-')\n",
" return date_str\n",
"\n",
"# 년도별, 분기별 data있음을 체크하여 DB에 저장\n",
"def save_naverFS(df,freq_type, code):\n",
" # table에 code 컬럼 추가\n",
" # index_label이 index로 표기되어 date로 수정\n",
" df['code'] = code\n",
" if freq_type == 'Y':\n",
" df.to_sql('naverfs_y', con, if_exists = 'append', index_label='date')\n",
" elif freq_type == 'Q':\n",
" df.to_sql('naverfs_q', con, if_exists = 'append', index_label='date')\n",
" return None"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"* code: 종목코드\n",
"* fin_type = '0': 재무제표 종류 (0: 주재무제표, 1: GAAP개별, 2: GAAP연결, 3: IFRS별도, 4:IFRS연결)\n",
"* freq_type = 'Y': 기간 (Y:년, Q:분기)\n",
"\n",
"- 2017.7.01 네이버재무제표 구조가 단일 리스트 컬럼 구조에서 이중 리스트 구조로 변경되어 df[i][1] 형태로 date 정보를 가져옴\n",
"문제점과 해결방안\n",
"표시된 DataFrame을 자세히 살펴보면 아래와 같은 문제점들이 있다. (대부분 네이버 파이낸스 페이지의 HTML TABLE 표현의 문제다)\n",
"\n",
"문제점\n",
"'연간'이른 컬럼명이 추가되었고, 컬럼 이름이 한 컬럼씩 오른쪽으로 밀렸다.\n",
"마지막 컬럼의 값이 NaN 값 (컬럼 이름이 밀려서 발생)\n",
"날짜에 \"(IFRS연결)\"와 같이 불필요한 문자열 포함하고 있다.\n",
"시계열 데이터로 처리하려면, '주요재무정보'가 컬럼이 되고 날짜가 행(row)가 되는 것이 편리하다.\n",
"각 문제에 대한 해결방안\n",
"컬럼명 '연간' 삭제\n",
"컬럼 문자열에서 날짜(년, 월)만 추출 (정규식 사용)\n",
"마지막 컬럼 삭제\n",
"컬럼과 로우를 전환 (df.T) 한다 (transpose 우리말로 전치행렬 이라고 한다)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false,
"deletable": true,
"editable": true,
"slideshow": {
"slide_type": "-"
}
},
"outputs": [],
"source": [
"def get_finstate_naver(code, fin_type, freq_type):\n",
" url_tmpl = 'http://companyinfo.stock.naver.com/v1/company/ajax/cF1001.aspx?' \\\n",
" 'cmp_cd=%s&fin_typ=%s&freq_typ=%s'\n",
" url = url_tmpl % (code, fin_type, freq_type)\n",
" \n",
" dfs = pd.read_html(url, encoding=\"utf-8\")\n",
" df = dfs[0]\n",
" if df.iloc[0,0].find('해당 데이터가 존재하지 않습니다') >= 0:\n",
" return None\n",
"\n",
" new_cols = []\n",
" cols = list(df.columns)\n",
" \n",
" for i in range(0,len(cols)):\n",
" new_cols.append(cols[i][1]) #list가 이중구조로 되어 있어 변경함\n",
"\n",
" cols = ['date']\n",
" for x in new_cols[:-1]:\n",
" cols.append(get_date_str(x))\n",
" df.columns = cols\n",
" df.set_index('date', inplace=True)\n",
" dft = df.T\n",
" dft.index = pd.to_datetime(dft.index)\n",
"\n",
" # remove if index is NaT\n",
" dft = dft[pd.notnull(dft.index)]\n",
" \n",
" #종목별 컬럼name 오류를 수정함\n",
" dft.rename(columns={'유보율': '자본유보율'}, inplace=True)\n",
" dft.rename(columns={'현금배당성향': '현금배당성향(%)'}, inplace=True)\n",
"\n",
" return dft"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false,
"deletable": true,
"editable": true,
"scrolled": false,
"slideshow": {
"slide_type": "subslide"
}
},
"outputs": [],
"source": [
"if __name__ == \"__main__\":\n",
" # NULL row에 대해 삭제가 필요함. 코드 추가 필요함\n",
" dir = 'D:/naver/FS/'\n",
" \n",
" pwd = 'rlaehgus1'\n",
" engine = create_engine('mysql+mysqlconnector://root:'+pwd+'@localhost/findb', echo=False)\n",
" con = engine.connect()\n",
" \n",
" # 전체 종목의 code를 가져오기\n",
" sql = 'SELECT * FROM listed_company'\n",
" comp_code = pd.read_sql(sql, con=engine)\n",
"\n",
" for inx, row in comp_code.iterrows():\n",
" code = row['code']\n",
" code = code.zfill(6) # 네이버금융 조회시 6자리여야 함.\n",
" print ('code=',code)\n",
" \n",
" # 네이버금융 데이터에서 재주재표 정보 가져오기\n",
" df_year = get_finstate_naver(code, 0, 'Y') #년간 재무제표\n",
" df_quarter = get_finstate_naver(code, 0, 'Q') #분기별 재무제표\n",
"\n",
" if df_year is not None:\n",
" save_naverFS(df_year,'Y', code) # 년간 db전체를 저장\n",
" \n",
" # csv파일로 저장\n",
" # fname = dir + year + '_ifrs_con_' + code + '.csv'\n",
" # df_year.to_csv(fname)\n",
" \n",
" if df_quarter is not None:\n",
" save_naverFS(df_quarter,'Q', code) # 분기별 db전체를 저장\n",
" \n",
" # csv파일로 저장\n",
" # fname = dir + quarter + '_ifrs_con_' + code + '.csv'\n",
" # df_quarter.to_csv(fname)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"naver colums(\n",
"['매출액', '영업이익', '세전계속사업이익', '당기순이익', '당기순이익(지배)', \n",
"'당기순이익(비지배)', '자산총계', '부채총계', '자본총계', '자본총계(지배)', \n",
"'자본총계(비지배)', '자본금', '영업활동현금흐름', '투자활동현금흐름', \n",
"'재무활동현금흐름', 'CAPEX', 'FCF', '이자발생부채', '영업이익률', '순이익률',\n",
"'ROE(%)','ROA(%)', '부채비율', '자본유보율', 'EPS(원)', 'PER(배)', 'BPS(원)',\n",
"'PBR(배)','현금DPS(원)', '현금배당수익률', '현금배당성향(%)', '발행주식수(보통주)'],\n",
"dtype='object', name='주요재무정보')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"##### data 디렉토리의 \"naver_finstate_\" + 아래 표의 이름을 붙여 디렉토리를 지정\n",
"\n",
"##### 디렉토리 문자열\t설명\t기간\n",
"##### year_gaap\tGAAP\t년\n",
"##### year_ifrs_con\tIFRS 연결\t년\n",
"##### year_ifrs_sep\tIFRS 별도\t년\n",
"##### quater_gaap\tGAAP\t분기\n",
"##### quater_ifrs_con\tIFRS 연결\t분기\n",
"##### quater_ifrs_sep\tIFRS 별도\t분기"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": []
}
],
"metadata": {
"celltoolbar": "Slideshow",
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.0"
},
"nikola": {
"category": "dev",
"date": "2017-02-25 02:30:35 UTC+09:00",
"description": "네이버 파이낸스 사이트에서 재무제표 크롤링",
"link": "",
"slug": "naver-finance-finstate-crawling",
"tags": "crawling, naver",
"title": "네이버 파이낸스 - 재무제표 크롤링",
"type": "text"
}
},
"nbformat": 4,
"nbformat_minor": 0
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment