본문 바로가기

Data Science/Data Collection

[02. 웹크롤링] 002. 야후 파이낸스 일본 – 주가 데이터

728x90

글로벌 시대에 해외투자가 늘어남에 따라 해외주식에 대한 데이터 가공도 중요한 시대이다. 야후 파이낸스 재팬에서 일본 주식 주가 데이터를 크롤링 해보자.

 

 

Yahoo!ファイナンス - 株価やニュース、企業情報などを配信する投資・マネーの総合サイト

【ご注意】 市場を特定したい場合は、銘柄コードに続けて拡張子(例:4689.t)をつけてください。各市場の拡張子、詳細についてはこちらをご覧ください。 チャートについては、株式分割などがあった場合は分割日以前の取引値についてもさかのぼって修正を行っております。 前日比については、権利落ちなどの修正を行っておりません。 取引値は、東証、福証、札証はリアルタイムで、他市場は最低20分遅れで更新しています。全市場(東証、福証、札証も含む)の出来高・売買代金に関しては、最低20分遅れで表示しています。株式分割があっ

finance.yahoo.co.jp

 

소니의 종목코드인 6758.T를 입력하고 時系列 탭을 클릭하면 다음과 같은 주가 데이터가 나타난다.

 

[그림 2.3] 야후 재팬이 제공하는 소니 주가 데이터

 

크롤링을 하기 위한 url형태는 다음과 같다.

 

https://info.finance.yahoo.co.jp/history/?code=6758.T&sy=2019&sm=1&sd=1&ey=2020&em=1&ed=10&tm=d&p=1

 

이 url을 이용하여 크롤링 해보자.

 

daily_price = []
col_name = ['날짜', '시가', '고가', '저가', '종가', '거래량', '조정가']
fullUrl = 'https://info.finance.yahoo.co.jp/history/?code=6758.T&sy=2019&sm=1&sd=1&ey=2020&em=1&ed=10&tm=d&p=1'

response = requests.get(fullUrl, headers={'User-Agent': 'Mozilla/5.0'})
html = response.text
soup = BeautifulSoup(html, 'html.parser')
# 시세데이터가 있는 테이블 찾음
soup = soup.find('table', {'class': 'boardFin'})
# 컬럼행 다음부터 시세데이터
sise = soup.find_all('tr')[1:]

for r in sise:
    d = []
    temp = r.find_all('td')
    # 날짜형식 변환
    dt = temp[0].text.replace('年', '-').replace('月', '-').replace('日', '')
    dt = datetime.strptime(dt, '%Y-%m-%d').strftime('%Y-%m-%d')
    d.append(dt)
    d.append(temp[1].text.replace(',', ''))
    d.append(temp[2].text.replace(',', ''))
    d.append(temp[3].text.replace(',', ''))
    d.append(temp[4].text.replace(',', ''))
    d.append(temp[5].text.replace(',', ''))
    d.append(temp[6].text.replace(',', ''))

    daily_price.append(d)

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


결과 값
날짜    시가    고가    저가    종가       거래량   조정가
0   2020-01-10  7864  7916  7830  7843   7961300  7843
1   2020-01-09  7775  7839  7717  7804   9195400  7804
2   2020-01-08  7591  7702  7514  7660  11405100  7660
3   2020-01-07  7542  7703  7532  7655  11720000  7655
4   2020-01-06  7331  7429  7325  7420   5154100  7420
5   2019-12-30  7421  7423  7354  7401   4512200  7401
6   2019-12-27  7450  7482  7407  7450   3597500  7450
7   2019-12-26  7399  7440  7387  7427   2297900  7427
8   2019-12-25  7406  7423  7378  7417   1804200  7417
9   2019-12-24  7434  7466  7365  7406   2879500  7406
10  2019-12-23  7401  7426  7371  7392   3216600  7392
11  2019-12-20  7370  7378  7290  7326   7646000  7326
12  2019-12-19  7422  7472  7409  7453   3680000  7453
13  2019-12-18  7370  7439  7365  7413   3822100  7413
14  2019-12-17  7494  7496  7420  7455   5298600  7455
15  2019-12-16  7414  7505  7396  7466   4827100  7466
16  2019-12-13  7433  7476  7401  7443   8866500  7443
17  2019-12-12  7300  7320  7237  7301   7063400  7301
18  2019-12-11  7207  7230  7204  7219   6038200  7219
19  2019-12-10  7200  7268  7198  7245   6480100  7245

 

