상세 컨텐츠

본문 제목

[Python] JSON FILE CRAWLING를 이용한 주가 데이터 크롤링

카테고리 없음

by 별달하현 2023. 2. 17. 00:36

본문

# JSON FILE CRAWLIING : 웹사이트 전체 틀은 유지하면서 보이지 않는 곳에서 데이터를 불러오고 일부 데이터를 바꾸는 기법을 사용시, 프로그래머는 JavaScript를 사용. 이를 이용해 서버에 데이터를 요청하면, 서버는 JSON이라는 파일 형태에 데이터를 담아줌. 이 데이터를 이용한 크롤링 방식을 의미함.

오른쪽 검사창에서 Network를 클릭 이후 왼쪽 인터페이스창의 페이지를 바꿔주면 위와 같은 데이터들이 뜸. 이후 오른쪽 창의 맨 위의 데이터를 우클릭 후 copy->copy link address를 클릭하면 url 복사 가능.=>https://finance.naver.com/world/worldDayListJson.naver?symbol=SPI@SPX&fdtc=0&page=2(일별 시세 우클릭 후 '검사' 클릭하면 위와 같이 됨)

# 필요한 모듈 불러오기

import pandas as pd
from urllib.request import urlopen 
import json

#일반적으로 json.read함수를 이용한 방식은 더이상 통하지 x=> 웹페이지 접근 시 이용자의 address를 숨기기 위해 hdr 딕셔너리를 이용해, 웹페이지를 속여서 데이터를 긁어와야함.

import json
from urllib.request import urlopen, Request

url = 'https://finance.naver.com/world/worldDayListJson.nhn?symbol=SPI@SPX&fdtc=0&page=1'
# User-Agent는 구글에 what is my user agent?치면 나옴
hdr = {
"User-Agent":
"Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.157 Safari/537.36"
}
req = Request(url, headers = hdr)
raw = urlopen(req)

raw_encoded = raw.read().decode('euc-kr') # 한글로 된 url을 디코딩해주는 방법

data = json.loads(raw_encoded)
print(data[0]['xymd'])
print(data[0]['clos'])

#pd.Dataframe()함수 : 괄호 속 데이터를 아래와 같이 출력해줌

***이외의 내용은 html crawling에서와 유사함***

def date_format(d=''):
    if d != '':
        this_date = pd.to_datetime(d).date()

    else:
        this_date = pd.Timestamp.today().date()  #오늘 날짜를 지정

    return this_date

def index_global(d, symbol, start_date='', end_date='',page=1):

    end_date = date_format(end_date)
    if start_date =='':
        start_date = end_date - pd.DateOffset(months=1)
    
    start_date = date_format(start_date)

    url = 'https://finance.naver.com/world/worldDayListJson.nhn?symbol='+symbol+'&fdtc=0&page='+str(page)
    hdr = {
    "User-Agent":
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36M"
    }
    req = Request(url, headers = hdr)
    raw = urlopen(req)

    raw_encoded = raw.read().decode('euc-kr')

    data = json.loads(raw_encoded)
    
    if len(data)>0:

        for n in range(len(data)):
            date = pd.to_datetime(data[n]['xymd']).date()

            if date <= end_date and date >= start_date:
                price = float(data[n]['clos'])

                d[date]=price
            
            elif date < start_date:
                return d
            
        if len(data) == 10:
            page +=1
            index_global(d, symbol, start_date, end_date,page)

    return d
    
#1 여러 종목을 한 번에 출력하는 방법
indices= {
    'SPI@SPX' : 'S&P 500',
    'NAS@NDX' : 'Nasdaq 100',
    'NII@NI225' : 'Nikkei 225'
}

historical_indices = dict()
start_date = '2023-01-01'
end_date = '2023-02-02'

for key, value in indices.items():  #.items() : 딕셔너리에 있는 쌍의 개수를 세어줌.
    s = dict()
    s = index_global(s, key, start_date)
    historical_indices[value]=s

prices_df = pd.DataFrame(historical_indices)
prices_df

#2 한 종목만 출력하는 방법
index_cd='SPI@SPX'
historical_prices = dict()
sp500 = index_global(historical_prices, index_cd, '2022-1-1', '2022-12-31')

 

참고 : 파이썬을 이용한 금융공학 레시피(김용환)