"주식 재무제표 크롤링"의 두 판 사이의 차이
DB CAFE
(→네이버 증권 재무제표) |
|||
168번째 줄: | 168번째 줄: | ||
=== 네이버 증권 재무제표 === | === 네이버 증권 재무제표 === | ||
https://engkimbs.tistory.com/625 | https://engkimbs.tistory.com/625 | ||
− | + | *파이썬 코드 | |
<source lang=python> | <source lang=python> | ||
import requests | import requests |
2020년 12월 15일 (화) 16:37 판
thumb_up 추천메뉴 바로가기
- DBA { Oracle DBA 명령어 > DBA 초급 과정 > DBA 고급 과정 }
- 튜닝 { 오라클 튜닝 목록 }
- 모델링 { 데이터 모델링 가이드 }
목차
1 R에서 전자공시시스템(DART) API를 이용한 크롤링[편집]
- 금융감독원의 전자공시 시스템(http://dart.fss.or.kr/)
- 오픈 API 인증키 신청 필요 , API KEY 발급
- 하루 동안 요청할 수 있는 횟수 10,000 번
- 한번에 최대 10개까지의 데이터 받을수 있음.
- 아무런 쿼리도 입력하지 않으면 단순히 최신 공시 10건을 출력
1.1 회사 사업보고서 10건 크롤링 하는 예제[편집]
- 해당 주소 http://dart.fss.or.kr/api/search.xml?auth=APIKEY&crp_cd=005930&start_dt=19990101&bsn_tp=A001
- :(A002은 반기, A003은 분기)
- auth 는 발급받은 API key 입력
- corp_code 는 회사코드 다운로드(https://opendart.fss.or.kr/api/corpCode.xml?crtfc_key=API키)
- 데이터를 xml,json 형태( .../api/search. 뒤의 xml을 json으로만 바꾸어주면 됩니다.)
library(httr)
library(rvest)
library(jsonlite)
library(XML)
library(methods)
corpCode <- xmlToDataFrame("D:/dev/R/corpCode.xml")
data.df = corpCode$list
api.key = "OPEN API 키값"
#start.date = "19990101"
list_bsns_year <- c('2015', '2016', '2017', '2018', '2019','2020') #
list_reprt_code <- c('11011', '11012', '11013', '11014') # 분기 리포트
corp_code = "00385363"
#ticker = "005930"
# for(i in 1:6){
#
for(i in list_bsns_year){
for(j in list_reprt_code){
url = paste0("https://opendart.fss.or.kr/api/tesstkAcqsDspsSttus.json?crtfc_key=",api.key,"&corp_code=",corp_code,"&bsns_year=",list_bsns_year[i],"&reprt_code=",list_reprt_code[j])
# print(url)
data = fromJSON(url)
# data.df = data$list
data.df <- rbind(data.df,data$list)
# data.df.rcept_no = data.df$rcept_no
# data.df %>% head()
}
}
# data.df %>% head()
1.2 공시번호로 사업보고서 확인[편집]
- 필요한 값은 공시번호에 해당하는 rcp_no 값 (data.df$rcept_no) 만 data.df.rcp 변수에 저장
- dart 홈페이지 공시들의 url 파악 필요
- 정기공시를 검색해보면 00 년 사업보고서 예시
1.3 재무제표 파일 다운로드[편집]
- 첨부되어 있는 재무제표 파일들을 다운로드 받기 위한 각 공시별 dcm 구하기
- dcm을 뽑아내기 위해 크롬 > 개발자도구 > xpath를 이용하여 추출
- //*[@id="north"]/div[2]/ul/li[1]/a
- 해당 부분의 값을 R에서 추출하는 법
# 위 페이지 url 정보를 GET() 함수를 통해 가져오며,read_html()을 통해 html 정보를 읽을 후,xpath 값으로 해당 노드의 정보를 읽어오도록 합니다.
url.business.report = 'http://dart.fss.or.kr/dsaf001/main.do?rcpNo=20180402005019'
req = GET(url.business.report)
req = read_html(req) %>% html_node(xpath = '//*[@id="north"]/div[2]/ul/li[1]/a')
req {xml_node} "#download"
onclick="openPdfDownload('20180402005019', '6060273'); return false;"> [1] "/images/common/viewer_down.gif" style="cursor:pointer;" alt="다운로드" title="다운로드">
req 변수 확인해보면 onclick 뒤의 openPdfDownload 부분이 있으며 앞의 20180402005019 부분은 위에서 나온 rcp_no,위의 6060273 부분이 해당 파일의 dcm에 해당.
dcm은 각 공시에 해당하는 문서번호로 이해.
req = req %>% html_attr('onclick')
dcm = stringr::str_split(req, ' ')[[1]][2] %>% readr::parse_number()
- html_attr() 함수를 이용해 'onclick' 부분의 데이터만 뽑아
- stringr 패키지의 str_split() 함수를 통해 캐릭터 값을 나눠준 후 두번째 값만을 뽑아내기
- 마지막으로 readr 패키지의 parse_number() 함수를 통해 해당 값에서 숫자 값만을 뽑아주도록 합니다.
- 정규표현식을 아신다면 해당작업이 훨씬 쉽게 가능
1.3.1 홈페이지 첨부된 엑셀 파일이 다운로드[편집]
- 상단의 다운로드 부분을 클릭한 후 팝업창이 뜨면, 다시 개발자 도구를 열어줍니다.
- 재무제표 항목을 클릭하면 파일이 다운로드
http://dart.fss.or.kr/pdf/download/excel.do
위의 url에 데이터를 요청하며 쿼리에 해당하는 부분은 rcp_no는 위에서 구한 값(공시번호),dcm_no 역시 위에서 찾아낸 문서번호,lang은 한국어인 ko가 있습니다.
R에서 post 형식으로 나타내면 다음과 같습니다.
query.base = list(
rcp_no = '20180402005019',
dcm_no = dcm
)
down.excel = POST('http://dart.fss.or.kr/pdf/download/excel.do', query = query.base)
down.excel
Response [http://dart.fss.or.kr/pdf/download/excel.do?rcp_no=20180402005019&dcm_no=5026126]
Date: 2019-02-18 14:08
Status: 200
Content-Type: application/vnd.ms-excel
Size: 74.8 kB
down.excel 변수를 확인해보면 엑셀 파일이 연결되어 있음이 확인됩니다.
writeBin(content(down.excel, "raw"), paste0(ticker, "_", data.df.rcp[i], '.xls'))
writeBin() 함수를 통해 해당 파일을 다운로드 받으며 저장 이름은 티커_rcp.xls 로 하도록 합니다.
모든 재무제표 항목이 포함된 엑셀파일이 잘 다운로드 됨이 확인됩니다.
df = readxl::read_excel( paste0(ticker, "_", data.df.rcp[i], '.xls'), sheet = 2)
df
# A tibble: 62 x 4
`연결 재무상태표` ..2 ..3 ..4
<chr> <chr> <chr> <chr>
1 제 49 기 2017.12.31 현재 NA NA NA
2 제 48 기 2016.12.31 현재 NA NA NA
3 제 47 기 2015.12.31 현재 NA NA NA
4 (단위 : 백만원) NA NA NA
5 NA 제 49 기 제 48 기 제 47 기
6 자산 NA NA NA
7 유동자산 146982464 141429704 124814725
8 현금및현금성자산 30545130 32111442 22636744
9 단기금융상품 49447696 52432411 44228800
10 단기매도가능금융자산 3191375 3638460 4627530
# ... with 52 more rows
read_excel() 함수를 통해 다운로드 받은 파일을읽어올 수도 있습니다.
처음 API를 통한 json 형태로 얻은 10개의 rcp를 통해 최근 10년치 엑셀 파일을 모두 다운로드 받는 방법은 for loop를 통해 해결할 수 있습니다.
<source lang=r>
for (i in 1 : length(data.df.rcp)) {
url.business.report = paste0('http://dart.fss.or.kr/dsaf001/main.do?rcpNo=',data.df.rcp[i])
req = GET(url.business.report)
req = read_html(req) %>% html_node(xpath = '//*[@id="north"]/div[2]/ul/li[1]/a')
req = req %>% html_attr('onclick')
dcm = stringr::str_split(req, ' ')[[1]][2] %>% readr::parse_number()
query.base = list(rcp_no = '20180402005019',dcm_no = dcm,lang = 'ko')
down.excel = POST('http://dart.fss.or.kr/pdf/download/excel.do',query = query.base)
writeBin(content(down.excel, "raw"), paste0(ticker, "_", data.df.rcp[i], '.xls'))
Sys.sleep(2)
print(i)
}
2 네이버 증권 재무제표[편집]
https://engkimbs.tistory.com/625
- 파이썬 코드
import requests
from bs4 import BeautifulSoup
URL = "https://finance.naver.com/item/main.nhn?code=005930"
samsung_electronic = requests.get(URL)
html = samsung_electronic.text
soup = BeautifulSoup(html, 'html.parser')
finance_html = soup.select('div.section.cop_analysis div.sub_section')[0]
th_data = [item.get_text().strip() for item in finance_html.select('thead th')]
annual_date = th_data[3:7]
quarter_date = th_data[7:13]
finance_index = [item.get_text().strip() for item in finance_html.select('th.h_th2')][3:]
finance_data = [item.get_text().strip() for item in finance_html.select('td')]
import numpy as np
finance_data = np.array(finance_data)
finance_data.resize(len(finance_index), 10)
finance_date = annual_date + quarter_date
import pandas as pd
finance = pd.DataFrame(data=finance_data[0:,0:], index=finance_index, columns=finance_date)
annual_finance = finance.iloc[:, :4]
quarter_finance = finance.iloc[:, 4:]