๋ชฉ์ฐจ
ํ์ด์ฌ์ ๋ค์ํ ํ์ฉ ๊ธฐ๋ฅ
ํ์ด์ฌ์ ์นํฌ๋กค๋ง, ์๋ํ, ๋ฅ๋ฌ๋, ์นํ์ด์ง ์ ์, ๋ฐ์ดํฐ๋ถ์, GUI ํ๋ก๊ทธ๋๋ฐ, ๊ฒ์๊ฐ๋ฐ, ์ด๋ฏธ์ง ์ฒ๋ฆฌ ๋ฑ ๋ค์ํ ๊ธฐ๋ฅ์ ์ ๊ณตํ์ฌ ์ฃผ๋ชฉ์ ๋ฐ๊ณ ์๋ค. ๊ฐ๊ฐ์ ํ์ฉ ์์๋ฅผ ์ดํด๋ณด์. ๊ทธ๋ฆฌ๊ณ ์น ํฌ๋กค๋ง BeautifulSoup ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋ํด ์์๋ณด์.
๊ธฐ๋ฅ | ๋ผ์ด๋ธ๋ฌ๋ฆฌ/ ํ๋ ์์ํฌ |
์น ํฌ๋กค๋ง | BeautifulSoup |
์๋ํ | Selenium |
๋ฅ๋ฌ๋ | TensorFlow |
์นํ์ด์ง ์ ์ | Django, Flask |
๋ฐ์ดํฐ ๋ถ์ | Pands, Matplotlib |
GUI ํ๋ก๊ทธ๋๋ฐ | Tkinter, PyQt |
๊ฒ์ ๊ฐ๋ฐ | Pygame |
์ด๋ฏธ์ง ์ฒ๋ฆฌ | OpenCV |
๐ ์นํฌ๋กค๋ง์ด๋?
- ์ธํฐ๋ท ์์ ์นํ์ด์ง์์ ์ ๋ณด๋ฅผ ์์งํ๋ ์์ ์ผ๋ก
- ์นํ์ด์ง์ HTML ์ฝ๋๋ฅผ ๊ฐ์ ธ์์ ํ์ํ ๋ฐ์ดํฐ๋ฅผ ์ถ์ถํ๋ ๊ธฐ์ ์ด๋ค.
๐ง ํ์ํ ๋๊ตฌ
- 'requests' : ์นํ์ด์ง์์ HTML ์ ๋ณด๋ฅผ ๊ฐ์ ธ์ค๋ ๋ชจ๋
- 'BeautifulSoup' : ๊ฐ์ ธ์จ HTML์ ๋ถ์ํ์ฌ ํ์ํ ์ ๋ณด๋ฅผ ์ถ์ถํ๋ ๋ชจ๋
โ ํฌ๋กค๋ง, ํ์ฑ, ์คํฌ๋ํ์ ์ฐจ์ด๋ ๋ฌด์์ผ๊น?
- ํฌ๋กค๋ง์ ์น ์ธ๋ฑ์ฑ์ ์ํด ์๋์์ด๋์น(WWW)์ ์ฒด๊ณ์ ์ผ๋ก ํ์ํด ๋๊ฐ๋ ์์
- ํ์ฑ์ ์น์์ ๋ฌธ์์ด์ ๋ถ์ํ์ฌ ์๋ฏธ ์๋ ์ ๋ณด๋ก ๋ณํํ๋ ๊ณผ์
- ์คํฌ๋ํ์ ๋ค์ํ ์น ์ฌ์ดํธ๋ก๋ถํฐ ๋ฐ์ดํฐ๋ฅผ ์ถ์ถํ๋ ๊ธฐ์ ์ ์๋ฏธ
์นํฌ๋กค๋ง BeautifulSoup ๋ผ์ด๋ธ๋ฌ๋ฆฌ ํ์ฉ
๐ฆ BeautifulSoup ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ค์น
์นํฌ๋กค๋ง ์ ํ์ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ค์นํ๋ค. beautifulsoup4, requests
- cmd ์ฐฝ์ ์คํํ๋ค (Window + R)
- ํ์ด์ฌ ์ ๋ชจ๋ ์คํํ๋ค. (โ ํ์ด์ฌ ์ค์น์ ํ๊ฒฝ๋ณ์ ํจ์ค๋ฅผ ๋ฐ๋์ ์ฒดํฌํด์ผ ์์ ์ฌ์ฉํ ์ ์๋ค.)
- ํ์ด์ฌ ์ ์์ Beautifulsoup ๋ชจ๋ ํ์ธ
- ์ค์น๊ฐ ์๋ ๊ฒฝ์ฐ ctrl + z๋ก ์ ํ๋ฉด์ ์ข
๋ฃํ๊ณ , ์๋ install ๋ช
๋ น ์คํ
๐ ediya.html ํ์ผ ์นํฌ๋กค๋งํ๊ธฐ - ๋ก์ปฌ
- ์ด๋์ผ ์ฌ์ดํธ๋ฅผ ํฌ๋กค๋งํ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ ediya.html ํ์ผ์ ์์ ๊ณต๊ฐ์ ๋ฐฐ์นํ๋ค.
- File > NewFile > "์นํฌ๋กค๋ง.py" ๋ก ์ ์ฅ
๐ ์นํฌ๋กค๋ง.py ์ฝ๋ ์์ฑ
from bs4 import BeautifulSoup
homepage = open('ediya.html', 'r', encoding = 'utf-8')
doc = homepage.read()
homepage.close()
#print(doc)
soup = BeautifulSoup(doc,'html.parser')
result = soup.find_all('p', class_='each-menu')
#print(result)
for data in result:
#print(data)
print(data.text)
- `from bs4 import BeautifulSoup` : ํด๋น ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ HTML ๋ฐ XML ๋ฌธ์๋ฅผ ํ์ฑํ๊ณ ๋ถ์ํ๋๋ฐ ์ฌ์ฉ
- `homepage = open('')` : html ํ์ผ์ ์ฝ๊ธฐ๋ชจ๋('r')๋ก ์ด๊ณ , ํ์ผ์ ์ฝ์๋ UTF-8 ์ธ์ฝ๋ฉ์ ์ฌ์ฉํ๋ค. ์ด๋ ํ์ผ์ด ํ์ฌ ๋๋ ํ ๋ฆฌ์ ์์ด์ผ ํ๋ค. ํ์ผ์ ์ด๊ณ ํด๋น ๋ด์ฉ์ ๋ณ์ hompage์ ์ ์ฅํ๋ค.
- `doc = homepage.read()` : homepage์์ HTMLํ์ผ์ ๋ด์ฉ์ ์ฝ์ด์ ๋ณ์ doc์ ์ ์ฅํ๋ค. ์ด ๋ณ์์๋ HTMLํ์ผ์ ๋ชจ๋ ๋ด์ฉ์ด ๋ฌธ์์ด ํํ๋ก ์ ์ฅ๋๋ค.
- `homepage.close()` : โ ํ์ผ์ ์ด์์ผ๋ฉด ํญ์ ํ์ผ์ ๋ซ์์ผํ๋ค.!!
- doc์ ๋ด๊ธด HTML ํ์ผ์ ์ด์ด์ ํด๋น ๋ด์ฉ์ ๋ฌธ์์ด๋ก ์ฝ์ด์จ ํ์, BeautifulSoup ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ์ฌ ํ์ฑ๋ ๊ฒฐ๊ณผ๋ฅผ ํตํด ์ํ๋ ์ ๋ณด๋ฅผ ์ถ์ถํ ์ ์๋ค.
- `soup = BeautifulSoup(doc, 'html.parser') ` : BeautifulSoup ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ค. ์ด๋, doc์ ์ ์ฅ๋ HTML๋ฌธ์๋ฅผ ๋ฌธ์์ด๋ก ํ์ฑํ๊ณ BeautifulSoup๊ฐ์ฒด๋ก ๋ณํํ๋ค. HTML ๋ฌธ์๋ฅผ ํ์ฑํ ๋๋ 'html.parser'๋ฅผ ์ฌ์ฉํ๋ค.
- `result = soup.find_all('p', class_='each-menu')` : BeautifulSoup ๊ฐ์ฒด soup ์์ find_all ๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ฌ HTML๋ฌธ์์์ <p> ํ๊ทธ ์ค ํด๋์ค ์์ฑ์ด each-menu ์ธ ๋ชจ๋ ์์๋ฅผ ์ฐพ๋๋ค. ๊ฒฐ๊ณผ๋ ๋ฆฌ์คํธ ํํ๋ก ๋ฐํ๋๊ณ , ์ด ๋ฆฌ์คํธ์๋ ํด๋น ์กฐ๊ฑด์ ๋ง์กฑํ๋ ๋ชจ๋ ์์๊ฐ ํฌํจ๋๋ค.
- `for data in result` : result ๋ฆฌ์คํธ์ ์ ์ฅ๋ ๊ฐ ์์๋ค์ ์ํํ๋ฉด์ ๋ฐ๋ณต์ ์ผ๋ก ์ฒ๋ฆฌํ๋ค. ์ฌ๊ธฐ์ data๋ result ๋ฆฌ์คํธ์ ์๋ ๊ฐ๊ฐ์ ์์๋ฅผ ์๋ฏธํ๋ค.
- `print(data.text)` : BeautifulSoup ๊ฐ์ฒด์ธ data์ ํ ์คํธ ๋ด์ฉ๋ง ์ถ๋ ฅํ๋ค. ํ๊ทธ๊น์ง ๋์ค๋๊ฒ์ ์ํ์ง ์์๋๋ .text์์ฑ์ ์ฌ์ฉํ์ฌ ํด๋น ์์์ ํ ์คํธ ๋ด์ฉ๋ง ๋ฐํํ๋๋ก ํ๋ค.
๐ฅ ๋น๊ทผ๋ง์ผ ์ฌ์ดํธ ์นํฌ๋กค๋งํ๊ธฐ - Colab
์ด๋ฒ์๋ ์ค์ ๋น๊ทผ๋ง์ผ ์ฌ์ดํธ๋ฅผ Colab์์ ํฌ๋กค๋งํด๋ณด์.
๐ ์ฝ๋ ์ค๋ช
- `requests` ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ์ฌ url ์ฃผ์์ ์๋ ์นํ์ด์ง์ ๋ด์ฉ์ ๊ฐ์ ธ์จ๋ค. `get` ํจ์๋ฅผ ์ฌ์ฉํ์ฌ ํด๋น ์นํ์ด์ง์ GET์์ฒญ์ ๋ณด๋ด๊ณ , ์๋ฒ๋ก๋ถํฐ ๋ฐ์ ์๋ต์ webpage ๋ณ์์ ์ ์ฅํ๋ค.
- ํ์ฑ๋ html ๋ฌธ์์์ ํน์ ํ๊ทธ๋ ํด๋์ค๋ฅผ ์ฐพ์๋ด๊ณ ์ ๋ณด๋ฅผ ์ถ์ถํ ์์๋ค. ์ฌ๊ธฐ์ title, title.string, h1.string์ ์ฌ์ฉํ์ฌ ๊ฐ๊ฐ ์์์์ ์ ๋ณด๋ฅผ ์ถ์ถํ๋ค.
- `soup.ul.children` : ์ ์ฌ์ฉํ์ฌ ํ์ฑ๋ HTML๋ฌธ์์์ <ul> ํ๊ทธ์ ์์ ์์์ ๋ฌธ์์ด์ ์ถ๋ ฅํ๋ค.
๐ ์ ๊ท ํํ์
- `import re` : ํด๋น ๋ชจ๋์ ์ ๊ท ํํ์์ ์ฌ์ฉํ์ฌ ๋ฌธ์์ด์ ์ฒ๋ฆฌํ๋ค.
- `re.compile("[ou]l")` : ์ ๊ท ํํ์์ ์ฌ์ฉํ์ฌ <ul>, <ol> ํ๊ทธ๋ฅผ ๋ชจ๋ ์ฐพ์ ์ถ๋ ฅ
- `re.compile("h[1-9]")` : <h1> ๋ถํฐ <h9> ๊น์ง์ ๋ชจ๋ ์ ๋ชฉ ํ๊ทธ๋ฅผ ์ฐพ์ ์ถ๋ ฅ
๐ Select() ํจ์๋ฅผ ์ฌ์ฉํ์ฌ CSS ์ ํ์๋ก ์ ๋ณด ๊ฐ์ ธ์ค๊ธฐ
- BeautifulSoup ์ select() ํจ์๋ฅผ ํ์ฉํ์ฌ HTML ํด๋์ค๊ฐ card-region-name ์ธ ์์๋ค์ ์ ํํ๋ค. ๊ทธ๋ฐ ๋ค์ ๊ฐ ์์์์ .get_text()๋ฉ์๋๋ฅผ ํธ์ถํ์ฌ ํ ์คํธ๋ฅผ ์ถ์ถํ๊ณ ์ถ๋ ฅํ๋ค.
๐ญ ์นํฌ๋กค๋ง : ๋ฐ์ดํฐ ์ถ์ถ๊ณผ ๊ฐ๋ฐ์ ๋๊ตฌ ํ์ฉ
ํฌ๋กค๋ง์ ์น ํ์ด์ง์์ ๋ฐ์ดํฐ๋ฅผ ์ถ์ถํ๋ ์์ ์ด๋ค. ๋น๊ทผ๋ง์ผ๊ณผ ๊ฐ์ ์ฌ์ดํธ์์ ์ํ๋ ์ ๋ณด๋ฅผ ๊ฐ์ ธ์ค๋ ค๋ฉด ํฌ๋กค๋ง์ด ํ์ํ๋ค. ์ด์ฒ๋ผ ์ํ๋ ๋ฐ์ดํฐ์ API๋ฅผ ์ ๊ณตํ์ง ์๋๋ค๋ฉด ์น ํฌ๋กค๋ง์ ํตํด ๋ฐ์ดํฐ๋ฅผ ์์งํ๋ฉด ๋๋ค.
ํฌ๋กค๋ง์ ํตํด ์์ธ์ ์๋ ์ธ๊ธฐ์๋ ์ํ์ ๋ณด๊ณ ์ถ๋ค๋ฉด ํด๋น ์นํ์ด์ง์ HTML์ ๊ฐ์ ธ์์ BeautifulSoup์ ๊ฐ์ ๋๊ตฌ๋ฅผ ์ฌ์ฉํ์ฌ ์ํ๋ ์ ๋ณด๋ฅผ ์ถ์ถํ ์ ์๋ค.
ํฌ๋กค๋ง์ ์งํํ ๋๋ ๊ฐ๋ฐ์ ๋๊ตฌ(F12)๋ฅผ ํ์ฉํ๋ ๊ฒ์ด ์ ์ฉํ๋ค. ๋ธ๋ผ์ฐ์ ์ ๊ฐ๋ฐ์ ๋๊ตฌ๋ฅผ ์ด๊ณ ์์๋ฅผ ๊ฒ์ํ๋ฉด ํ๊ทธ์ ๊ตฌ์กฐ์ ํด๋์ค๋ฅผ ํ์ธํ ์ ์๋ค. ์ด๋ฅผ ํตํด ์ด๋ค ํ๊ทธ๋ฅผ ์ฐพ์๋ด์ผ ํ๋์ง ํ์ ํ ์ ์๋ค.
์์ฝํ์๋ฉด, ํฌ๋กค๋ง์ ์น ํ์ด์ง์์ ์ํ๋ ๋ฐ์ดํฐ๋ฅผ ์ถ์ถํ๋ ๋ฐฉ๋ฒ์ผ๋ก ๊ฐ๋ฐ์๋๊ตฌ๋ฅผ ์ด์ฉํด์ ์นํ์ด์ง์ ๊ตฌ์กฐ๋ฅผ ํ์ ํ๊ณ BeautifulSoup์ ๊ฐ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ์ฌ ๋ฐ์ดํฐ๋ฅผ ์ถ์ถํ ์ ์๋ค.