root@hfairy:~$

[웹크롤링] 네이버 스마트스토어 리뷰 크롤링 본문

공부/빅데이터 분석

[웹크롤링] 네이버 스마트스토어 리뷰 크롤링

hfairy 2025. 7. 10. 01:58

 

https://ryd-gmswjr.tistory.com/11

 

[MySQL] 데이터베이스 구축 및 테이블 생성 _ 1

MySQL을 기반으로 실습 진행하였으며 버전은 8.1.0이다.(mysql --version) 데이터베이스 생성CREATE DATABASE IF NOT EXISTS cosmetic_db; 'CREATE DATABASE'를 이용해 'cosmetic_db'라는 데이터베이스를 생성한다.이때 중복

ryd-gmswjr.tistory.com

데이터베이스와 테이블 구축 방법은 위 게시물에 자세하게 작성해 놓았다.

 

 

오늘 코드를 통해 데이터를 삽입할 테이블과 컬럼 정보는 위와 같다.

각 컬럼의 목적은 아래와 같다.

 

comment_num(primary key): 고유번호

product_name: 제품명

comment_text: 리뷰 내용

comment_date: 리뷰 작성 일자

crawling_date: 크롤링한 날짜 및 시간

site_name: 크롤링한 사이트 이름(쿠팡, 네이버쇼핑 등)

url: 크롤링한 사이트 url


MySQL 연결 코드

MySQL에 연동할 코드는 다른 코드에서도 쓰기 편하도록 별도의 파일을 생성하여 import하였다.

파일명은 'mysql_info'
아래 코드에서 "****"로 처리한 password에는 실제 password 넣으면 된다.

import mysql.connector
import subprocess
import re

# MySQL 서버 연결 정보
host = '127.0.0.1'
database = 'cosmetic_db'
user = 'root'
password = '****'

# MySQL 서버에 연결
conn = mysql.connector.connect(host=host, database=database, user=user, password=password)

# 커서 생성
cursor = conn.cursor()

def kill_chrome():
    # KILL, TASKKILL / 프로세스를 종료하는 명령을 의미
    subprocess.call("TASKKILL /f /IM CHROME.EXE")
    subprocess.call("TASKKILL /f /IM CHROMEDRIVER.EXE")


def remove_tag(_input_data):
    p = re.compile('@[a-zA-Z0-9_]+')
    data = p.search(_input_data)
    if data is not None:
        tag_data = p.findall(_input_data)
        output_data = _input_data
        for tag in tag_data:
            output_data = output_data.replace(tag, '')
        return output_data.strip()
    else:
        return _input_data
    #print(output_data)

 

 

최종코드

url에는 후기를 크롤링할 제품 페이지의 url을 넣으면 된다.

product_name도 직접 제품명을 작성한다.

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.keys import Keys
import time
import random
from mysql_info import *
from selenium.webdriver.common.action_chains import ActionChains

random_delay = random.uniform(2, 9)

site_name = "네이버스토어"
driver = webdriver.Chrome()
url = "https://smartstore.naver.com/..."

driver.get(url)
time.sleep(random_delay)

product_name =driver.find_element(By.CLASS_NAME, '_22kNQuEXmb').text.strip()

action = ActionChains(driver)

time.sleep(random_delay)

# 스크롤
for c in range(0,6):
    driver.find_element(By.TAG_NAME,'body').send_keys(Keys.PAGE_DOWN)
    time.sleep(1) 


# 유니크 인덱스 추가 후 수정한 쿼리
query = "INSERT IGNORE INTO derma_comment_tb (product_name, comment_text, comment_date, site_name, url) VALUES (%s, %s, %s, %s, %s)"

review_list= []
page_index = 1

try:
    review_button = driver.find_element(By.XPATH, "//a[@data-name='REVIEW']")
    ActionChains(driver).move_to_element(review_button).click().perform()
except Exception as e:
    print(f"리뷰 버튼을 찾거나 클릭하는 데 실패했습니다: {e}")

time.sleep(random_delay)

# 페이지를 아래로 스크롤하여 최신순 버튼이 보이도록 함
for _ in range(2):
    driver.find_element(By.TAG_NAME, 'body').send_keys(Keys.PAGE_DOWN)
    time.sleep(1)

# 최신순 버튼 클릭
try:
    lately_button = driver.find_element(By.XPATH, "//a[@data-shp-contents-id='최신순']")
    ActionChains(driver).move_to_element(lately_button).click().perform()
except Exception as e:
    print(f"최신순 버튼을 찾거나 클릭하는 데 실패했습니다: {e}")

time.sleep(random_delay)

while True: 
    try:
        review_elements = driver.find_elements(By.CLASS_NAME, '_9oeeh3ukt7')
        for element in review_elements:
            # 리뷰 날짜
            try:
                print(f"\n{page_index}페이지...\n")
                comment_date = element.find_element(By.XPATH, ".//span[contains(text(), '.')]").text.strip()
                print(comment_date)
            except:
                comment_date = ''

            # 리뷰 본문 (하단의 span 중 마지막 것)
            try:
                comment_text = element.find_elements(By.CLASS_NAME, '_2L3vDiadT9')[-1].text.strip()
                print(comment_text)
            except:
                comment_text = ''
        
            review_list.append((product_name, comment_text[:1000],comment_date, site_name, url))

        for review in review_list:
            try:
                cursor.execute(query, review)
            except mysql.connector.errors.IntegrityError:
                print("중복값 제외")
        
        conn.commit()

        next_page = str(page_index + 1)

        if int(next_page) % 10 == 1:
            driver.find_elements(By.CLASS_NAME, "fAUKm1ewwo")[-1].click()
        else:
            page_elements = driver.find_elements(By.CLASS_NAME, "UWN4IvaQza")
            for page_element in page_elements:
                if page_element.text == next_page:
                    page_element.click()
                    time.sleep(random_delay)
                    break
        time.sleep(random_delay)
        page_index += 1

    except Exception as e:
        print("에러 발생 또는 마지막 페이지:", e)
        break

 

쿠팡과 비교해서 블락이 안 걸려서 다행이었다... 쿠팡은 너무 쉽게 차단 당해서 다음날까지 시도도 못하고..

vpn이나 프록시를 사용해야 하나 했는데 너무 복잡해서 일단은 되는 것만이라도 하는걸로