ํ์ฌ์์ ํน์ ๊ฐ์ธ ํ๋ก์ ํธ๋ฅผ ์งํํ ๋ ๋ฐ์ดํฐ๋ฅผ ํฌ๋กค๋งํด ์ค๋ ๊ฒฝ์ฐ๊ฐ ์ข ์ข ์์ต๋๋ค. ์ ํ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์จ๋ค๋์ง, ์ต๊ทผ 2๋ ์น์ ๊ฒฝ์ ๋ด์ค ๊ธฐ์ฌ๋ฅผ ๋ชจ์๋ค๋์ง ๋ฑ ์น์ฌ์ดํธ์์ ๋ฐ์ดํฐ๋ฅผ ์ง์ ์์งํ๊ณ ์์ต๋๋ค.
์ง๊ธ๊น์ง๋ ์ฃผ๋ก requests์
bs4
๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ๊ณ , JavaScript ๋น์ค์ด ๋์ ๋์ ์น์ฌ์ดํธ๋ selenium
์ ํตํด ๋ธ๋ผ์ฐ์ ๋ก ํ์ํ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ ์์
์ ํ์ต๋๋ค. ์ฐ์ฐํ๊ฒ requests
๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ ์ํ ์ฌ๋๋ค์ด JavaScript์ง์์ ํ๋ requests-html
์ด๋ผ๋ ํจํค์ง๋ฅผ ๋ง๋ค์๋ค๋ ๊ฒ์ ์๊ฒ ๋์ด์ ์ด์ ํ
์คํธ๋ฅผ ํด๋ณด๋ ๊น์ ํฌ๋กค๋งํ๋ ๋ฐฉ๋ฒ์ ์ ๋ฆฌํ๋ ์๋ฆฌ์ฆ ํ ํฌ์คํธ๋ฅผ ์์ฑํ๊ธฐ๋ก ํ์ต๋๋ค.
์ด๋ฒ ํฌ์คํธ์์๋ requests์ bs4์ ํ์ฉํ ์ ์ ์นํ์ด์ง๋ฅผ ํฌ๋กค๋งํด ๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค.
requests ๋ผ์ด๋ธ๋ฌ๋ฆฌ (+ ์ธํฐ๋ท์ ์๋ ์๋ฆฌ)
requests๋ python์ ์ํ http ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋๋ค. ๋จ์ํ๊ฒ ์ค๋ช ํ์๋ฉด ์ธํฐ๋ท์์ ๋ฐ์ดํฐ (HTML, CSS, Javascript)๋ฅผ ์ฐ๋ฆฌ๊ฐ ์ผ๋ฐ์ ์ผ๋ก ์ฌ์ฉํ๋ ๋ธ๋ผ์ฐ์ ์ธ ํฌ๋กฌ, ํ์ด์ดํญ์ค, ์์ง๊ฐ ์๋ python์ผ๋ก ์ง์ ๊ฐ์ ธ์ฌ ์ ์๋๋ก ํฉ๋๋ค. ์๋์ ๊ทธ๋ฆผ์ ๋ณด์๋ฉด ๋ ์ฝ๊ฒ ์ดํด๋ฅผ ํ์ค ์ ์์ต๋๋ค.
ํฌ๋กฌ์ ๊ฒฝ์ฐ ctrl + shift + i ๋ฒํผ์ ๋๋ฅด๋ฉด ๊ฐ๋ฐ์ ๋๊ตฌ ํ๋ฉด์ผ๋ก ๋์ด๊ฐ ํ์ฌ ๋ณด๊ณ ์๋ ์นํ์ด์ง์ HTML, CSS, JavaScript๋ฅผ ํ์ธํด๋ณด์ค ์ ์์ต๋๋ค. ์ฐ๋ฆฌ๊ฐ requests ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ๋ค๋ฉด ์๋ ์ฐ์ธก ๊ทธ๋ฆผ์ HTML์ด๋ผ๊ณ ๋นจ๊ฐ๊ฒ ํ๊ธฐ๋ ๋ถ๋ถ์ Python์ผ๋ก ๊ฐ์ ธ์ฌ ์ ์์ต๋๋ค. ์ด ๋ถ๋ถ์์ ์ฐ๋ฆฌ๊ฐ ํ์ํ ์ ๋ณด๋ง HTML ํ๊ทธ๋ฅผ ์ด์ฉํด์ ๊ฐ์ ธ์ค๋ฉด ๋ฉ๋๋ค. ์ด๋ ์ฃผ์ํด์ผ ํ ์ ์ requests ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ์ ์ ์นํ์ด์ง ํฌ๋กค๋ง์ ์ ํฉํฉ๋๋ค.
(์ ์ ์น์ฌ์ดํธ vs ๋์ ์น์ฌ์ดํธ์ ๋ํ ์ค๋ช ์ ๋งํฌ ์ฐธ๊ณ ํ์ธ์)
๊ทธ๋ผ ์ด์ requests๋ฅผ ์ฌ์ฉํ์ฌ ํฌ๋กค๋ง์ ํด๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค. ๋ง๊ฐ์ ๋ ์ํผ ํํ์ด์ง์์ ์์ 100๊ฐ์ ๋ ์ํผ ๋ชฉ๋ก๋ฅผ ๊ฐ์ ธ์๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค.
ํฌ๋กค๋ง ํ
1. ๊ฐ๋ฐ์ ๋๊ตฌ, ์์ค ๊ฒ์ฌ ์์ฑ์ ์ ์ด์ฉํ๊ธฐ
ํฌ๋กฌ์ ctrl+shift+i ๋ฅผ ์ฌ์ฉํ๋ฉด ๊ฐ๋ฐ์ ๋๊ตฌ ์ฝ์์ ๋์ธ ์ ์์ต๋๋ค. ์ดํ ctrl + shift + c๋ฅผ ๋๋ฅธ ๋ค๋ฉด, ์ปค์๊ฐ ์ฌ๋ ค์ง ๊ณณ์ HTML ์ฝ๋ ๋ถ๋ถ์ ํ์ธํ ์ ์์ต๋๋ค. ํน์ ๋จ์ํ๊ฒ ๋ง์ฐ์ค ์ฐํด๋ฆญ์ ํ์ฌ ๊ฒ์ฌ๋ฅผ ๋๋ฅด๋ ๋ฐฉ๋ฒ๋ ์์ต๋๋ค.
2. ์์งํ๊ณ ์ถ์ ์ ๋ณด๊ฐ ์ด๋ค ๊ตฌ์กฐ๋ก ๋์ด์๋์ง ํ์ ํ๊ธฐ
์๋์ ์ฌ์ง์ ๋ณด์๋ฉด, ๊ฐ๊ฐ์ ๋ ์ํผ๋ <li class='common_sp_list_li'> ๋ผ๋ ํ๊ทธ์ ๋ชฉ๋ก์ผ๋ก ์ ๋ณด๊ฐ ๋์ด๋์ด ์๋ค๋ ๊ฒ์ ์ ์ ์์ต๋๋ค. ๊ทธ๋ฆฌ๊ณ ๋ ์ํผ ํ๊ทธ๋ค์ <ul class='common_sp_list_ul ea4'>์ด๋ผ๋ ์์ ํ๊ทธ๊ฐ ์๊ณ ๊ทธ ์์๋ <div class='rcp_m_list2'>๋ผ๋ ์์ ํ๊ทธ ์๋์ ์๋ค๋ ๊ฒ์ ์ ์ ์์ต๋๋ค. ์ฐ๋ฆฌ๊ฐ ์ํ๋ ์ ๋ณด ์ธ์ ๋ค๋ฅธ ์ ๋ณด๋ค์ด <li class='common_sp_list_li'> ๋ผ๋ ํ๊ทธ๋ฅผ ๊ฐ์ง๊ณ ์๋ค๋ฉด, ์์ ํ๊ทธ๋ฅผ ํ์ฉํ์ฌ ๋ ์ํผ๊ฐ ์์นํ HTML์ ํ์ฑ ํด์ผ ํฉ๋๋ค.
3. ์์ ์๋ ์๋ ์ ๋ณด๋ ์์ธ์ฒ๋ฆฌํ๊ธฐ
๋ค๋ฅธ ๋ ์ํผ ํญ๋ชฉ๊ณผ๋ ๋ค๋ฅด๊ฒ 16์ ๋ ์ํผ๋ ๋ฆฌ๋ทฐ ์ ๋ณด๊ฐ ์์ต๋๋ค. ๋ง์ฝ ์์ธ์ฒ๋ฆฌ ์์ด ๋ฐ๋ณต๋ฌธ์ ์งฐ๋ค๋ฉด ์๋ฌ๊ฐ ์๊ธธ ํ๋ฅ ์ด ๋์ต๋๋ค. ๋ฐ๋ผ์ ํฌ๋กค๋ง์ ํ์ค ๋๋ ์์ ์๋ ์๋ ์ ๋ณด๋ฅผ ์์ธ์ฒ๋ฆฌํ ์ ์๋ ๋ฐฉ๋ฒ์ ์๊ฐํด ๋์ ์ผ ๋ฐ์ดํฐ ์์ง ๋ ํํฌ๋ฃจ ์๊ฐ์ ๋ญ๋นํ๋ ๊ฒ์ ์๋ฐฉํ ์ ์์ต๋๋ค.
์์ค์ฝ๋
์๋ ์ฝ๋๋ฅผ ๋ณต๋ถํ์๋ฉด ๋ ์ํผ ๋ญํน ํ๋ฉด์ ๋ด๊ธด 100๊ฐ์ ๋ ์ํผ์ ๋ํ ์ด๋ฆ, ๋งํฌ, ์กฐํ์, ๋ฆฌ๋ทฐ ๋ฑ์ ์ ๋ณด๊ฐ ์ ๋ฆฌ๋ ํ์ผ์ ๋ค์ด๋ก๋ํ ์ ์์ต๋๋ค. ์กฐ๋ฆฌ ๊ณผ์ ๊ณผ ์ฌ๋ฃ์ ๊ฐ์ ์ธ๋ถ ์ ๋ณด๊ฐ ํ์ํ๋ค๋ฉด, ๋งํฌ ๋ณ๋ก ์ ์์ ํ ๋ค ์ ์ฌํ ๋ฐฉ๋ฒ์ผ๋ก HTML ํ๊ทธ๋ฅผ ์ด์ฉํด์ ๋ฐ์ดํฐ๋ฅผ ์์งํ์๋ฉด ๋ฉ๋๋ค.
(๋ง์ฝ ๊ฐ URL ๋ณ๋ก ๋ ์ํผ ์ ๋ณด๋ฅผ ๊ฐ์ ธ์ค๋ ๋ฐ ์ด๋ ค์์ด ์์ผ์๋ค๋ฉด, ๋๊ธ๋ก ๋ฌธ์ ์ฃผ์ธ์~)
import requests
import pandas as pd
from bs4 import BeautifulSoup
# URL ์
๋ ฅ (ํฌ๋กค๋ง ๋์ ์น์ฌ์ดํธ)
url = 'https://www.10000recipe.com/ranking/home_new.html'
# HTTPS ํธ์ถ
req = requests.get(url)
# HTML ์ ์ฅ
html = req.text
# HTML ํ์ฑ
soup = BeautifulSoup(html, 'html.parser')
# ๋ ์ํผ ๋ชฉ๋ก์ด ๋ด๊ธด HTML ํ๊ทธ
recipes = soup.find_all('li', {"class":"common_sp_list_li"})
# ๋ ์ํผ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ ๋น ๋ฆฌ์คํธ
recipe_data = []
# ๊ฐ ๋ ์ํผ์ ํ๊ทธ ๋ด ํ์ํ ์ ๋ณด๋ฅผ HTML ํ๊ทธ๋ก ์ฐพ์์ ๋ณ์๋ก ์ ์ฅ
for recipe in recipes:
recipe_rank = recipe.find('p',{'class':'ranking_num'}).text
recipe_name = recipe.find('div',{'class':'common_sp_caption_tit'}).text
recipe_auth = recipe.find('div',{'class':'common_sp_caption_rv_name'}).text.strip()
recipe_link = 'https://www.10000recipe.com' + recipe.find('div',{'class':'common_sp_thumb'}).find('a')['href']
try: #๋ ์ํผ ๋ฆฌ๋ทฐ๊ฐ ์๋ ๊ฒฝ์ฐ๊ฐ ์๊ธฐ ๋๋ฌธ์ ์๋ฌ ๋ฐฉ์ง๋ฅผ ์ํด try, except๋ก ๋จ์ ์์ธ์ฒ๋ฆฌ
recipe_review_num = recipe.find('span',{'class':'common_sp_caption_rv_ea'}).text.replace('(','').replace(')','')
except:
recipe_review_num = '0'
recipe_view_cnt = recipe.find('span',{'class':'common_sp_caption_buyer'}).text.replace('์กฐํ์ ','')
# ๋น ๋ฆฌ์คํธ์ ๋ฐ์ดํฐ ์ ์ฅ
recipe_data.append([recipe_rank, recipe_name, recipe_auth, recipe_link, recipe_review_num, recipe_view_cnt])
# Pandas DataFrame์ผ๋ก ์ ์ฅ
df = pd.DataFrame(recipe_data, columns=['๋ญํน','๋ ์ํผ์ ๋ชฉ','์์ฑ์','๋ ์ํผ๋งํฌ','๋ฆฌ๋ทฐ์','์กฐํ์'])
# ๋ญํน ๋ฐ์ดํฐ csv ํ์ผ๋ก ์ ์ฅ (์์
๋ก ๋์ค์ ๋ถ๋ฌ์ค๊ธฐ ๊ฐ๋ฅ)
df.to_csv('๋ง๊ฐ์๋ ์ํผ_Top_100.csv', encoding='cp949')
# ์ฒซ 5๊ฐ์ ํ๋ง ๊ฐ์ ธ์ค๊ธฐ
df.head()
'๐ป ITยท๊ธฐ์ ยทํต๊ณ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[์นํฌ๋กค๋ง 2ํ] selenium webdriver๋ฅผ ํ์ฉํ ์ํ ๋ฆฌ์คํธ ํฌ๋กค๋ง (0) | 2023.01.29 |
---|---|
๋ฉํฐํ๋ก์ธ์ฑ (Multiprocessing) w/ Python (0) | 2023.01.26 |
[API] DALLยทE 2 Python์ผ๋ก ์ฌ์ฉํด๋ณด๊ธฐ (3) | 2023.01.25 |
Python์ผ๋ก ๋ฉ์ผ ๋ณด๋ด๊ธฐ [@gmail] (3) | 2023.01.21 |
[API] ChatGPT Python์ผ๋ก ์ฌ์ฉํด๋ณด๊ธฐ - Part.1 (์์ ) (8) | 2023.01.17 |
๋๊ธ