본문 바로가기

프로젝트/크롤링, 스크래핑

[Python] (1)네이버 금융 증권 데이터(PER,PBR,배당률) 수집 : 크롤링

https://finance.naver.com/ 네이버 금융 웹사이트

 

오늘은 크롤링을 사용하여 네이버 금융에서 증권 데이터를 수집해보도록 하겠습니다.

 

두 번째 포스팅에 프로그램을 실행해 볼 수 있도록 코랩 링크 달아놓겠습니다.

 

코딩에 대한 지식이 없는 분들도 단순히 프로그램을 실행하여 코스피 증권 데이터를 엑셀로 가져가실 수 있습니다.

 

리스트에 코스피에 상장된 주식들의 티커 저장하기


# 모듈 가져오기
!pip install pykrx
from pykrx import stock

# 오늘날 코스피에 상장되어 있는 주식의 이름과 티커 수집 
today = datetime.today().strftime("%Y%m%d")
ticker_list = stock.get_market_ticker_list(date = today, market="KOSPI")
symbol_list = []
for ticker in ticker_list:
    symbol = stock.get_market_ticker_name(ticker)
    symbol_list.append(symbol)

# 코스피 상장 주식의 개수 확인
print(len(ticker_list))
print(len(symbol_list))

 

pykrx라이브러리에 저장되어 있는 코스피 상장 주식들을 리스트에 저장합니다.

 

get_market_ticker_list 메서드를 사용해 상장된 주식의 티커를 수집하고

get_market_ticker_name 메소드를 사용해 상장된 주식의 이름을 수집합니다.

 

주식의 이름을 담은 리스트는 symbol_list에, 주식의 티커를 담은 리스트는 ticker_list에 저장합니다.

 

stock.get_market_ticker_list(date = today, market="KOSPI")

부분에서 date와 market을 자신이 원하는 대로 변경할 수 있습니다.

 

date는 "YYYYmmdd" (ex.20210210) 양식으로 넣어주셔야 하고 market은 "KOSPI", "KOSDAQ", "KONEX"를 넣어주시거나

모두 수집하고 싶다면 "ALL"을 넣어주시면 됩니다. (전부 수집할 경우 시간이 오래 걸리기 때문에 권장하지 않습니다)

 

 

CSS Selector 수집하기


# 수집할 증권 데이터의 셀렉터 저장
per_selector = "#_per"
pbr_selector = "#_pbr"
dividend_yield_selector = "#_dvr"

 

 

 

일단 크롤링을 위해서 css selector를 사용할 것이므로 수집 방법을 알려드리겠습니다.

 

 

 

1. 네이버 금융 페이지에서 아무 주식명을 검색합니다.

2. f12를 눌러 개발자 도구를 엽니다.

3. 요소를 선택하기 1번 표시된 부분을 클릭합니다.

4. 사이트 내에서 수집하고자 하는 데이터 위에 마우스를 클릭합니다.

(간단한 수집을 위해 PER, PBR, 배당수익률의 숫자 부분을 클릭하시길 권장합니다)

5. html코드에서 파란색 줄이 쳐진 곳을 마우스 우클릭합니다.

6. copy -> copy selector를 클릭합니다.

 

자 이제 html 태그를 사용해 수집하려는 데이터의 css selector를 가져오는 데 성공했습니다!

 

이제 css selector를 사용하여 크롤링을 할 수 있습니다. 

 

아무 곳에나 붙여 넣기를 해보면 "#_per" 이런 식으로 수집된 것을 볼 수 있습니다.

(#은 id를 의미합니다)

 

크롤링을 사용하여 증권 데이터 수집하기


float변환을 위해 따옴표 제거# 모듈 가져오기
import requests
from bs4 import BeautifulSoup

# 크롤링을 사용하여 증권 데이터 수집하기
pers = []
pbrs = []
dividend_yields = []

for ticker in ticker_list:
    url = f"https://finance.naver.com/item/main.nhn?code={ticker}"
    html = requests.get(url, headers={'User-agent':'Mozilla/5.0'})
    soup = BeautifulSoup(html.text, "lxml")
    per = soup.select(per_selector)
    pbr = soup.select(pbr_selector)
    dividend_yield = soup.select(dividend_yield_selector)

    if not per:  # 리스트가 비어있을 경우 None으로 변환
        per = [None]
    for pe in per:
        if pe != None:
            per_text = pe.text
            per_text = per_text.replace(",", "")  # float변환을 위해 따옴표 제거
            pers.append(float(per_text))
        else:
            per_text = pe
            pers.append(per_text)

    if not pbr:  # 리스트가 비어있을 경우 None으로 변환
        pbr = [None]
    for pb in pbr:
        if pb != None:
            pbr_text = pb.text
            pbr_text = pbr_text.replace(",", "")  # float변환을 위해 따옴표 제거
            pbrs.append(float(pbr_text))
        else:
            pbr_text = pb
            pbrs.append(pbr_text)
        
    if not dividend_yield:  # 리스트가 비어있을 경우 None으로 변환
        dividend_yield = [None]
    for d in dividend_yield:
        if d != None:
            dividend_yield_text = d.text
            dividend_yield_text = dividend_yield_text.replace(",", "")  # float변환을 위해 따옴표 제거
            dividend_yields.append(float(dividend_yield_text))
        else:
            dividend_yield_text = d
            dividend_yields.append(dividend_yield_text)

 

코스피 상장 주식의 PER, PBR, 배당률 데이터를 수집합니다.

 

기본적인 크롤링 모듈인 request와 beautifulsoup을 사용하여 크롤링합니다.

 

웹사이트 캡처 사진의 url을 보면 빨간 밑줄 쳐진 곳에 주식의 티커가 들어가는 것을 알 수 있습니다.

 

따라서 url 변수에 f스트링을 사용하여 각 주식의 웹사이트에 접속할 수 있도록 해줍니다.

 

headers={'User-agent':'Mozilla/5.0'}를 넣은 이유는 수집하는 주체가 봇이 아닌 유저임을 알리기 위해서입니다.

(위 코드를 삽입하지 않을 경우 봇으로 인지해 크롤링을 할 수 없습니다.)

 

soup = BeautifulSoup(html.text, "lxml")

"html.parser"보다 "lxml"으로 파싱 하는 것이 더 빠릅니다.

단 "lxml"은 추가 설치가 필요하므로 작동이 안 될 경우 "html.parser"을 삽입해 주십시오. 

 

데이터가 수집될 때 리스트 형식으로 수집되므로 for문으로 리스트를 풀어주고 append로 새로운 리스트에 담아줍니다.

(예를 들어 per = soup.select(per_selector)에서 per은 per데이터 한 개가 들어있는 리스트입니다)

 

수집하려는 데이터가 비어있는 경우에는 None으로 변환해줍니다.

(배당금을 주지 않는 주식의 경우 배당률 데이터가 비어있습니다)

 

코랩으로 위 코드를 돌릴 경우 약 10분 ~ 15분 정도 소요됩니다.

 

pers, pbrs, dividend_yields를 출력해보면 데이터가 잘 수집된 것을 볼 수 있습니다.

 


수집한 데이터를 모아 보기 좋게 시각화를 하고, 데이터프레임에 정리하고 엑셀로 변환하는 작업은 다음에 진행해 보도록 하겠습니다.

 

https://bigdata-doctrine.tistory.com/4

 

[Python] (2)네이버 금융 증권 데이터(PER,PBR,배당률) 수집 : 데이터프레임

https://bigdata-doctrine.tistory.com/3 [Python] (1)증권 데이터(PER,PBR,배당률) 수집 : 크롤링 https://finance.naver.com/ 네이버 금융 웹사이트 오늘은 크롤링을 사용하여 네이버 금융에서 증권 데이터를 수..

bigdata-doctrine.tistory.com