- StockScraper ์ธ๋ถ๋ด์ฉ (๊ธ์ ๋ชฉ : ์น ํฌ๋กค๋ง์ ์ด์ฉํ ๋ฐ์ดํฐ ๋ถ์)
- Kim์ ๊ฐ๋ฐ ํ๋ก์ ํธ ๋ชจ์ (๊นํํ ๋ ํฌ์งํ ๋ฆฌ)
- ๋งํฌ๋์ธ ํ๋กํ (Chang-Seong Kim)
- ๊ฐ๋ฐ ํ๊ฒฝ : Google Colab
- ๊ฐ๋ฐ ๋ชฉ์ : Python์ ์ด์ฉํ ์น ํฌ๋กค๋ง ๊ฒฝํ ๋ฐ Colab ํ์ฉ ๊ฒธํ ์ต๋
- ๊ฐ๋ฐ ๋ด์ฉ : ๋ค์ด๋ฒ ์ฆ๊ถ ์ฌ์ดํธ๋ฅผ ์ด์ฉํ ์ผ์ฑ์ ์ ์ฃผ์ ์ ๋ณด ์์ง
- ๊ฐ๋ฐ ์ญ๋ : Colab ํ์ฉ, Python์ BeautifulSoup, Pandas, Requests ํ์ฉ, ์น ํฌ๋กค๋ง ์ดํด
- ์์ธ ๋ด์ฉ : ์น ํฌ๋กค๋ง์ ์ด์ฉํ ๋ฐ์ดํฐ ๋ถ์ (๋ธ๋ก๊ทธ ์นดํ ๊ณ ๋ฆฌ)
- ๊ฐ๋ฐ์ ํ์ํ๋ ๊ธฐ๋ฅ :
![]()
![]()
![]()
![]()
- ์น ํฌ๋กค๋ง ๊ธฐ๋ฅ์ ๊ตฌํํ ์ ์๋ ๊ฐ๋จํ ํ๋ก๊ทธ๋จ์ ์ ์ํ์์ต๋๋ค.
- ์น ํฌ๋กค๋ง์ ์ด์ฉํ์ฌ HTML๋ก ๊ตฌ์ฑ๋ ์น ํ์ด์ง ์ ๋ณด๋ฅผ ์ฝ๊ฒ ๊ฐ์ ธ์ฌ ์ ์์์ต๋๋ค.
- ๋ ๋์๊ฐ๋ฉด ๊ฒ์ ์์ง ํ๋ก๊ทธ๋จ ๊ฐ๋ฐ์ ํ์ฉ๋ ์ ์์ ๊ฒ ๊ฐ์ต๋๋ค.
- ๊ทธ๋ฐ๋ฐ ์น ํฌ๋กค๋ง์ ์๋ง์ ๋ฐ์ดํฐ ๋ถ์ ๋ฐฉ๋ฒ ์ค ๋จ์ง ํ๋์ ๋๊ตฌ์ผ๋ฟ์ด์์ต๋๋ค.
- ๋ฌผ๋ก ์๋ํ ํ๋ก๊ทธ๋จ ๊ฐ๋ฐ๋ ์ค์ํ์ง๋ง ๋ฐ์ดํฐ ์์ง ๊ณํ ๋ฐ ํด์ ๋ฐฉ๋ฒ์ด ๋ ์ค์ํ ๊ฒ ๊ฐ์ต๋๋ค.
- ๋ฐ์ดํฐ ๋ถ์ ๋๋ ๊ฒ์ ์์ง ๊ตฌ์ถ์ ํ ๋ฐฉ๋ฒ์ผ๋ก ์น ํ์ด์ง์ ์๋ ๋ฐ์ดํฐ๋ฅผ ์ถ์ถํ๋ ๊ฒ์ ๋๋ค.
- Pyhton์ ๋ฐ๋ณต๋ฌธ ๋ฐ Requests ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ด์ฉํ๋ฉด ์น ํฌ๋กค๋ง ๊ธฐ๋ฅ์ ๊ตฌํํ ์ ์์ต๋๋ค.
- ๋ธ๋ก๊ทธ ๊ธ์์๋ ์น ํฌ๋กค๋ง ๊ธฐ๋ฅ์ ์ด์ฉํ ์ฃผ์ ์ ๋ณด ๋ฐ์ดํฐ ๋ถ์ ๋ฐฉ๋ฒ์ ์์ฑํ์์ต๋๋ค.
- BeautifulSoup๋ ๋ํ์ ์ธ ์น ํฌ๋กค๋ง ๋ชฉ์ ์ Python ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋๋ค.
- BeautifulSoup๋ HTML ๋๋ XML ๋ฑ์ ์ธ์ด์์ ๋ฐ์ดํฐ๋ฅผ ์ถ์ถํ๋ ๊ธฐ๋ฅ์ ์ ๊ณตํฉ๋๋ค.
- Pandas๋ ๋ฐ์ดํฐ ๊ฐ๊ณต ๋ชฉ์ ์ Python ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋๋ค.
- ๋ฐ์ดํฐ ๋ถ์ ์ ๋ฐ์ดํฐ๋ฅผ DB ํ์์ผ๋ก ๋น ๋ฅด๊ฒ ๋ณํ์ํฌ ์ ์์ต๋๋ค.
- ๋๋ ๋ค์ํ ๋ฐ์ดํฐ์ ์กฐํฉ์ํค๊ฑฐ๋ ๋ฐ์ดํฐ ํํฐ๋ง ์ ์ด์ฉ๋ฉ๋๋ค.
- ๊ทธ๋์ BeautifulSoup๋ก ๋ฐ์ดํฐ๋ฅผ ์ทจ๋ํ ํ Pandas๋ก ๋ณํํ๋ ์์ ์ ํ๊ธฐ๋ ํฉ๋๋ค.
from bs4 import BeautifulSoup # BeautifulSoup ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ์์ต๋๋ค.
import requests # Requests ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ์์ต๋๋ค.
for page in range(1, 6): # ํ์ด์ง ์๋ฅผ ์๋ฏธํ๋ 1๋ถํฐ 5๊น์ง์ ์ซ์์ ๋ํด ๋ฐ๋ณตํ์์ต๋๋ค.
print(str(page))
# ํ์ฌ ํ์ด์ง ๋ฒํธ๋ฅผ ์ถ๋ ฅํ๋๋ก ์ค์ ํ์์ต๋๋ค.
url_005930 = "http://finance.naver.com/item/sise_day.nhn?code=005930" + "&page=" + str(page)
# ๋ค์ด๋ฒ ๊ธ์ต์ ์ผ์ฑ์ ์์ ์ฃผ์ ์ ๋ณด๊ฐ ์๋ ํ์ด์ง์์ ํ์ด์ง ๋ฒํธ(&page=)๋ฅผ str(page) ํ๋ผ๋ฏธํฐ๋ก ์ถ๊ฐํ์์ต๋๋ค.
headers = {"User-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"}
# ์น ์๋ฒ๊ฐ ์น ํฌ๋กค๋ง ์์ฒญ์ ์น ๋ธ๋ผ์ฐ์ ์์ ์จ ๊ฒ์ผ๋ก ์ธ์ํ๊ฒ ํ๊ธฐ ์ํด User-Agent ํค๋ ์ ๋ณด๋ฅผ ์์ฑํ์์ต๋๋ค.
# ์ฐธ๊ณ ๋ก User-Agent ์ ๋ณด๋ 'https://useragentstring.com/'์์ ํ๋ํ ์ ์์ผ๋ฉฐ ์ด๋ ์ฌ์ฉ์์ ์น ํ๊ฒฝ ๋ฑ์ ์ ๋ณด์
๋๋ค.
response = requests.get(url_005930, headers=headers)
# ์ค์ ํ url์ HTTP GET ์์ฒญ์ ๋ณด๋ธ ํ response ๋ณ์์ ํด๋น ์๋ต์ ์ ์ฅํ๊ฒ ์ค์ ํ์์ต๋๋ค.
soup = BeautifulSoup(response.text, "html.parser")
# response์ ์ ์ฅ๋ ์๋ต ์ค HTML ๋ด์ฉ์ ์ฌ์ฉํ์ฌ BeautifulSoup ๊ฐ์ฒด๋ฅผ ์์ฑํ์์ต๋๋ค.
# BeautifulSoup ๊ฐ์ฒด๋ฅผ ์ด์ฉํ์ฌ HTML ๋ด์ฉ์ ํ์ฑ(๋ถ์)ํ ์ ์์ต๋๋ค.
parsing_list = soup.find_all("tr")
# HTML ๋ด์ฉ ์ค 'tr' ํ๊ทธ๊ฐ ํฌํจ๋ ๋ชจ๋ ๋ฌธ์์ด(ํ)์ ์ฐพ์ ๋ฆฌ์คํธ๋ก ๋ฐํ์์ผฐ์ต๋๋ค.
isCheckNone = None
# None ๊ฐ์ ๋ํ ๋น๊ต๋ฅผ ์ํ ๋ณ์๋ฅผ ์ค์ ํ์์ต๋๋ค.
for i in range(1, len(parsing_list)):
# parsing_list ๋ด์ฉ์ ์๋ 'tr' ํ๊ทธ๊ฐ ํฌํจ๋ ํ์ ๋ฐ๋ณตํ์์ต๋๋ค.
if(parsing_list[i].span != isCheckNone):
# ์ ํจํ ๋ฐ์ดํฐ ํ ์ ๋ณด๋ง ์ทจ๋ํ๊ธฐ ์ํด 'span' ํ๊ทธ์ ๋ด์ฉ์ด None์ด ์๋์ง ํ์ธํ์์ต๋๋ค.
print(parsing_list[i].find_all("td", align="center")[0].text,
# ํด๋น 'tr' ํ๊ทธ ๋ด์์ 'td' ํ๊ทธ ์ค align ์์ฑ์ด "center"์ธ ์ฒซ ๋ฒ์งธ ์์([0])์ ํ
์คํธ(๋ ์ง)๋ฅผ ์ถ๋ ฅํฉ๋๋ค.
parsing_list[i].find_all("td", class_="num")[0].text)
# ๊ฐ์ 'tr' ํ๊ทธ ๋ด์์ 'td' ํ๊ทธ ์ค class ์์ฑ์ด "num"์ธ ์ฒซ ๋ฒ์งธ ์์([0])์ ํ
์คํธ(์ฃผ์ ์ข
๊ฐ)๋ฅผ ์ถ๋ ฅํฉ๋๋ค.