수달이네 기술 블로그

7.셀레니움을 이용한 크롤링3: 데이터프레임화(야놀자 리뷰 크롤링) 본문

AI공부/머신러닝

7.셀레니움을 이용한 크롤링3: 데이터프레임화(야놀자 리뷰 크롤링)

슬픈 수달이 2025. 12. 1. 22:07
  1. 먼저 필요한 요소를 import한다.
import time
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By 
import pandas as pd
import openpyxl
  1. 리뷰를 담을 리스트를 만들고, 크롬으로 리뷰를 가져온다.
def crawl_yanolja_reviews(name, url, max_scroll=100):
    review_list = []
    driver=webdriver.Chrome()
    driver.get(url)
    time.sleep(3)
  1. 리뷰 확인

리뷰사이트를 확인해보니 여러 리뷰가 있는데, 스크롤을 해야 새로운 리뷰가 추가로 생성되는 것을 알 수 있었다.

  1. 현재 스크롤 높이를 확인하고, 스크롤이 더이상 되지 않을때까지 내려간다.
    last_height = driver.execute_script("return document.body.scrollHeight") 
    #자바스크립트 이용, 현재 스크롤의 높이를 리턴시켜줌
    print(last_height)
    same_count = 0
    scroll_times = 0

    while True:
        scroll_times+= 1
        driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
        #스크롤을 0부터 끝까지 내릴것이다.)
        time.sleep(2)
        new_height = driver.execute_script("return document.body.scrollHeight")

        if new_height == last_height:
            same_count += 1  #만약 스크롤 개수가 같다(3번정도 같으면 종료, 인터넷문제일수도)
        else:
            same_count = 0
            last_height = new_height
        if same_count >= 3:
            print('더 이상 새로운 리뷰가 없습니다.')
            break
        if scroll_times >= max_scroll:
            print('최대 스크롤 횟수 도달, 종료')
            break
  • 현재 스크롤 높이와 나중스크롤 높이가 같으면 끝, 만약 아니라면 스크롤
  1. 리뷰를 파싱한다.
    #/html/body/div[1]/section/div/div[5]/div[1]/div[2]/div/div[3]/div[1]/p
        #/html/body/div[1]/section/div/div[5]/div[2]/div[2]/div/div[3]/div[1]/p
    containers = driver.find_elements(By.XPATH,"/html/body/div[1]/section/div/div[5]/div/div[2]/div/div[3]/div[1]/p")
    print('총 리뷰 개수: ', len(containers))

위와 같이 xpath가 구성되어있음을 확인했다. 따라서 공통되는 부분만 남겨서 모든 element를 찾아올 수 있었다.

그러나, 리뷰내용뿐 아니라 다양한 내용을 얻고 싶었기에,

containers = driver.find_elements(By.XPATH,"/html/body/div[1]/section/div/div[5]/div")
    for c in containers:
        try: 
            review_text = c.text.strip()
        except:
            review_text = ""
        try:
            date_text = c.find_element(By.XPATH,".//div/div/div/div/p").text
            #해당 컨테이너에서 날짜만 출력(패턴만 맞추면 됨.)
        except:
            date_text = ""

        review_list.append({
            "review": review_text,
            "date": date_text
        })

컨테이너에 리뷰박스 부분을 담아준 후

컨테이너에서 리뷰 텍스트에 해당하는 내용과,date에 해당하는 내용을 뽑아준다.

이후 이것을 review_list로 반환해주면된다.

  1. 실행
if __name__ == "__main__": #py파일을 실행했을때 해당 파일이 자기 자신이면 실행
    name = "알로프트 서울 명동"
    url = "<https://nol.yanolja.com/reviews/domestic/10064814>"
    reviews = crawl_yanolja_reviews(name, url)
    df = pd.DataFrame(reviews)
    file_name = f'{name}_reviews.xlsx'
    df.to_excel(file_name, index = False)
    print("엑셀저장완료!!")

메인에서 크롤링을 돌린 후 해당 딕셔너리 리스트를 데이터프레임으로 만들어주면 된다.