본문 바로가기

코딩

파이썬 네이버 금융 기업 정보 스크랩

https://engkimbs.tistory.com/

 

새로비

#IT #재테크

engkimbs.tistory.com

새로비님의 블로그에서 html 구조에서 정보를 얻는 데에 많은 도움을 받았습니다!

 

라이브러리부터 불러오기

 

import pandas as pd
import numpy as np
import requests
import lxml
from bs4 import BeautifulSoup
from requests import Response

 

 

기업정보를 얻어올 곳은 KIND이다.

주소: https://kind.krx.co.kr/corpgeneral/corpList.do?method=loadInitPage 

해당 페이지에서 F12를 눌러 개발자 도구를 연 후, 아래 사진의 엑셀 다운로드를 누르면 페이지에서 요청을 보내는 것이 개발자 도구의 네트워크 탭에서 보이는데, General 탭의 requset url에서 어떤 url로 요청이 가는지 알 수 있다.

 

이어서 네트워크 탭에서 Payload를 누른 후, Form Data의 view source를 클릭하면

아래의 옵션 정보를 확인할 수 있다. 

method=download&pageIndex=1&currentPageSize=3000&comAbbrv=&beginIndex=&orderMode=3&orderStat=D&isurCd=&repIsuSrtCd=&searchCodeType=&marketType=&searchType=13&industry=&fiscalYearEnd=all&comAbbrvTmp=&location=all

 

위 정보들을 확인한 메인 url인 아래 주소의 method 뒷자리부터, 찾아낸 옵션과 일치하게 입력하면 된다.

 

"https://kind.krx.co.kr/corpgeneral/corpList.do?method=loadInitPage" 이만큼 지우고

 

"method=download&pageIndex=1&currentPageSize=3000&comAbbrv=&beginIndex=&orderMode=3&orderStat=D&isurCd=&repIsuSrtCd=&searchCodeType=&marketType=&searchType=13&industry=&fiscalYearEnd=all&comAbbrvTmp=&location=all" 이거 입력

 

근데 아래 url만 입력해도 된다.

 

df_code = pd.read_html('https://kind.krx.co.kr/corpgeneral/corpList.do?method=download&searchType=13', header=0)[0]
df_code.종목코드 = df_code.종목코드.map('{:06d}'.format)

 

 

pd.read_html함수로 html을 읽어오면, 기업정보의 리스트를 읽어온다. 읽어온 데이터가 리스트 내부에 리스트가 들어있는 형식이라서 데이터프레임으로 나오지 않는다. [0]을 붙여서 리스트를 꺼내 데이터프레임으로 만든다.

종목코드는 6자리이기에 0을 채워서 6자리 숫자로 만들어주면 된다.

문자열로 바꾸고 zfill을 사용해도 된다.

 

반응형

 

def code_search(name):
    ticker = df_code[df_code.회사명 == name].종목코드.iat[0]
    return ticker

 

티커를 불러오는 함수를 만들었다. 값만 빼오고 싶은데 리턴이 데이터프레임의 셀로 나와서 iat[0]을 사용해서 값만 꺼내 주었다. 어차피 매칭 되는 것은 하나니까 뭐 괜찮겠지... 싶은데 혹시 더 좋은 방법을 아시면 댓글로 알려주세요.

 

이후, 회사 이름을 입력하면 코드를 검색해서 불러오도록 함수를 정의해보았다.

사실 이 아래는 첫 줄에 위에서 정의한 함수 넣은 것 빼고는 거의 새로비님의 블로그를 "엄청나게" 참고해서 만든 거라 내용이 별 차이가 없다. 

궁금하신 분은 https://engkimbs.tistory.com/625을 참고해주세요.

 

def crawl_overview(name):
    code = code_search(name)
    res = requests.get("https://finance.naver.com/item/main.naver?code=" + code)
    page_soup = BeautifulSoup(res.text, "lxml")
    finance_html = page_soup.select_one('div.cop_analysis')

    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')]

    finance_data = np.array(finance_data)
    finance_data.resize(len(finance_index),10) #new shape, refcheck

    finance_date = annual_date + quarter_date
    finance = pd.DataFrame(data=finance_data[0:,0:], index = finance_index, columns = finance_date)

    annual_finance = finance.iloc[:,:4]
    quarter_finance = finance.iloc[:,4:]

    return finance, annual_finance, quarter_finance

 

코드가 진행되는 순서는 우선 finance_html에 request로 요청하고, beautifulsoup로 읽어온 html 데이터를 저장한다.

저장된 html 데이터를 select를 통해서 읽어오고, get_text로 텍스트를 가져오고, strip으로 태그는 제거한다.

 

그래서 동네북 주식 삼성전자를 입력해보면 아래와 같이 결과가 나온다. 굳!

 

crawl_overview("삼성전자")
(             2018.12    2019.12    2020.12  ...    2021.06    2021.09 2021.12(E)
매출액        2,437,714  2,304,009  2,368,070  ...    636,716    739,792    753,510
영업이익         588,867    277,685    359,939  ...    125,667    158,175    150,733
당기순이익        443,449    217,389    264,078  ...     96,345    122,933    113,345
영업이익률          24.16      12.05      15.20  ...      19.74      21.38      20.00
순이익률           18.19       9.44      11.15  ...      15.13      16.62      15.04
ROE(지배주주)      19.63       8.69       9.98  ...      12.04      12.60           
부채비율           36.97      34.12      37.07  ...      36.29      38.30           
당좌비율          204.12     233.57     214.82  ...     214.08     210.70           
유보율        27,531.92  28,856.02  30,692.79  ...  31,140.36  32,225.78           
EPS(원)         6,024      3,166      3,841  ...      1,391      1,775      1,637
PER(배)          6.42      17.63      21.09  ...      16.99      14.36      46.97
BPS(원)        35,342     37,528     39,406  ...     40,361     42,447     43,229
PBR(배)          1.09       1.49       2.06  ...       2.00       1.75       1.78
주당배당금(원)       1,416      1,416      2,994  ...                                 
시가배당률(%)        3.66       2.54       3.70  ...                                 
배당성향(%)        21.92      44.73      77.95  ...

 

반응형