-
[Python] naver finance 에서 원하는 정보 긁어오기 Part 1. (한국편)Programming 2022. 9. 9. 19:39
이번 포스팅에서는 naver finance 에서 데이터를 긁어오는 걸 할 텐데, naver finance 에서 제공하는 API 를 이용하려 한다.
먼저 데이터를 긁어오기 전에 한국 주식 거래소에서 거래되는 종목들의 ticker 를 먼저 알아야한다.
https://seibro.or.kr/websquare/control.jsp?w2xPath=/IPORTAL/user/stock/BIP_CNTS02004V.xml&menuNo=40
SEIBro
seibro.or.kr
위의 링크로 이동해, 아래와 같은 화면에서 종목 전체 검색 후 목록 전체를 .xls 파일로 다운받을 수 있다. 다운받은 파일에 대한 처리가 일부 필요하여 첨부로 KOSPI, KOSDAQ 종목들을 .xlsx 파일로 올려두니, 시간 절약 겸 첨부 파일을 이용하시길
이번편에서는 미국편과 달리 한국 주식 데이터를 긁어오기 위해서는 크롤링(crawling)을 해야한다. 미국 주식에 대한 재무제표 정보는 yahoo finance 에서 무료로 제공하는 API 를 통해 데이터를 긁어올 수 있지만, naver finance API 는 살펴보니 유료로 데이터를 제공하는 것 같다.
네이버 파이낸스 API 사용 가능 여부 그래서 URL 으로 접근하여 웹페이지를 구성하는 요소들을 긁어와, 필요한 정보를 추출해서 사용하려 한다.
지난 포스팅에서 정리했던 퀀트 기법에 필요한 정보를 naver finance 에서 제공하는 정보와 matching 해보면 아래의 표와 같다.
yahoo finance 에서 봤던 것과 동일하게 각 정보들이 한 곳에 모여있지 않고 산재되어 있기 때문에 그룹별로 모아서 처리하는 게 좋다.
Measures naver finance 에 matching naver finance tab 적용 기법 PER PER(배) 기업현황 NCAV, 3P Combo PBR PBR(배) 기업현황 Graham, 3P Combo, PBR + GP/A PSR 시가총액/매출액 기업현황 3P Combo Market cap 시가총액(억) 기업현황 NCAV Current assets 유동자산 재무분석 (재무상태표) NCAV Total liabilities 부채총계(억) 기업현황 NCAV Total debt/equity 부채총계 / 자본총계 기업현황 Graham ROA ROA(%) 기업현황 Graham Net income 당기 순이익 기업현황 NCAV GP/A 매출총이익 / 자산총액 재무분석 (포괄손익계산서) PBR + GP/A 1) 필요한 정보가 포함된 URL 주소 확인하기
- 기본적으로 yahoo finance 와 동일하게 URL에 종목코드를 변수로 받아 종목코드별(기업별) 페이지를 구성하고 있다.
- 각 페이지에서 우리가 필요한 정보는 위 표에서 정리한 대로 "기업현황"과 "재무분석" tab 에 있다.
종목분석 tab 예시 (SK하이닉스) - 우선 chrome 개발자 도구를 켜고, "기업현황" tab 을 누르면, 오른쪽 "href" 부분에서 해당 tab 에 연결되는 URL 정보를 확인할 수 있다.
기업현황 URL https://navercomp.wisereport.co.kr/v2/company/c1010001.aspx?cmp_cd={종목코드}
- 그런데 해당 tab 에서 우리가 원하는 "Financial Summary" 부분에 대한 URL 은 위의 URL 과 개별로 분리되어 있다.
(데이터가 업데이트되는 부분이라 따로 구성되어 있는 듯)
- Chrome 개발자 도구를 - Network 을 켜고 "기업현황" tab 을 누르면, 호출에 대한 응답을 볼 수 있다.
그 중 "cF1001.aspx?cmp=cd" 부분을 보면 매출액, 영업이익 등이 html 언어로 표현되어 있는 것을 알 수 있다.
기업현황 URL 찾기 이렇게 우리는 원하는 정보가 포함되어 있는 페이지의 URL을 얻을 수 있다. 보통 정보를 숨기지 않는 한 URL 을 통해 어느 정도 정보를 파악할 수 있는데, cmp_cd 는 종목코드 / freq_typ 은 연간(A), 분기(Q) / encparam 과 id 는 종목별로 랜덤하게 부여되는 key 값 정도로 파악된다.
https://navercomp.wisereport.co.kr/v2/company/ajax/cF1001.aspx?cmp_cd=000660&fin_typ=4&freq_typ=A&encparam=N2FKWGZ2My9UK2s1Q1ZIVkFSU0kwdz09&id=RVArcVR1a2
기업현황 URL 2) 원하는 데이터가 포함된 URL 찾기
- URL 을 찾았으니 우리가 추출할 수 있는 데이터를 한 번 긁어와보자. 위에서 "encparam" 과 "id" 는 랜덤 key 값으로 해석된다고 했는데, 그럼 우리가 이 정보들을 알고 접근할 수는 없다.
- 따라서 두 component 를 html 에서 찾아서 접근하는 방법을 사용하려 한다. 아래의 코드는 필요한 두 component 를 찾는 함수가 구현된 것이다.
import pandas as pd def get_basic_key_values(code): # 기본적인 종목별 encparam, encid 찾기 url = 'https://navercomp.wisereport.co.kr/v2/company/c1010001.aspx?cmp_cd={}'.format(code) html = requests.get(url).text re_enc = re.compile("encparam: '(.*)'", re.IGNORECASE) re_id = re.compile("id: '([a-zA-Z0-9]*)' ?", re.IGNORECASE) encparam = re_enc.search(html).group(1) encid = re_id.search(html).group(1) return encparam, encid code = '000660' #SK하이닉스 종목코드 encparam, encid = get_basic_key_values(code)
3) 원하는 데이터 긁어오기
- 위에서 얻은 정보들로 우리는 새로운 URL 은 다음과 같이 정의할 수 있다.
http://companyinfo.stock.naver.com/v1/company/ajax/cF1001.aspx?cmp_cd=000660&fin_type=0&freq_type=A&encparam=bEJ1c29ReE5yOUJrSU1QelpHR0ZVQT09&id=bG05RlB6cn
그렇다면 우리는 아래와 같은 함수를 활용해서 "Financial Summary" 에 해당하는 데이터 프레임을 불러올 수 있게 된다.
def get_dataframe(code): encparam, encid = get_basic_key_values(code) url = 'http://companyinfo.stock.naver.com/v1/company/ajax/cF1001.aspx?cmp_cd={}&fin_type=0&freq_type=A&encparam={}&id={}'.format(code, encparam, encid) headers = {'Referer': 'HACK'} html = requests.get(url, headers=headers).text dfs = pd.read_html(html) df = dfs[1] return df
불러온 데이터 프레임은 아래와 같이 구성되어 있는 것을 확인할 수 있다.
불러온 Financial Summary 데이터 여기서 원하는 정보를 뽑아내면 되는데, 글이 길어지는 관계로 이번 포스팅은 이 정도로 마무리하려 한다.
다음 포스팅에서는 실제로 우리가 퀀트 기법을 적용하기 위해 필요한 정보를 추출하고 정리하는 방법을 다룰 예정이다.
'Programming' 카테고리의 다른 글
[Python] 퀀트 투자 기법 적용 결과 (한국편) (1) 2022.09.17 [Python] naver finance 에서 원하는 정보 긁어오기 Part 2. (한국편) (0) 2022.09.15 [Python] 퀀트 투자 기법 적용하기 Part 2. (미국편) (0) 2022.09.03 [Python] 퀀트 투자 기법 적용하기 Part 1. (미국편) (2) 2022.08.28 [Python] yahoo finance 에서 원하는 정보 긁어오기 (미국편) (2) 2022.08.24