파진기와 함께 코딩을
[MD스터디] 올리브영으로 배워보는 크롤링 2 본문
오늘은 어제에 이어서 리뷰 크롤링을 해보겠습니다
일단 전편에서 만들었던 data 폴더 아래에 products.csv 파일을 만들어주세요
안은
product_link,category
https://www.oliveyoung.co.kr/store/goods/getGoodsDetail.do?goodsNo=A000000223388,위생용품
이렇게 채워주시고
첫번째줄인 헤더는 열 이름입니다!
그니깐 두번째줄부터 실제 데이터값으로 프로덕트 링크는 https://www.oliveyoung.co.kr/store/goods/getGoodsDetail.do?goodsNo=A000000223388 이고, 카테고리는 위생용품인겨
그리구 코드 파일 만들어주시오
코드내용은 아래랑 같고 파일명은 자유로,,
# filename: [25_리뷰크롤링]올영.py
import time
import csv
import os
from bs4 import BeautifulSoup
from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from itertools import zip_longest
from selenium import webdriver
from selenium.webdriver.common.by import By
def load_data():
data = []
# 위생용품 리스트 파일로 변경
with open("./data/products.csv", newline='', encoding='utf-8') as fr:
reader = csv.DictReader(fr)
for row in reader:
data.append(row)
return data
def write_data(data):
# 위생용품 리뷰 결과 파일로 변경
file_path = "./data/hygiene_reviews_score.csv"
file_exists = os.path.isfile(file_path)
with open(file_path, "a", newline='', encoding='utf-8') as fw:
writer = csv.DictWriter(
fw,
fieldnames=["page", "product_name", "star", "title", "review", "skin_type"]
)
if not file_exists:
writer.writeheader()
for row in data:
writer.writerow(row)
def crawl_parse_review_html_write_data(url):
driver = webdriver.Chrome()
try:
driver.get(url)
# 기존 로직 그대로 (리뷰 탭 클릭)
WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.XPATH, '//*[@id="reviewInfo"]'))
).click()
time.sleep(3)
for page_num in range(1, 200):
parse_review_text_list = []
html = driver.page_source
soup = BeautifulSoup(html, 'lxml')
product_name_tag = soup.find("p", class_="prd_name")
product_name = product_name_tag.text if product_name_tag else []
user_clrfix_tags = soup.find_all("div", class_="user clrfix")
review_tags = soup.find_all("div", class_="txt_inner")
title_tags = soup.find_all("div", class_="poll_sample")
star_tags = soup.find_all("div", class_="score_area")
combined_list = list(
zip_longest(title_tags, review_tags, user_clrfix_tags, star_tags, fillvalue=None)
)
for title_tag, review_tag, user_clrfix_tag, star_tag in combined_list:
review_text = review_tag.text if review_tag else None
title_text = [tag.text.strip() for tag in title_tag.find_all("span")[1::2]] if title_tag else None
span_text = [span.text.strip() for span in user_clrfix_tag.find_all("span")[1:]] if user_clrfix_tag else None
# 원본 스타일 유지
star_text = [star.text.strip() for star in star_tag.find_all("span")][0] if star_tag else None
review_data = {
"page": page_num,
"product_name": product_name,
"star": star_text,
"title": title_text,
"review": review_text,
"skin_type": span_text
}
parse_review_text_list.append(review_data)
write_data(parse_review_text_list)
# 다음 페이지 이동 (원본 그대로)
try:
next_button = driver.find_element(By.XPATH, f"//a[@data-page-no='{page_num + 1}']")
next_button.click()
time.sleep(3)
except NoSuchElementException:
print(f"Page {page_num} is the last page.\n")
break
finally:
driver.quit()
return parse_review_text_list
if __name__ == '__main__':
data = load_data()
parse_review_list = []
for i, review in enumerate(data):
url = review["product_link"]
try:
parse_review = crawl_parse_review_html_write_data(url)
except:
continue
print(f"{i}번 제품 끝")
이 코드를 실행하면?? 자동으로 올영 사이트가 텨지고 리뷰 페이지가 쭉쭉 넘어가면서 크롤링이 됩니다 ㅎㅎ
다른 분야를 하고 싶다면?? csv상안의 카테고리를 바꿔주면 됩니다.
당연히 올리브영 내의 한 상품 상세만 해당이 되고 호환이 됩니다~
다른사이트는 DOM 구조가 달라 호환이 안되어요~

그러면 이렇게 잘 정리가 된걸 볼수 있습니다~
재밌어가지궁 추후엔 다른 사이트나 분야도 해보고 싶당
'데이터📊' 카테고리의 다른 글
| [MD스터디] 올리브영으로 배워보는 크롤링 (15) | 2025.09.26 |
|---|