06. ์น ์คํฌ๋ํ ์ค์ต - ์ข ๋ชฉ์ ์บ๋ค์ฐจํธ
06. ์น ์คํฌ๋ํ ์ค์ต - ์ข ๋ชฉ์ ์บ๋ค์ฐจํธ ๊ด๋ จ
01. ์ข ๋ชฉ์ ๊ฐ๊ฒฉ ๋ฐ์ดํฐ ํฌ๋กค๋ง
์ ํธ๋ฆฌ์จ ์ข ๊ฐ ํฌ๋กค๋ง
import pandas as pd
import matplotlib.pyplot as plt
import requests
from datetime import datetime
from matplotlib import dates as mdates
from bs4 import BeautifulSoup as bs
์๋์ ์ฃผ์๋ก๋ถํฐ ํฌ๋กค๋ง์ ํด๋ด ์๋ค.
url = 'https://finance.naver.com/item/sise_day.nhn?code=068270&page=1'
ํด๋น ์ฃผ์๋ก ์ ์ํด๋ณด๋ฉด ์ ํธ๋ฆฌ์จ์ ์ผ๋ณ ์ข ๊ฐ, ์ ์ผ๋น, ์๊ฐ, ๊ณ ๊ฐ, ์ ๊ฐ, ๊ฑฐ๋๋์ด ์ ๋ฐ์ดํธ ๋๊ณ ์๋ ์ฌ์ดํธ์ ๋๋ค. ๋ค์ด๋ฒ ๊ธ์ต ์ฌ์ดํธ์์ ์ ํธ๋ฆฌ์จ์ ๊ฒ์ ํ ์ ์ํ์ฌ ์ป์ ์ฃผ์๋ผ๊ณ ๋ณด์๋ฉด ๋ฉ๋๋ค.
requests๋ผ๋ ํจํค์ง์ ์๋ get์ด๋ผ๋ ๋ชจ๋(ํจ์)์ url์ ์ ๋ ฅ์ผ๋ก ํ๊ณ , ์ด๋ฅผ ๋ณ์์ ์ ์ฅํ ํ์ ๋ณ์.text๋ฅผ ํ๋ฉด ํด๋น URL์ HTML ์ฝ๋๋ฅผ ๋ฐ์์ฌ ์ ์์ต๋๋ค. HTML ์ฝ๋๋ฅผ ๋ฐ์์ค๋ ๋ฐฉ๋ฒ์ ์๋์ ๊ฐ์ต๋๋ค.
response = requests.get(url)
response.text
HTML ์ฝ๋๋ฅผ ๋ฐ์์ค๋ ํ์ด์ฌ ์ฝ๋๋ฅผ ์คํํ๊ธฐ ์ ์ ์์ headers๋ผ๋ ๊ฐ๋ ์ด ํ์ํฉ๋๋ค.
headers = {'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36'}
response = requests.get(url, headers=headers)
์์ ๋งํฌ์์ ์ค๋ช
ํ๊ณ ์๋ฏ์ด, ์ ์ ์์ด์ ํธ๋ฅผ ์ธ์๋ก ๋ฃ์ด์ get ํจ์๋ฅผ ์ฌ์ฉํ๋ฉด ํฌ๋กค๋ง ๋ฐฉ์ง ์ฐจ๋จ์ ๋ซ๊ณ ํฌ๋กค๋ง์ ํ ์ ์์ต๋๋ค. ์์ headers๊ฐ์ ๊ฐ์ฌ์ ๋ธ๋ผ์ฐ์ ์์ ์ถ์ถํ ๊ฐ์ผ๋ก ์ฌ๋ฌ๋ถ๋ค์ ์ฌ๋ฌ๋ถ๋ค์ ์์ด์ ํธ ์ ๋ณด๋ฅผ ์ถ์ถํด์ ์ฌ์ฉํ์
๋ ๋ฉ๋๋ค! ์ด์ response.text
๋ฅผ ์ถ๋ ฅํด๋ณผ๊น์?
response.text
#
# \n<html lang="ko">\n<head>\n<meta http-equiv="Content-Type" content="text/html; charset=euc-kr">\n<title>๋ค์ด๋ฒ ๊ธ์ต</title>\n\n<link rel="stylesheet" type="text/css" href="https://ssl.pstatic.net/imgstock/static.pc/20220819210825/css/newstock.css">\n<link rel="stylesheet" type="text/css" href="https://ssl.pstatic.net/imgstock/static.pc/20220819210825/css/common.css">\n<link rel="stylesheet" type="text/css" href="https://ssl.pstatic.net/imgstock/static.pc/20220819210825/css/layout.css">\n<link rel="stylesheet" type="text/css" href="https://ssl.pstatic.net/imgstock/static.pc/20220819210825/css/main.css">\n<link rel="stylesheet" type="text/css" href="https://ssl.pstatic.net/imgstock/static.pc/20220819210825/css/newstock2.css">\n<link rel="stylesheet" type="text/css" href="https://ssl.pstatic.net/imgstock/static.pc/20220819210825/css/newstock3.css">\n<link rel="stylesheet" type="text/css" href="https://ssl.pstatic.net/imgstock/static.pc/20220819210825/css/world.css">\n</head>\n<body>\n<script ... ์ค๋ต ...
BeautifulSoup4๋ฅผ ํตํด์ ํด๋น HTML ์ฝ๋๋ฅผ ํ์ฑํฉ๋๋ค.
html = bs(response.text, 'html.parser')
html_table = html.select("table")
table = pd.read_html(str(html_table))
print('ํ์ฑ๋ ํ
์ด๋ธ์ ๊ฐ์ :', len(table))
#
# ํ์ฑ๋ ํ
์ด๋ธ์ ๊ฐ์ : 2
์ฒซ๋ฒ์งธ ํ ์ด๋ธ์ ์ถ๋ ฅํด๋ด ์๋ค.
table[0]
- ๋ถ๋ฌ์จ ๊ฒฐ๊ณผ๊ฐ ์ ์ ๋ฌ๋ผ๋ ์๊ด์์ต๋๋ค. ์ ๋ ์ด ์ค์ต์ 2022๋ 8์ 29์ผ์ ํ์๊ธฐ๋๋ฌธ์ 8์ 29์ผ๊น์ง์ ์ฃผ๊ฐ๊ฐ ์๋ ๊ฒ์ด๊ณ , ์ฌ๋ฌ๋ถ๋ค์ด ์ค์ต์ ํ ๋๋ ๋ ๊ทธ๋ ๊ธฐ์ค์ ์ฃผ๊ฐ ๋ฐ์ดํฐ๋ฅผ ๋ถ๋ฌ์ฌ ๊ฒ์ ๋๋ค.
์ ํธ๋ฆฌ์จ์ ์ผ๋ณ ์ข ๊ฐ, ์ ์ผ๋น, ์๊ฐ, ๊ณ ๊ฐ, ์ ๊ฐ, ๊ฑฐ๋๋์ด ์๋ ํ ์ด๋ธ์ ๋๋ค. ๋ค๋ง, ์ค๊ฐ์ ๊ฒฐ์ธก๊ฐ๋ค์ด ์กด์ฌํฉ๋๋ค. ๋๋ฒ์งธ ํ ์ด๋ธ์ ์ถ๋ ฅํด๋ด ์๋ค.
table[1]
๋๋ฒ์งธ ํ
์ด๋ธ์ ์ฐ๋ฆฌ๊ฐ ์ํ๋ ํ
์ด๋ธ์ด ์๋๋๋ค. ์ฒซ๋ฒ์งธ ํ
์ด๋ธ๋ง์ ์ฌ์ฉํ๋ค๊ณ ๊ฐ์ ํด๋ด
์๋ค. ๊ทธ๋ฐ๋ฐ ์ฒซ๋ฒ์งธ ํ
์ด๋ธ์ ์์ ํ์ธํ์ ๋ ๊ฒฐ์ธก๊ฐ์ด ์์์ผ๋ฏ๋ก ๊ฒฐ์ธก๊ฐ์ ์ ๊ฑฐํ์ฌ ์ถ๋ ฅํด๋ด
์๋ค. ๋จ์ํ ๊ฒฐ์ธก๊ฐ์ ์ ๊ฑฐํ๋ ๊ฒ์ dropna()
๋ฅผ ํตํด์ ๊ฐ๋ฅํฉ๋๋ค.
table[0].dropna()
์์ ์งํํ๋ ์ผ๋ จ์ ๊ณผ์ ๋ค์ 1ํ์ด์ง๋ถํฐ 99ํ์ด์ง๊น์ง ๋ฐ๋ณตํด๋ด ์๋ค.
df = pd.DataFrame()
sise_url = 'https://finance.naver.com/item/sise_day.nhn?code=068270'
for page in range(1, 100):
page_url = '{}&page={}'.format(sise_url, page)
print(page_url)
# ์์์ ํ๋ ์ผ๋ จ์ ๊ณผ์ ๋ค์ ๊ฐ url์ ๋ํด์ (99ํ์ด์ง์ ๋ํด์ ๋ฐ๋ณต)
response = requests.get(page_url, headers=headers)
html = bs(response.text, 'html.parser')
html_table = html.select("table")
table = pd.read_html(str(html_table))
# ํ์ฌ ์ป์ ๋ฐ์ดํฐํ๋ ์์ ๊ธฐ์กด ๋ฐ์ดํฐํ๋ ์์ ๋์ .
df = df.append(table[0].dropna())
ํฌ๋กค๋ง์ด ๋๋ฌ๋ค๋ฉด ๋ฐ์ดํฐํ๋ ์์ ์ถ๋ ฅํด๋ด ์๋ค.
df
์ต๊ทผ ๋ฐ์ดํฐ 30ํ๋ง ์ฌ์ฉํ๊ฒ ์ต๋๋ค. ๋ค์ด๋ฒ ๊ธ์ต์ ๋ฐ์ดํฐ๊ฐ ๋ด๋ฆผ์ฐจ์์ผ๋ก ๋์ด์ ธ ์์ผ๋ฏ๋ก ์ค๋ฆ์ฐจ์์ผ๋ก ๋ณ๊ฒฝํฉ๋๋ค.
df = df.dropna()
df = df.iloc[0:30]
df = df.sort_values(by='๋ ์ง')
df
์
ํธ๋ฆฌ์จ์ ์ข
๊ฐ๋ฅผ ์๊ฐํํด๋ด
์๋ค. x์ถ ๋ ์ด๋ธ์ ๋ ์ง๊ฐ ๊ฒน์ณ์ ๋ณด๊ธฐ์ด๋ ค์ฐ๋ฏ๋ก 90๋ ํ์ ํ์ฌ ํ์ํ์ต๋๋ค. x์ถ์ ๋ ์ง ๋ฐ์ดํฐ๋ก y์ถ์ ์ข
๊ฐ ๋ฐ์ดํฐ๋ก ์ถ๋ ฅํฉ๋๋ค. co๋ ์ขํ๋ฅผ ์ฒญ๋ก์(cyan
) ์์ผ๋ก, -๋ ๊ฐ ์ขํ๋ฅผ ์ค์ ์ผ๋ก ์ฐ๊ฒฐํด์ ํ์ํฉ๋๋ค.
plt.figure(figsize=(15, 5))
plt.title('Celltrion (close)')
plt.xticks(rotation=45)
plt.plot(df['๋ ์ง'], df['์ข
๊ฐ'], 'co-')
plt.grid(color='gray', linestyle='--')
plt.show()
02. ์บ๋ค์ฐจํธ ์๊ฐํ
์ด๋ฒ ์ค์ต์ ์ด์ ์ค์ต์์ ์ด์ด์ ์งํํ๋ค๊ณ ๊ฐ์ ํฉ๋๋ค.
์บ๋ค ์ฐจํธ์ ๋ํ ๊ธฐ๋ณธ์ ์ธ ์ง์
์บ๋ค ์ฐจํธ๋ฅผ ๊ทธ๋ฆฌ๋ ํจํค์ง๋ ๊ตฌ๋ฒ์ ๊ณผ ์ ๋ฒ์ ์ด ์์ต๋๋ค.
ํจํค์ง๋ช
์ด ๋น์ทํ๋ฐ, ํจํค์ง๋ช
์ค๊ฐ์ ํ์ดํ(-
)์ด๋ ์ธ๋์ค์ฝ์ด(_
)๊ฐ ์์ผ๋ฉด ์์ ํจํค์ง์ด๊ณ , ์ค๊ฐ์ ์๋ฌด ๋ฌธ์๋ ์๋ ๊ฒ์ด ์๋ก์ด ํจํค์ง์
๋๋ค. ๊ตฌ๋ฒ์ , ์๋ก์ด ์ ๋ฒ์ ๋ ๊ฐ์ง ๋ชจ๋๋ฅผ ์๊ฐํ๊ฒ ์ต๋๋ค. ๊ฐ๊ธ์ ์ด๋ฉด ์ ๋ฒ์ ์ฌ์ฉ์ ๊ถํฉ๋๋ค.
# ๊ตฌ๋ฒ์ ์ค์น
!pip install --upgrade mpl_finance
# ์ ๋ฒ์ ์ค์น
!pip install --upgrade mplfinance
๊ตฌ๋ฒ์ ์บ๋ค์ฐจํธ
from mpl_finance import candlestick_ohlc
df = df.sort_values(by='๋ ์ง')
for idx in range(0, len(df)):
# ๋ ์ง์ด์ datetime ํ์ผ๋ก ๋ณํ.
dt = datetime.strptime(df['๋ ์ง'].values[idx], '%Y.%m.%d').date()
# datetime ํ์ float ํ์ผ๋ก ๋ณํ
df['๋ ์ง'].values[idx] = mdates.date2num(dt)
# candlestick_ohlc()์์ ์๊ตฌํ๋ ํ์์ผ๋ก ๋ณ๊ฒฝ
ohlc = df[['๋ ์ง','์๊ฐ','๊ณ ๊ฐ','์ ๊ฐ','์ข
๊ฐ']]
plt.figure(figsize=(9, 6))
ax = plt.subplot(1, 1, 1)
plt.title('Celltrion (mpl_finance candle stick)')
# candlestick_ohlc ํจ์๋ฅผ ์ด์ฉํ์ฌ ์บ๋ค์ฐจํธ๋ฅผ ๊ทธ๋ฆฐ๋ค.
candlestick_ohlc(ax, ohlc.values, width=0.7, colorup='red', colordown='blue')
# x์ถ์ ๋ ์ด๋ธ์ด ์ซ์. %Y-%m-%d ํ์ ๋ฌธ์์ด๋ก ๋ณํํ์ฌ ํ์
ax.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d'))
plt.xticks(rotation=45)
plt.grid(color='gray', linestyle='--')
plt.show()
์บ๋ค ์ฐจํธ๋ฅผ ํตํด ์ฃผ๊ฐ ์ผ์๋ณ๋ก์ ์ฃผ๊ฐ ๋ณ๋ํญ์ ํ์ธํ ์ ์์ต๋๋ค. ์บ๋ค ์ฐจํธ๋ฅผ ์ํด์ ์ฌ์ฉํ๋ candlestick_ohlc()
๋ฅผ ํธ์ถํ ๋๋ ๋๋ฒ์งธ ์ธ์์ OHLC ๋ฐ์ดํฐ๋ฅผ ๋ฃ์ด์ฃผ์ด์ผ ํฉ๋๋ค.