240717 Today I Learn
ํฌ๋กค๋ง๊ณผ ์คํฌ๋ํ
ํฌ๋กค๋ง vs. ์คํฌ๋ํ
- ์น ํฌ๋กค๋ง: ์น์์ ์กด์ฌํ๋ ๋ชจ๋ ์น ํ์ด์ง๋ฅผ ๋ฐฉ๋ฌธํ์ฌ ๋ฐ์ดํฐ๋ฅผ ์์งํ๋ ๋ฐฉ๋ฒ. ํฌ๋กค๋ฌ๋ ์ธํฐ๋ท ์์ ๋ชจ๋ ํ์ด์ง๋ฅผ ๋ฐฉ๋ฌธํ๋ฉฐ, ๊ฐ ํ์ด์ง์ ๋งํฌ๋ฅผ ๋ฐ๋ผ๊ฐ๋ฉด์ ์๋์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ์์งํจ.
- ์น ์คํฌ๋ํ: ํน์ ์น ์ฌ์ดํธ๋ ํ์ด์ง์์ ํ์ํ ๋ฐ์ดํฐ๋ฅผ ์๋์ผ๋ก ์ถ์ถํด ๋ด๋ ๊ฒ
์น ํฌ๋กค๋ง | ์คํฌ๋ํ | |
๊ณตํต์ | ์ํ๋ ๋ฐ์ดํฐ๋ฅผ ์์งํ ์ ์๋ค. ๊ธฐ์ ์ ์ผ๋ก ํ์ด์ฌ์ผ๋ก ํจ๊ป ์ฌ์ฉ๋๋ ๊ฒฝ์ฐ๊ฐ ๋ง์. (์น ํฌ๋กค๋ง์ ํตํ ์น์ ๊ทผ → ์คํฌ๋ํ์ ํตํ ํน์ ๋ฐ์ดํฐ ์ถ์ถ) |
|
์ค๋ณต์ ๊ฑฐ | ์ค๋ณต์ ๊ฑฐ ํ์ → ๋์ผํ ์ฝํ ์ธ ๊ฐ ์ฌ๋ฌ ํ์ด์ง์ ์ ๋ก๋ ๋ ๊ฒ์ ์ธ์ํ์ง ๋ชปํจ. |
๋ฐ๋์ ํ์ํ ๊ฒ์ ์๋ → ํน์ ๋ฐ์ดํฐ๋ฅผ ์ถ์ถํ๋ ๊ฒ |
์ฐจ์ด์ | ์น์ฌ์ดํธ์ ๋ํ ์ ๋ณด๋ฅผ ์์ธํํ๊ณ ์ ์ฅํ๋ ๋ฐ ์ฌ์ฉ ๊ฒ์ ์์ง ๋ฐ ๊ธฐํ ์๋ํ ๋๊ตฌ์ ์ํด ์ํ |
๋ถ์ ๋ฐ ๊ธฐํ ๋ชฉ์ ์ ์ํด ์น์ฌ์ดํธ์์ ๋ฐ์ดํฐ๋ฅผ ์ถ์ถ ์ฌ๋/์ด ๋ชฉ์ ์ ์ํด ํน๋ณํ ์ค๊ณ๋ ์๋ํ ๋๊ตฌ์ ์ํด ์ํ |
โ ๏ธ ์ฃผ์์ฌํญ : ํฉ๋ฒ์ธ์ง ํ์ธ ํด๋ณด๊ธฐ
- '๋ก๋ด ๋ฐฐ์ ํ์ค(Robots Exclusion Standard)์ ์ค์ํ๋๊ฐ'์ ๋ํ ํ์ธ์ด ํ์ํ๋ค.
→ ์นํ์ด์ง ์ฃผ์ ๋งจ ๋ค์ '/robots.txt'๋ฅผ ๋ถ์ฌ์ ํ์ธํ๊ธฐ - ์คํฌ๋ํ/ํฌ๋กค๋ง์ ์ํํ๊ธฐ ์ ์ ํด๋น ์น ์ฌ์ดํธ์ robots.txt ํ์ผ์ ๋ฐ๋์ ํ์ธํ๊ณ , ๋ก๋ด ๋ฐฐ์ ํ์ค์ ์ค์ํ๋์ง ํ์ธํ๋ ๊ณผ์ ์ด ํ์ํจ.
์น์ฌ์ดํธ ๊ตฌ์ฑ์์ 3๊ฐ์ง
- HTML (Hyper Text Markup Language) : ์น ์ฌ์ดํธ์ ๋ผ๋
- CSS (Cascading Style Sheets) : ์์๊ฒ ๊พธ๋ฉฐ์ ํํ
- javascript : ๋์ํ๊ฒ ๋ง๋ค์ด ์ค
HTML
๐ MacOS ํฌ๋กฌ ๊ฐ๋ฐ์๋๊ตฌ ๋จ์ถํค(f12)
command(โ) + option (โฅ) +i
๐ก HTML (HyperText Mark-up Language)
๋ฌธ์๋ฅผ ์ค๋ช ํด์ฃผ๋ ์ ๋ณด๋ฅผ ํํ๋ ๋งํฌ์ ์ธ์ด(=ํ๊ทธ๋ก ๋๋ฌ์์ธ ์ธ์ด=<>)
๋ฌธ์์ ๋ด์ฉ ์ด์ธ์ ๋ฌธ์์ ๊ตฌ์กฐ๋ ์์ ๊ฐ์ ๊ฒ์ ํฌํจ
- ๋ฌธ์ ํ์ ์ ์ธ(Doctype): HTML ๋ฌธ์๊ฐ ์ด๋ค ๋ฒ์ ์ HTML์ด๋ XHTML๋ก ์์ฑ๋์๋์ง ์น ๋ธ๋ผ์ฐ์ ์๊ฒ ์๋ ค์ค.
- ๋ฃจํธ ์์(html): ๋ฃจํธ ์์๋ HTML ๋ฌธ์์ ์ต์์ ์์๋ก ๋ชจ๋ ๋ค๋ฅธ HTML ์์๋ค์ ํฌํจํ๋ ๋ถ๋ชจ ์์
- ํค๋(Head): HTML ๋ฌธ์์ ๋ฉํ๋ฐ์ดํฐ์ ์ธ๋ถ ๋ฆฌ์์ค์ ๋ํ ์ ๋ณด๋ฅผ ํฌํจํ๋ ๋ถ๋ถ.
→ ํ๋ฉด์ ์ง์ ์ ์ผ๋ก ๋ณด์ด์ง ์์ง๋ง, ์น ๋ธ๋ผ์ฐ์ ๊ฐ ๋ฌธ์๋ฅผ ์ฒ๋ฆฌํ๊ณ ํ์ํ๋ ๋ฐ ์ค์ํ ์ญํ ์ ํจ. - ๋ณธ๋ฌธ(Body): HTML ๋ฌธ์์ ์ค์ ๋ด์ฉ์ ๋ด๊ณ ์๋ ๋ถ๋ถ
→ ์น ํ์ด์ง๋ฅผ ๊ตฌ์ฑํ๋ ๋ชจ๋ ํ ์คํธ, ์ด๋ฏธ์ง, ๋งํฌ, ํ ์ด๋ธ, ํผ ๋ฑ์ ์ฝํ ์ธ ๊ฐ ํฌํจ- <div> : HTML๋ฌธ์ ๋ด์์ ํ ๊ฐ์ ๊ฐ๋ก ๊ณต๊ฐ(Block)์ ๋ง๋๋ ํ๊ทธ
→ <div class >: ํ๋์ ๊ณต๊ฐ(ํด๋์ค)๋ฅผ ๋ง๋ค๊ฒ ๋ค - <p> : ์ฃผ๋ก ๋ฌธ์ฅ์ ๋ํด์ ์ฌ์ฉํ๋ ํ๊ทธ์ด๋ฉฐ ์ญ์ ํ ๊ฐ์ ๊ฐ๋ก ๊ณต๊ฐ(Block)์ ๋ง๋๋ ํ๊ทธ
- <div> : HTML๋ฌธ์ ๋ด์์ ํ ๊ฐ์ ๊ฐ๋ก ๊ณต๊ฐ(Block)์ ๋ง๋๋ ํ๊ทธ
Beautiful Soup
- HTML ํ๊ทธ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ํฌ๋กค๋ง์ ์งํ
- request ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ํตํด ์นํ์ด์ง๋ฅผ ํธ์ถํ๊ณ , BeautifulSoup ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ํตํด ์น์ ์ ๊ทผ๋ ์ํ์์ ๋ฐ์ดํฐ๋ฅผ ์ถ์ถ
- ์คํฌ๋กค ๋ฐ ํ๋ฉด์ด๋, ๋ฒํผํด๋ฆญ ๋ฑ์ ๋ฐ๋๋ ๋ถ๋ถ์ ํฌ๋กค๋ง์ด ๋ถ๊ฐ๋ฅ → Selenium ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ๋์ฒด
๐ก ํ์ฑ
์น ์์ ์์ฐ์ด, ์ปดํจํฐ ์ธ์ด ๋ฑ์ ์ผ ๋ จ์ ๋ฌธ์์ด๋ค์ ๋ถ์ํ๋ ํ๋ก์ธ์ค
์ค์ต
# ์ฒ์ 1ํ ์ค์น
# pip install beautifulsoup4
# ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋ถ๋ฌ์ค๊ธฐ
import requests
from bs4 import BeautifulSoup as bs
# request ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ํตํ http ํต์ ํธ์ถ
page = requests.get("https://library.gabia.com/")
# beautifulsoup ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ด์ฉํ page์ text ๋ฐ์ดํฐ ํ์ฑ(๋ฌธ์์ด๋ถ์)
soup = bs(page.text, "html.parser")
# select ๋ฌธ๋ฒ์ ์ด์ฉํ์ฌ html ๋ด ํ์ํ ๋ถ๋ถ์ ๋ชจ๋ ์ ํํฉ๋๋ค.
# div.esg-entry-content ์์ a ๋ฅผ ํ๊ณ ๊ทธ ์๋๋ก span ์ ํ๊ณ ๋ด๋ ค๊ฐ์ text ๋ฅผ ๋ถ๋ฌ์ต๋๋ค.
elements = soup.select('div.esg-entry-content a > span')
# for ๊ตฌ๋ฌธ์ ํตํด ๋ฐ๋ณต์ ์ผ๋ก ์ํํด์ค๋๋ค.
for index, element in enumerate(elements, 1):
print("{} ๋ฒ์งธ ๊ฒ์๊ธ์ ์ ๋ชฉ: {}".format(index, element.text))
Selenium
- ์์ ํ ํฌ๋กค๋ง์ ์ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์๋, ์น๊ฐ๋ฐ์๋ค์ด ๋์ ์น์ด ์ ๋๋ก ์๋ํ๋์ง๋ฅผ ํ
์คํธํ๊ธฐ ์ํด์ ๋ง๋ค์ด์ง ๋ชจ๋
→ ๋์ ํฌ๋กค๋ง์ด ๊ฐ๋ฅ - ํฌ๋กฌ ๋ฑ์ ๋ธ๋ผ์ฐ์ ๋ฅผ ์๋์ผ๋ก ์ด์ด์ ์ปจํธ๋กคํ๋ ํ๋ ์์ํฌ
์ค์ต
CGV ์ ์ฌ๋ผ์จ '๋ฒ์ฃ๋์2' ๊ด๋ จ ํ์ ์ ์ ๋ ๋์์ ์ด์ฉํด ํฌ๋กค๋ง & ์คํฌ๋ํ ํด๋ณด์.
๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋ถ๋ฌ์ค๊ธฐ
from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium import webdriver
from selenium.webdriver.chrome.service import Service as ChromeService
from webdriver_manager.chrome import ChromeDriverManager
import time
import pandas as pd
import warnings
warnings.filterwarnings('ignore')
ํจ์
def get_movie_reviews(url, page_num=12):
# WebDriver ์๋น์ค ๊ฐ์ฒด ์ฌ์ฉ
#service = ChromeService(executable_path=ChromeDriverManager().install())
#wd = webdriver.Chrome(service=service)
chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument('--headless')
chrome_options.add_argument('--no-sandbox')
chrome_options.add_argument('--disable-dev-shm-usage')
wd = webdriver.Chrome(options=chrome_options)
wd.get(url)
writer_list = []
review_list = []
date_list = []
like_list = []
for page_no in range(1, page_num+1):
try:
page_ul = wd.find_element(By.ID, 'paging_point')
page_a = page_ul.find_element(By.LINK_TEXT, str(page_no))
page_a.click()
time.sleep(2)
writers = wd.find_elements(By.CLASS_NAME, 'writer-name')
writer_list += [writer.text for writer in writers]
reviews = wd.find_elements(By.CLASS_NAME, 'box-comment')
review_list += [review.text for review in reviews]
dates = wd.find_elements(By.CLASS_NAME, 'day')
date_list += [date.text for date in dates]
likes = wd.find_elements(By.ID, 'idLikeValue')
like_list += [like.text for like in likes]
if page_no % 10 == 0:
next_button = page_ul.find_element(By.CLASS_NAME, "paging-side")
next_button.click()
time.sleep(2)
except NoSuchElementException:
break
movie_review_df = pd.DataFrame({
"Writer": writer_list,
"Review": review_list,
"Date": date_list,
"Like": like_list
})
wd.close()
return movie_review_df
# ์ฌ์ฉ ์์
movie_review_df = get_movie_reviews("http://www.cgv.co.kr/movies/detail-view/?midx=85813", page_num=12)
movie_review_df.to_csv('๋ฒ์ฃ๋์2ํฌ๋กค๋ง.csv', index=False, encoding="utf-8-sig")
'๐ Data Analysis > ๐๏ธ Note' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
๋ฐ์ดํฐ ์์ง ๋ฐฉ๋ฒ ํน๊ฐ #1 API (0) | 2024.07.16 |
---|---|
ํต๊ณํ ๊ธฐ์ด (3) ANOVA, ์ ํํ๊ท๋ถ์ (0) | 2024.05.29 |
ํต๊ณํ ๊ธฐ์ด (2) ํต๊ณ์ ๊ฐ์ค๊ฒ์ (0) | 2024.05.28 |
ํต๊ณํ ๊ธฐ์ด (1) ํ๊ท ์ด๋ ๋ฌด์์ธ๊ฐ? (0) | 2024.05.27 |
๋ฐ์ดํฐ ๋ฆฌํฐ๋ฌ์ (0) | 2024.05.07 |