Hello creators ๐
[1-4] ๋ด์ค ๊ธฐ์ฌ ์ ๋ชฉ ๊ฐ์ ธ์ค๊ธฐ [python beautifulsoup request ํ์ฉ crwaling] (Feat. ์คํ๋ฅดํ ์ฝ๋ฉํด๋ฝ_๋ฐ์ดํฐ๋ถ์ ์์ ) ๋ณธ๋ฌธ
[1-4] ๋ด์ค ๊ธฐ์ฌ ์ ๋ชฉ ๊ฐ์ ธ์ค๊ธฐ [python beautifulsoup request ํ์ฉ crwaling] (Feat. ์คํ๋ฅดํ ์ฝ๋ฉํด๋ฝ_๋ฐ์ดํฐ๋ถ์ ์์ )
๋ถ์๋งค๋_HA 2022. 12. 8. 22:361๏ธโฃ 'ํดํน ์๋ ํดํน' ์ ํตํ ๋ธ๋ผ์ฐ์ ๋ฐ ์คํฌ๋ํ์ ์๋ฆฌ ์ดํด
'์ผ์ฑ์ ์' ๊ธฐ์ฌ๋ฅผ '์ผ๋์ฐป์ฐจ' ๋ก ๋ฐ๊ฟ๋ณด๊ธฐ
๋ค์ด๋ฒ ๋ด์ค์์, ์ผ์ฑ์ ์ ๊ฒ์ํ๊ณ (์ด๋ ํ ์น ํ์ด์ง ์์๊ฑด) > ๊ฒ์ฌ > ์ผ์ฑ์ ์๋ฅผ '์ผ๋์ฐป์ฐจ' ๋ก ๋ฐ๊ฟ๋ณด์.
๊ทธ๋ฌ๋ฉด, '์ผ์ฑ์ ์' ๊ธฐ์ฌ๊ฐ ๋์์ผ ํ๋๋ฐ, '์ผ๋์ฐป์ฐจ' ์ ๋ํ ๊ธฐ์ฌ๊ฐ ๋์จ๋ค. ๐คทโ๏ธ
์ ๊ทธ๋ฐ๊ฑฐ์ง?
์ฝ๊ฒ ๋งํ๋ฉด, ์ด๋ฏธ ๋ธ๋ผ์ฐ์ ๊ฐ ๋ค์ด ๋ฐ์์จ '๋ด ๊บผ' ๋ฅผ ๋ฐ๊พผ ๊ฒ ์ด๊ธฐ ๋๋ฌธ.
'๋ด๊บผ?' ๋ญ๊ฐ ๋ด๊ป๋ฐ ?
๋ด๊บผ๋ ์๋ฒ๋ฅผ ํตํด์ '์ด๋ฏธ ๋ฐ์์จ HTML, CSS, Javascript ์ผํ์ ๋ฉ์ด๋ฆฌ' ๋ฅผ ์๋ฏธ.
์ด๋ฏธ ๋ฐ์์๊ณ , ๊ทธ๋์ ๋ด๊บผ๊ธฐ ๋๋ฌธ์, ์๋ฌด๋ฆฌ ๋ฐ๊ฟ๋ ๋ด๊บผ์๋ง ์ํฅ์ ๋ฏธ์น๊ณ ๋ค๋ฅธ์ฌ๋์ด ์ผ์ฑ ์ ์ ๊ฒ์์ ํด๋ ์ํฅ์ด ์์.
์ด๋ฅผ ํตํด ์ ์ ์๋ ์นํ์ด์ง์ ์๋ฆฌ๋?
์ฐ๋ฆฌ๊ฐ ๋ค์ด๋ฒ์์ ๊ฒ์์ ํ๋ฉด ๋ค์๊ณผ ๊ฐ์ ์ผ์ด ๋ฒ์ด์ง๋ค.
1) ๊ฒ์์ด๋ฅผ ๋ฃ๊ณ > enter ๋ฅผ ์น๋ค.
2) ๋ค์ด๋ฒ ์๋ฒ๋ ๊ทธ์ ํด๋นํ๋ HTML(๋ผ๋), CSS(๊พธ๋ฉฐ์ฃผ๋๋), Javascript(๋์) ๋ฅผ ์ค๋ค. ( ์ผํ์ ๋ฉ์ด๋ฆฌ )
3) ๋ธ๋ผ์ฐ์ ๋ ์ด ์ผํ์ ๋ฅผ ๋ฐ์์ '๊ทธ๋ฆฌ๊ธฐ๋ง ํ๋ค.'
4) (์ฌ๊ธฐ์์ ๋ด๊ฐ ํ ๊ฑด) ๋ธ๋ผ์ฐ์ ๊ฐ ๋ฐ์์จ ์ด๋ฏธ ๋ฐ์์จ ์ผํ์ ๋ฅผ ๋๋ ์์ ํ ๊ฒ
5) ๋ธ๋ผ์ฐ์ ๊ฐ ๋ฐ์์จ ์ผํ์ ๋ฅผ ์ ์์๋ด๋ฉด > ํฌ๋กค๋ง์ด ๋๋ค.
2๏ธโฃ ๋ด์ค ํ๋์ '์ ๋ชฉ' ๊ฐ์ ธ์ค๊ธฐ
์ ๋ชฉ์ ๊ฐ์ ธ์จ๋ค๋ ๊ฑด?
์ด๋๋ค์ ๊ฐ์ ธ์๋ณด๊ฒ ๋ค๋ ๋ง!
์ด ์๊ฐ ๋๋ ๋ช๊ฐ์ง ์ง๋ฌธ
1๏ธโฃ [์ค๋ฌด์์] '์ด๊ฑธ ๊ฐ์ ธ์์ผ ํด!' ๋ผ๋ ๊ทธ ์๊ฐ, ๋ญ๊ฐ ๋ ์ฌ๋ผ์ผ ํ ๊น?
2๏ธโฃ [๊ณต๋ถํ ๋] ์ฝ๋ฉ ๊ณต๋ถ๋ฅผ ํ๋ค๋ ๊ฑด '์ด๋๊น์ง ํด์ผ ํ๋ค๊ณ ํ ์ ์์๊น?' (์ด๋๊น์ง ์ ๋ฆฌํด์ผ ํ๋๊ฑธ๊น? ์ด๋๊น์ง ์๊ธฐํด์ผ ํ ๊น, ์ด๋๊น์ง ๊ตฌ๊ธ๋ง์ ํด์ผํ๋ ๊ฑธ๊น?)
์ด์ ๋ํ ๋ ์ค์ค๋ก์ (๋ถํ์คํ) ๋๋ต (๊ทธ๋ฆฌ๊ณ ๋ช๊ฐ์ ๊ฐ์ )
Q. 1๏ธโฃ '[์ค๋ฌด์์] '์ด๊ฑธ ๊ฐ์ ธ์์ผ ํด!' ๋ผ๋ ๊ทธ ์๊ฐ, ๋ญ๊ฐ ๋ ์ฌ๋ผ์ผ ํ ๊น?'
๊ฐ์ฅ ๋ฒ ์คํธ๋, ๋ด๊ฐ ์ธ์ธ ์ ์์ด์, ๋ฐ๋ก ์ธ ์ ์๋๊ฑฐ?
๊ฐ์ฅ ๋ฒ ์คํธ๋, ๋ด๊ฐ ๋น์ทํ ๋ฌธ์ ๋ฅผ ํ์ด๋ณธ๊ฑฐ?
๊ฐ์ฅ ๋ฒ ์คํธ๋, ๊ตฌ๊ธ๋ง์ ํด์ ๋ฐ๋ก ๋์จ๊ฑฐ?
๊ฐ์ฅ ๋ฒ ์คํธ๋, ๊ต์ฌ์์ ๋์จ๊ฑฐ?
์์ง, ์ ๋ชจ๋ฅด๊ฒ ๋ค.
ํ์คํ๊ฑด, '์, ํ ์ ์๋ค.' ๋ผ๋ ์์ ๊ฐ์ด ๋๋ ์ํ์ธ ๊ฒ ๊ฐ๋ค.
๋ ์ด์ด์ง๋ ์ง๋ฌธ.
'์ด๋จ ๋, ์์ ๊ฐ์ด ๋ค๊น?'
๋ง์ด ํด๋ด์ผ ์ ๊ฒ ๊ฐ๋ค.
๋ค๋ง, ํ์คํ๊ฑด
์ฌ์ด ๋ง๋ก '์ฝ์ ์ ์๋ ์ํ' ๋ผ๋ฉด, ์ง๊ธ ๋จ๊ณ์์๋ ๋์ด๊ฐ๋ ๋๋ค๊ณ ์๊ฐํจ.
๊ทธ๋ฌ๋ฉด, ์ด๋ฐ ๊ฐ์ค์ ์ธ์๋ณด์
1๏ธโฃ ์ฒ์ ๋ณด๋ ๋ฌธ์ ๊ฐ ์์
2๏ธโฃ '์ฝ์ ์ ์๋ ์ํ' ์ '์ ํํ ์ฝ๋'๋ก ํ์ต์ ํ์
3๏ธโฃ '์ฝ์ ์ ์๋ ์ํ' ์ '์ ํํ ์ฝ๋' ๋ก ๋ค์ ๊ทธ ๋ฌธ์ ๋ฅผ ๋ด.
4๏ธโฃ ๊ทธ๋ฌ๋ฉด, ์ฝ๋๋ฅผ ๋ณด๋ฉด์, ์ฃผ์ด์ง (๊ด๋ จ๋) ๋ฌธ์ ๋ฅผ ํ ์ ์์ง ์์๊น?
5๏ธโฃ ๊ทธ๊ฒ '์์ ๊ฐ' ์ด ๋์ง ์์๊น?
6๏ธโฃ ๊ทธ๋ ๋ค๋ฉด, '์ด๋ค ๋ฌธ์ ๋ณ' ๋ก '์ ํํ ์ฝ๋' ์ ๊ทธ๊ฑธ '์ฝ์ ์ ์๋ ์ํ' ๊ฐ ๋ ์ ์๋๋ก ์ค๋นํ์! ( ์ด๊ฒ, 'Q2[๊ณต๋ถํ ๋] ์ฝ๋ฉ ๊ณต๋ถ๋ฅผ ํ๋ค๋ ๊ฑด '์ด๋๊น์ง ํด์ผ ํ๋ค๊ณ ํ ์ ์์๊น?'' ์ ๋ํ ๋ต์ด ๋์์)
๊ทผ๋ฐ, ์ด๋ฐ ๋ฌธ์ ๊ฐ ์๊ฒจ '์ด์ ํ๋ฃจ์ ์ ๋ง์ ๊ฒ๋ค์ ๋ฐ๋ผํด๋ณด๊ฒ ๋ ํ ๋ฐ, ์ธ์ ํ๊ธฐ ๋ ธํธ๋ฅผ ์ฐพ์๋ณด๊ณ ์์ง?'
- ๋ ธ์ ๊ฒ์์ ํด๋ด๋ ํฌ๊ฒ ์ ๊ฒ์๋์ง ์์.
์, ๊ทธ๋ฌ๋ฉด,
1๏ธโฃ '์ด๋ค ๋ฌธ์ ๋ณ' ๋ก '์ ํํ ์ฝ๋' ์ ๊ทธ๊ฑธ '์ฝ์ ์ ์๋ ์ํ' ๊ฐ ๊ธฐ๋ก๋์ด ์๋ '์ฝํ ์ธ ' ๋ฅผ ๋ง๋ ๋ค.
2๏ธโฃ ๊ฒ์๊ธฐ๋ฅ์ 'google' ์ ๊ฒ์๊ธฐ๋ฅ์ ์จ์, ๋ด๊ฐ ๋ง๋ ์ฝํ ์ธ ์์์ ์ฐพ๋๋ค.
3๏ธโฃ ๊ตฌ๊ธ๋ง ํ ๋๋ 'site:https://hello-5200.tistory.com/ ์ธ๋ฆฌ์ผ ๋ ๋ฒจ๋์์ธ'
site:https://hello-5200.tistory.com/ ์ธ๋ฆฌ์ผ ๋ ๋ฒจ๋์์ธ
์ด๋ ๊ฒ ๊ฒ์ํ๋ค. ( ๋ด๋ถ ๊ฒ์ ๊ธฐ๋ฅ์ธ site ๋ฅผ ํ์ฉํ๋ค.)
์ด๋ ๊ฒ ํ๋ฉด,
- ๋ด๊ฐ ํ์๋ ๋ฌธ์ ๋ผ๊ณ ๋๊ปด์ง๋ ๊ฑด > ์ด๊ณณ์์ ์ฐพ์์ ์ด์ ํด๊ฒฐํด ๋๊ฐ๋ฉด ๋๋ค.
- ๊ทธ๊ฒ ์๋๋ฉด, Top ~ down ๋ฐฉ์์ผ๋ก ํด์ ๊ฒ์ํ์.
python(์ธ์ด) > beutifulsoup(๋ผ์ด๋ธ๋ฌ๋ฆฌ) > select_one(ํจ์, task ๋ฑ)
๋๋๋, ์ ๋ฆฌํ๋ฉด ๐
- ๋ญ๊ฐ๋ฅผ ํ์ตํ ๋,
1๏ธโฃ '์ฝ์ ์ ์์ ์ ๋' ์ ์์ค์ผ๋ก '์ ํํ ์ฝ๋' ์ '์ฝํ ์ธ (๊ธ, ์ค๋ช )' ๊ฐ ์์ผ๋ฉด, ํธ๊ณ ๋์ค์. (๋ค์ ๋น์ทํ ๋ฌธ์ ๊ฐ ๋์ค๋ฉด, ๋ด ๋ธ๋ก๊ทธ or ๋ค๋ฅธ ์ฌ์ดํธ ๊ตฌ๊ธ๋งํด์ ํ์ด๋๊ฐ๋ฉด ๋๋ค.)
- ๊ธ๋ก ์ ๋ฆฌํ ๋
โ (๋ด๊ฐ ์ฐ์ตํ ๋ฌธ์ ๊ฐ 1์ฒ๊ฐ ์ฏค ๋๋ค๊ณ ๊ฐ์ ํ๋ฉด, ํ๊ธฐ ๋ ธํธ๋ฅผ ์ผ์ผ์ด ์ฐพ๋๊ฑด ๋ถ๊ฐ๋ฅํ๋ค๊ณ ๋ณธ๋ค.)
1๏ธโฃ 1์ด ์์ ์๊ฐํด ๋ผ ์ ์๋ hierarchy ๋ฅผ ์ ๋ชฉ์ ์ต๋ํ ๋ง์ด ๋ด์๋ธ๋ค. (๊ฒ์์ด ๋๋๋ก) (Top - down ๋ฐฉ์ / ์์์ ์๋๋ก ๋ด๋ ค๊ฐ๋ ๋ฐฉ์์ผ๋ก ์ด๋ค.)
2๏ธโฃ '์๋ฆฌ๊น๋ฆฌ ํ๋ ๋ถ๋ถ(ํค์๋) ex) a.text, a['href'] select, select_one ํจ์๊ฐ ํท๊ฐ๋ ธ์', '๊ด๋ จ ๊ฐ๋ ex) parsing, crawling, scraping' ๊น์ง ๋ชจ๋ ์ด๋ค.
- ํ์์ ์ผ๋ก ์์ด์ผ ํ๋ ๊ฒ๋ค ์ ๋ฆฌ โญโญโญ
1๏ธโฃ ๋ฌธ์ ์ํฉ
2๏ธโฃ ์ฝ๊ฒ ๋ง๋ก ์ฝ์ด๋ผ ์ ์์ ์ ๋์ ์ค๋ช
3๏ธโฃ ์๋ฆฌ๊น๋ฆฌ ํ๋ ๋ถ๋ถ(ํค์๋)
4๏ธโฃ ๊ด๋ จ๊ฐ๋ (์ ์ฌ์ด, ๋์์ด)
๋ค์ ๊ทธ๋์, ์ด๋ป๊ฒ ํ๋ฉด 'ํ๊ฐ์ ๋ด์ค ๊ธฐ์ฌ' ๋ฅผ ๊ฐ์ ธ์ฌ ์ ์๋๋ฐ?
# ๋ ๋ฒ์งธ (๋ด ์ฝ๋)
import requests
from bs4 import BeautifulSoup
headers = {'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36'}
# ์ด๋ค ๊ธฐ๋ฅ?
data = requests.get('https://search.naver.com/search.naver?where=news&ie=utf8&sm=nws_hty&query=์ผ์ฑ์ ์',headers=headers)
# ํด๋น url ์ ์์ฒญ > '์ํ ์ฝ๋์ HTML ๋ด์ฉ์ ์๋ต' ๋ฐ์(get) (https://library.gabia.com/contents/9239/)
# request ๋ enter ๋ฅผ ์ณ์ ์ผํ์ ๋ฅผ ๋ฐ์์ค๋ ๊ธฐ๋ฅ
soup = BeautifulSoup(data.text, 'html.parser')
# ์๋ต๋ฐ์ HTML ๋ด์ฉ์ BeautifulSoup ํด๋์ค์ ๊ฐ์ฒด ํํ๋ก ์์ฑ/๋ฐํํฉ๋๋ค. BeautifulSoup ๊ฐ์ฒด๋ฅผ ํตํด HTML ์ฝ๋๋ฅผ ํ์ฑํ๊ธฐ ์ํ ์ฌ๋ฌ ๊ฐ์ง ๊ธฐ๋ฅ์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
# beutifulsoup ์ '์์์ฃผ๋ ์ ๋ค'
a = soup.select_one('#sp_nws6 > div.news_wrap.api_ani_send > div > a')
# BeautifulSoup ๊ฐ ์ ๊ณตํ๋ ๊ธฐ๋ฅ ์ค CSS ์
๋ ํฐ๋ฅผ ์ด์ฉํ์ฌ ์ํ๋ ์ ๋ณด๋ฅผ ์ฐพ์ ์ ์์.
# copy selector ๋ฅผ ๋ฃ๋ ๊ณณ, ๋ฌธ์์ด๋ก ๋ฃ์ด์คโญโญโญโญโญ
# โselect_one ์ด๋ผ๋ ํจ์๋ ์ด๋ป๊ฒ ๊ธฐ์ตํ์ง?
# ๋ด๊ฐ ํ๋ฒ ํ๊ฑฐ๋ ๐ ๊ธฐ์ต์ด ์ ์๋ ์ ์์ผ๋, ๋ช
ํํ๊ฒ ํ์
# ์๊ฐ์ ์ด๋ป๊ฒ ์ค์ผ ์ ์์๊น? > ์์ผ๋ก ์ ๋ง์ task ๋ฅผ ๋ง๋๊ฒ ๋ ํ
๋ฐ... ๋ค์ ๋
ธํธ๋ฅผ ์ผ์ผ์ด ์ฐพ๋๊ฑด... ์ผ์...
# ๋ด๊ฐ ์ ๋ฆฌํ ๊ฑฐ์ ๊ตญํํด์, ๊ตฌ๊ธ๋ง ๊ฒ์์ ์ด์ฉํ ์ ์์๊น โญโญโญ
# ํน์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ฃผ์๋ฅผ ์ฐพ๊ณ , site ๋ฅผ ์ง์ ํ๊ณ ๊ตฌ๊ธ๋ง โญโญโญ ๐๐๐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ํฐ ์์ฉ์ด ์๋ค ์ผ์....
# ์ํผ, ๊ทธ๋ฌ๋ฉด, ๋ด๊ฐ ๊ฒ์ํ ์ ์๊ฒ ๋ง๋ค์ด์ผ ๊ฒ ๋ค. ์ผ์... โญโญโญโญโญ ok
# ๋ง์ฝ ๋ด๊ฐ ํด๋ณธ๊ฒ๋ ์๋๋ผ๋ฉด, ์ด๋ป๊ฒ ๊ฒ์ํด์ผ ํ ๊นโโโ
# ๋ญ ์ต๋ํ ์๊ณ ์๋ ๊ฐ๋
์ ๋์ํด์ ๊ฒ์ํด์ผ ๊ฒ ์ง.
print(a)
print(a.text)
print(a['title'])
(์ข ์งค๋ ค์ ๋์ค๋, colab ์ฐธ๊ณ ํ์)
3๏ธโฃ '์ฌ๋ฌ๊ฐ์ ๋ด์ค' ๊ธฐ์ฌ ์ ๋ชฉ์ ๊ฐ์ ธ์ค๊ธฐ
์ด๊ฒ๋ ๋น์ทํด
์ง๊ธ ๊ธฐ์ต ๋๋ ๊ฑด, '์์ ํด๋๋ก, ๋ญํ
์ด๋ก ๊ฐ์ ธ์จ๋ค.' 'li ํ๋ ํ๋์ ์ ๊ทผ'
import requests
from bs4 import BeautifulSoup
headers = {'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36'}
data = requests.get('https://search.naver.com/search.naver?where=news&ie=utf8&sm=nws_hty&query=์ผ์ฑ์ ์',headers=headers)
soup = BeautifulSoup(data.text, 'html.parser')
lis = soup.select('#main_pack > section > div > div.group_news > ul > li ') # ์ง๊ธ์ ์ด๊ฑธ ๋ค ์ดํดํ ์ ์์ด โญโญโญโญโญโญโญ / ๊ฐ๋ฒผ์ด ๋ง๋ก, ์ด๋ฐ๊ฑฐ๊ตฌ๋ ํ๊ณ , ๋์ด๊ฐ์ผ ํด /
#select ํจ์๋ฅผ ์ฌ์ฉ โญโญโญโญโญ
#li ๋ฅผ ์ถ๊ฐ ํ๋ค. โญโญโญโญโญ li ๋ก ํ๋ฒ ๋ ๋ค์ด๊ฐ๋ผ
a = lis[0].select_one('a.news_tit') #li ๋ค ์ค ์ ์ฒซ ๋ฒ์งธ ๊ธฐ์ฌ ๊ฐ์ ธ์ค๊ธฐ #๐๐๐๐๐ ์ฌ๊ธฐ๊ฐ ์ ๋งค
print(a)
a.text
a['href']
# print(lis[0].text)
# print(lis[0]['data-url'])
4๏ธโฃ ๋ฐ๋ณต๋ฌธ์ ์ฌ์ฉํด์ ๊ฐ์ ธ์๋ณด๊ธฐ
import requests
from bs4 import BeautifulSoup
headers = {'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36'}
data = requests.get('https://search.naver.com/search.naver?where=news&ie=utf8&sm=nws_hty&query=์ผ์ฑ์ ์',headers=headers)
soup = BeautifulSoup(data.text, 'html.parser')
lis = soup.select('#main_pack > section > div > div.group_news > ul > li') #li ๋ฅผ ์ถ๊ฐ ํ๋ค. โญโญโญโญโญ li ๋ก ํ๋ฒ ๋ ๋ค์ด๊ฐ๋ผ
for a in lis:
news = a.select_one('a.news_tit')
print(news.text)
print(news['href'])
# print(lis[0].text)
# print(lis[0]['data-url'])
5๏ธโฃ 'ํจ์' ์ฌ์ฉํด์ ๊ฐ์ ธ์ค๊ธฐ
def get_news_1208 (keywords):
headers = {'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36'}
data = requests.get(f'https://search.naver.com/search.naver?where=news&ie=utf8&sm=nws_hty&query={keywords}',headers=headers)
soup = BeautifulSoup(data.text, 'html.parser')
lis = soup.select('#main_pack > section > div > div.group_news > ul > li') #li ๋ฅผ ์ถ๊ฐ ํ๋ค. โญโญโญโญโญ li ๋ก ํ๋ฒ ๋ ๋ค์ด๊ฐ๋ผ
for a in lis:
news = a.select_one('a.news_tit')
print(news.text)
print(news['href'])
# print(lis[0].text)
# print(lis[0]['data-url'])
๐ ์์ ์ถ์ฒ
์คํ๋ฅดํ ์ฝ๋ฉํด๋ฝ_๋ฐ์ดํฐ๋ถ์ ์ฐธ๊ณ
https://spartacodingclub.kr/nb