Notice
Recent Posts
Recent Comments
Link
«   2026/08   »
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31
Archives
Today
Total
관리 메뉴

파진기와 함께 코딩을

[MD스터디] 올리브영으로 배워보는 크롤링 2 본문

데이터📊

[MD스터디] 올리브영으로 배워보는 크롤링 2

pajingi 2025. 9. 27. 19:07

오늘은 어제에 이어서 리뷰 크롤링을 해보겠습니다

 

일단 전편에서 만들었던 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