Skip to content

Instantly share code, notes, and snippets.

@KimMyungSam
Created June 3, 2017 10:06
Show Gist options
  • Save KimMyungSam/eb4aa0bf077f6d6baaf46a49cc971d44 to your computer and use it in GitHub Desktop.
Save KimMyungSam/eb4aa0bf077f6d6baaf46a49cc971d44 to your computer and use it in GitHub Desktop.
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"# API 인증키 발급\n",
"계정을 만들고, API 인증키 발급 받는다\n",
"\n",
"계정 신청: https://dart.fss.or.kr/dsag002/insertForm.do\n",
"\n",
"### 개인용, 기업용\n",
"* 개인용: 1만건/일\n",
"* 기업용: 조회 건수 제한이 없는 대신 조회 서버 IP 제한"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"# 오픈 API가 제공하는 주요정보\n",
"주요하게 다음 2가지 API를 제공한다\n",
"\n",
"1. 기업 개황 API : http://dart.fss.or.kr/api/company.json?auth=xxx&crp_cd=xxx\n",
"1. 정보 검색 API : http://dart.fss.or.kr/api/search.json?auth=xxx\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"# API 개발 가이드 사이트에서 테스트\n",
"https://dart.fss.or.kr/dsap001/guide.do API 개발 가이드\n",
"\n",
"<img src=\"http://i.imgur.com/9NpoJgx.png\" >\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"# JSON vs XML\n",
"다음 두 가지(XML, JSON) 형식을 제공한다 \n",
"* http://dart.fss.or.kr/api/search.xml?auth=xxx (XML)\n",
"* http://dart.fss.or.kr/api/search.json?auth=xxx (JSON)\n",
"\n",
"데이터는 동일하다. JOSN이 상대적으로 가볍고, Python에서 다루기도 좋다."
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"# 실제 인증키를 사용\n",
"auth = 'c8b8df3eb87c919d0650373d93c6a95f779858b7' \n",
"\n",
"# 헤더: 실제 인증키를 사용시 사용하지 않아도 된다\n",
"headers={'Referer':'https://dart.fss.or.kr/dsap001/guide.do'}"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"outputs": [],
"source": [
"# json 사용시\n",
"import requests\n",
"from pandas.io.json import json_normalize\n",
"import json\n",
"import re\n",
"import pandas as pd\n",
"from bs4 import BeautifulSoup\n",
"\n",
"# url_tmpl = 'http://dart.fss.or.kr/api/search.json?auth={auth}'\n",
"# url = url_tmpl.format(auth=auth,headers=headers)\n",
"\n",
"# 당일 100건 조회\n",
"# url_tmpl = 'http://dart.fss.or.kr/api/search.json?auth={auth}&page_set=100'\n",
"\n",
"# 회사의 전체 사업+반기+분기보고서 100건\n",
"# url_tmpl = 'http://dart.fss.or.kr/api/search.json?auth={auth}&crp_cd={code}&start_dt=19990101&bsn_tp=A001&bsn_tp=A002&bsn_tp=A003&page_set=100'\n",
"# url = url_tmpl.format(auth=auth, code='005930')\n",
"\n",
"code = ['073240','011170'] #금호타이어, 롯데케미칼, 100건\n",
"code_book = {}\n",
"for company in code:\n",
" url_tmpl = 'http://dart.fss.or.kr/api/search.json?auth={auth}&crp_cd={code}&start_dt=20170301&bsn_tp=A001&page_set=1'\n",
" url = url_tmpl.format(auth=auth, code=company)\n",
" r = requests.get(url, headers=headers)\n",
" jo = json.loads(r.text)\n",
" table = json_normalize(jo, 'list')\n",
" rcp_no = table['rcp_no'] #공시문서 번호\n",
" rno = rcp_no[0]\n",
" code_book[company] = rno "
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"# 보고서 보기\n",
"조회 결과에서 중요한 것은 문서의 고유 번호인 접수 번호 \"rcp_no\":\"20170515003806\" (삼성전자 분기보고서 2017.03)\n",
"\n",
"이 번호를 rcpNo 인자 다음 URL을 만들어 문서를 조회할 수 있다\n",
"\n",
"### 데스크탑 버전\n",
"http://dart.fss.or.kr/dsaf001/main.do?rcpNo=20170515003806"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"def get_report_doc_urls(rcp_no,eleid):\n",
" doc_urls = []\n",
" url = \"http://dart.fss.or.kr/dsaf001/main.do?rcpNo=%s\" % (rcp_no)\n",
" r = requests.get(url)\n",
" reg = re.compile('viewDoc\\((.*)\\);')\n",
" params = []\n",
" matches = reg.findall(r.text)\n",
" for m in matches: \n",
" params.append(m.replace(\"'\", \"\").replace(\" \", \"\").split(\",\"))\n",
" \n",
" doc_url_tmpl = \"http://dart.fss.or.kr/report/viewer.do?rcpNo=%s&dcmNo=%s&eleId=%s&offset=%s&length=%s&dtd=%s\" \n",
"\n",
" for p in params:\n",
" if eleid == p[2]:\n",
" doc_urls.append( doc_url_tmpl % tuple(p) )\n",
" return doc_urls"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {
"scrolled": true,
"slideshow": {
"slide_type": "slide"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"주 주 명\n"
]
}
],
"source": [
"# 사업 보고서 하위 문서 전체\n",
"\n",
"eleid = '16' # 연결재무제표 주석 (번호)\n",
"doc_urls = get_report_doc_urls(rno,eleid)\n",
"url = ''.join(doc_urls)\n",
"\n",
"html = requests.get(url).text\n",
"soup = BeautifulSoup(html, 'lxml')\n",
"get_text = soup.find_all('th')\n",
"print(get_text[0].text)\n",
"\n",
"#프레임워크로 되어 있는 페이지에서 html 헤더가 갖기 따로 있어 원하는 페이지를 얻을수없음.\n"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"105\n",
"1\n",
" (단위 : 백만원) 구 분 당기 전기\n",
"0 재고자산의 변동 (722) 9517 NaN\n",
"1 원재료와 상품매입액 1127944 1342314 NaN\n",
"2 종업원급여 513899 439146 NaN\n",
"3 감가상각비 및 무형자산상각비 224177 205446 NaN\n",
"4 광고선전비 85463 99894 NaN\n",
"5 운반비 및 선임 153064 169443 NaN\n",
"6 지급수수료 41362 41046 NaN\n",
"7 기타비용 681991 597638 NaN\n",
"8 합 계 2827178 2904444 NaN\n",
"150\n",
"2\n",
" (단위: 천원) 계정과목 판매비와관리비 매출원가 합 계\n",
"0 재고자산의 변동 - 1275769660 1275769660 NaN\n",
"1 사용된 원재료 - 3889057659 3889057659 NaN\n",
"2 종업원급여 57927528 174080277 232007805 NaN\n",
"3 퇴직급여 5866782 17444188 23310970 NaN\n",
"4 복리후생비 11131464 29492982 40624446 NaN\n",
"5 감가상각비 1528405 358899193 360427598 NaN\n",
"6 무형자산상각비 664753 996484 1661237 NaN\n",
"7 지급수수료 31927555 45481322 77408877 NaN\n",
"8 운반보관료 163946030 2233730 166179760 NaN\n",
"9 기타 104999290 228483636 333482926 NaN\n",
"10 합 계 377991807 6021939131 6399930938 NaN\n"
]
}
],
"source": [
"# 사업 보고서 하위 문서 전체\n",
"eleid = '16' # 연결재무제표 주석 (번호)\n",
"no = list(code_book.values())\n",
"code = list(code_book.keys())\n",
"\n",
"idx = 0\n",
"for doc_no in no:\n",
" doc_urls = get_report_doc_urls(doc_no,eleid)\n",
" url = ''.join(doc_urls)\n",
"# df[idx] = pd.read_html(url)\n",
"# df_code = df[idx]\n",
" df_code = pd.read_html(url)\n",
" n = len(df_code)\n",
" idx += 1\n",
" print (n)\n",
" print (idx)\n",
" for i in range(0,n-1):\n",
" text1 = df_code[i].to_html().find(\"재고자산\") > 0\n",
" text2 = df_code[i].to_html().find(\"급여\") > 0\n",
" text3 = df_code[i].to_html().find(\"감가상각비\") > 0\n",
" text4 = df_code[i].to_html().find(\"원재료\") > 0\n",
"\n",
" if text1 and text2 and text3 and text4:\n",
" print (df_code[i])\n",
" break"
]
}
],
"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.4.3"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment