본문 바로가기

Data Science/Data Collection

[02. 웹크롤링] 001. 네이버 – 주가 데이터

728x90

네이버는 국내 최대 포털 사이트이다. 주식 및 부동산 등 여러가지 정보를 제공해주고 있다. 네이버의 주가 데이터를 웹크롤링하는 방법에 대해 알아보자.

 

네이버에서 삼성전자 주가 데이터를 한 번 보자

 

 

네이버 금융

국내 해외 증시 지수, 시장지표, 펀드, 뉴스, 증권사 리서치 등 제공

finance.naver.com

 

스크롤을 내리면 일별시세란 부분이 보인다. 이 부분을 바로 우리가 크롤링할 것이다.

 

일별시세의 주소는 다음 주소에서 더욱 깔끔하게 볼 수 있다.

 

 

네이버 금융

 

finance.naver.com

 

[그림 2.1] 삼성전자 일별시세

 

구조를 살펴보면 10개의 데이터씩 일별로 보여준다. 제공하는 데이터는 날짜, 종가, 전일비, 시가, 고가, 저가, 거래량이다.

 

페이지에서 마우스 오른쪽 버튼을 눌러 소스 보기로 들어가면 다음과 같이 웹의 언어로 보인다.

 

[그림 2.2] 소스 보기로 본 구조

 

구조를 보면 <tr> ~ </tr> 부분이 일자별 데이터가 있는 부분임을 알 수 있다. 이 부분의 데이터를 파이썬으로 크롤링 해보자.

 

bs4와 requests라는 패키지를 사용해야 한다. 없다면 pip install bs4, pip install requests로 설치하자.

 

from bs4 import BeautifulSoup
import requests
import pandas as pd
from datetime import datetime

# 데이터가 있는 url
fullUrl = 'https://finance.naver.com/item/sise_day.nhn?code=%s&page=%s' % ('005930', '1')
response = requests.get(fullUrl)
html = response.text
soup = BeautifulSoup(html, 'html.parser')

# <table>을 가져옴
soup = soup.find('table')

# 첫 번째 <tr>은 컬럼이므로 잘라서 저장
col_name = soup.find('tr').text.split('\n')[1:-1]
sise = soup.find_all('tr')

daily_price = []
for r in sise:
    # 시세 데이터가 있는 테이블 행을 반복하면서 <span> 안에 있는 데이터를 가져옴
    span = r.find_all('span')
    temp = []
    for c in range(len(span)):
        # 첫 번째 <span>은 날짜이므로 날짜 형식으로 변환
        if c == 0:
            temp.append(datetime.strptime(span[c].text.strip(), "%Y.%m.%d").strftime("%Y-%m-%d"))
        # 나머지는 숫자 데이터이므로 , 제거
        else:
            temp.append(span[c].text.strip().replace(',', ''))
    if len(temp) > 0:
        daily_price.append(temp)

df = pd.DataFrame(daily_price, columns=col_name)
print(df)


결과 값
날짜     종가   전일비     시가     고가     저가       거래량
0  2020-01-03  55500   300  56000  56600  54900  15307310
1  2020-01-02  55200   600  55500  56000  55000  12993228
2  2019-12-30  55800   700  56200  56600  55700   8356767
3  2019-12-27  56500  1100  55700  56900  55500  12313056
4  2019-12-26  55400   400  54700  55400  54400   9645034
5  2019-12-24  55000   500  55600  55700  54800  11868463
6  2019-12-23  55500   500  56100  56400  55100   9839252
7  2019-12-20  56000     0  56100  56500  55600  12095519
8  2019-12-19  56000   300  57000  57300  55500  14180520
9  2019-12-18  56300   400  56700  57200  56000  15558208

 

크롤링이 잘되었다. pandas패키지는 파이썬에서 데이터 분석에 없어서는 안되는 라이브러리다. 반드시 공부할 필요가 있다. pandas를 계속 쓰기 위해 dataframe 형식으로 결과 값을 출력했다.

 

위 코드를 조금 업그레이드하여 기간데이터를 크롤링하게 바꿔보았다. 코드를 보면서 공부해보길 바란다.

 

from bs4 import BeautifulSoup
import requests
import math
import pandas as pd
import numpy as np
from datetime import datetime

def get_stock_data_from_naver(code, date_range):
    pg_length = math.ceil(np.busday_count('2019-01-01', '2020-01-03') / 10)

    daily_price = []
    col_name = ''
    for p in range(1, pg_length + 1):
        fullUrl = 'https://finance.naver.com/item/sise_day.nhn?code=%s&page=%s' % (code, p)
        response = requests.get(fullUrl, headers={'User-Agent': 'Mozilla/5.0'})
        html = response.text
        soup = BeautifulSoup(html, 'html.parser')
        soup = soup.find('table')
        if col_name == '':
            col_name = soup.find('tr').text.split('\n')[1:-1]
        sise = soup.find_all('tr')

        for r in sise:
            span = r.find_all('span')
            temp = []
            for c in range(len(span)):
                if c == 0:
                    temp.append(datetime.strptime(span[c].text.strip(), "%Y.%m.%d").strftime("%Y-%m-%d"))
                else:
                    temp.append(span[c].text.strip().replace(',', ''))
            if len(temp) > 0:
                daily_price.append(temp)

    df = pd.DataFrame(daily_price, columns=col_name)
    df = df[(df['날짜'] >= date_range[0]) & (df['날짜'] <= date_range[1])]

    return df

if __name__ == '__main__':
    stock = get_stock_data_from_naver('005930', ['2020-01-01', '2020-01-03'])
    print(stock)


결과 값
날짜     종가  전일비     시가     고가     저가       거래량
0  2020-01-03  55500  300  56000  56600  54900  15307310
1  2020-01-02  55200  600  55500  56000  55000  12993228

 

 

728x90