여기에 원하는 기간의 데이터를 받아오기 위해 코드를 함수화하고 수정하였다. 설정한 기간을 받아오기 위해 총 페이지 수를 계산해야하고 그 계산된 페이지만큼 루프를 돌면서 데이터를 크롤링하면 된다.

 

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_yahoo_japan(code, date_range):
    fullUrl = 'https://info.finance.yahoo.co.jp/history/?code=%s&sy=%s&sm=%s&sd=%s&ey=%s&em=%s&ed=%s&tm=d' % \
              (code, date_range[0].split('-')[0], date_range[0].split('-')[1], date_range[0].split('-')[2],
               date_range[1].split('-')[0], date_range[1].split('-')[1], date_range[1].split('-')[2])
    
    response = requests.get(fullUrl, headers={'User-Agent': 'Mozilla/5.0'})
    html = response.text
    soup = BeautifulSoup(html, 'html.parser')
    soup = soup.find('span', {'class': 'stocksHistoryPageing'})
    pg_length = math.ceil(int(soup.text.split('/')[1].split('件中')[0]) / 20)

    daily_price = []
    col_name = ['날짜', '시가', '고가', '저가', '종가', '거래량', '조정가']
    for p in range(1, pg_length + 1):
        fullUrl = 'https://info.finance.yahoo.co.jp/history/?code=%s&sy=%s&sm=%s&sd=%s&ey=%s&em=%s&ed=%s&tm=d&p=%s' % \
                  (code, date_range[0].split('-')[0], date_range[0].split('-')[1], date_range[0].split('-')[2],
                   date_range[1].split('-')[0], date_range[1].split('-')[1], date_range[1].split('-')[2], p)

        response = requests.get(fullUrl, headers={'User-Agent': 'Mozilla/5.0'})
        html = response.text
        soup = BeautifulSoup(html, 'html.parser')
        soup = soup.find('table', {'class': 'boardFin'})

        sise = soup.find_all('tr')[1:]

        for r in sise:
            d = []
            temp = r.find_all('td')
            dt = temp[0].text.replace('年', '-').replace('月', '-').replace('日', '')
            dt = datetime.strptime(dt, '%Y-%m-%d').strftime('%Y-%m-%d')
            d.append(dt)
            d.append(temp[1].text.replace(',', ''))
            d.append(temp[2].text.replace(',', ''))
            d.append(temp[3].text.replace(',', ''))
            d.append(temp[4].text.replace(',', ''))
            d.append(temp[5].text.replace(',', ''))
            d.append(temp[6].text.replace(',', ''))

            daily_price.append(d)

    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_yahoo_japan('6758.T', ['2019-01-01', '2020-01-10'])
    print(stock)


결과 값
날짜    시가    고가    저가    종가       거래량   조정가
0    2020-01-10  7864  7916  7830  7843   7961300  7843
1    2020-01-09  7775  7839  7717  7804   9195400  7804
2    2020-01-08  7591  7702  7514  7660  11405100  7660
3    2020-01-07  7542  7703  7532  7655  11720000  7655
4    2020-01-06  7331  7429  7325  7420   5154100  7420
..          ...   ...   ...   ...   ...       ...   ...
241  2019-01-10  5349  5385  5223  5246   6571100  5246
242  2019-01-09  5439  5465  5373  5413   5033800  5413
243  2019-01-08  5395  5408  5310  5376   5764200  5376
244  2019-01-07  5403  5482  5335  5370   6878000  5370
245  2019-01-04  5148  5185  5025  5182   9040000  5182
728x90