저번 시간에 웹 크롤링에 대해서 배웠습니다. 이번 시간에는 조금 더 복잡한 작업을 수행하는 방법에 대해 배웠습니다. input에 텍스트 입력하기, 스크롤하기 등을 통해 구글 플레이스토어에서 리뷰 데이터를 가져와 보겠습니다.
웹 크롤링으로 데이터 가져오기
웹 크롤링이란?웹 크롤링(Web Crawling)은 인터넷 상에서 웹 페이지들을 자동으로 탐색하여 정보를 수집하는 프로세스를 말합니다. 웹 크롤러는 일종의 소프트웨어로, 웹 페이지에 접근하여 그 안
dararium.tistory.com
크롬 드라이버를 통해 크롬 브라우저 열기
가장 먼저, 웹드라이버를 통해 크롬 브라우저를 열고, 구글 플레이스토어 페이지로 이동해줍니다.
from selenium import webdriver
from selenium.webdriver.common.by import By
from webdriver_manager.chrome import ChromeDriverManager
ChromeDriverManager().install()
driver = webdriver.Chrome()
url = 'https://play.google.com/store/games?hl=ko'
driver.get(url)
send_keys()
함수를 이용해서 검색어 입력하기
이번에는 배달의 민족의 리뷰 데이터를 가져와 보도록 하겠습니다. 그러기 위해서 가장 먼저 검색창에 배달의 민족을 입력해야 합니다. xpath를 이용해 검색 버튼을 클릭해줍니다.
driver.find_element(By.XPATH, '//*[@id="kO001e"]/header/nav/div/div[1]/button').click()
selenium에서는 send_keys()
함수로 input에 텍스트를 입력할 수 있습니다. 인자로 입력할 텍스트를 입력해줍니다. 그 후, 검색을 위해 엔터 키를 쳐야 합니다. 이때는 selenium의 Keys
모듈을 이용해서 엔터키 이벤트를 브라우저에 전달할 수 있습니다.
from selenium.webdriver.common.keys import Keys
driver.find_element(By.CLASS_NAME, 'HWAcU').send_keys('배달의 민족')
driver.find_element(By.CLASS_NAME, 'HWAcU').send_keys(Keys.ENTER)
검색이 완료 됐다면 배달의 민족 앱을 클릭해서 상세 페이지로 이동해줍니다. 이 부분은 간단한 부분이기 때문에 설명은 생략하도록 하겠습니다.
execute_script()
함수를 이용해서 스크롤하기
한 번에 불러와야 하는 데이터가 많으면 로딩 속도가 느려집니다. 그리고 사용자는 로딩 속도가 느린 경우 기다리지 않고 사이트를 떠납니다. 그래서 초기 로딩 속도를 빠르게 하는 일은 매우 중요합니다. 로딩 속도를 빠르게 하기 위한 방법 중 하나로써 '페이지네이션'이라는 기법이 사용됩니다.
페이지네이션을 사용하면 사용자가 원할 때(다음 페이지로 이동한다든지, 스크롤한다든지)만 데이터를 필요한 만큼만 가져오기 때문에 로딩 속도를 줄일 수 있습니다.
구글 플레이스토어에도 이러한 페이지네이션 기법이 사용되었습니다. 리뷰는 기본적으로 20개만 노출되고, 사용자가 스크롤을 하면 다음 20개의 데이터를 불러오는 식입니다.
그렇다면 만약 크롤링으로 200개의 데이터를 가져오고 싶다면 어떻게 해야 할까요? 웹 드라이버를 통해 스크롤을 한 다음 데이터 추출을 진행하면 됩니다. 스크롤을 하려면 자바스크립트를 사용해야 하는데, 웹 드라이버에서 자바스크립트 코드를 실행하려면 execute_script()
함수를 사용합니다.
# 모달 지정
modal = driver.find_element(By.CLASS_NAME, 'fysCi')
modal.click()
import time
for i in range(9):
code = 'arguments[0].scrollTo(0, arguments[0].scrollHeight)'
driver.execute_script(code, modal)
time.sleep(2)
모달 내에서 스크롤을 할 것이기 때문에 모달을 찾아서 포커스를 맞춰줍니다. 그리고 execute_script()
함수의 두 번째 인자로 전달합니다.
첫 번째 인자는 실행할 자바스크립트 코드를 넣어주어야 하는데요. 위의 코드에서 code
에 나오는 arguments[0]
은 modal
을 의미합니다. scrollTo(x, y)
는 지정한 좌표 값으로 스크롤을 이동해주는 함수입니다.
여기서 scrollHeight
라는 개념이 등장하는데요. scrollHeight
는 보이지 않는 부분까지 포함한 콘텐츠의 크기를 의미합니다. 구글 플레이스토어의 리뷰 모달을 예로 들어보면, 아까 20개의 리뷰가 처음에 불러와 진다고 말씀 드렸는데요, 리뷰 20개의 높이의 합이 scrollHeight
가 되는 것입니다. 즉, arguments[0].scrollTo(0, arguments[0].scrollHeight)
은 스크롤을 끝까지 내려달라는 의미입니다.
스크롤을 끝까지 내리면 어떻게 될까요? 다음의 20개의 데이터가 불러와집니다. 그러면 리뷰 데이터가 처음의 20개와 새로 불러와진 20개를 합쳐 총 40개가 됩니다. 200개의 리뷰를 불러오기 위해서는 총 9번(기본 노출 20개 + 20 x 9)을 스크롤하면 되기 때문에 for문으로 스크롤하는 코드를 반복해주겠습니다.
그런 다음, 리뷰 데이터들을 순회하면서 필요한 데이터들을 리스트에 저장합니다.
container = driver.find_elements(By.CLASS_NAME, 'RHo1pe')
review_list = []
for item in container:
name = item.find_element(By.CLASS_NAME, 'X5PpBb').text
date = item.find_element(By.CLASS_NAME, 'bp9Aid').text
rate = item.find_element(By.CLASS_NAME, 'iXRFPc').get_attribute('aria-label')[10]
content = item.find_element(By.CLASS_NAME, 'h3YV2d').text
try:
help_count = item.find_element(By.CLASS_NAME, 'AJTPZc').text.split()[1][:-2]
except:
help_count = '0'
review_list.append({
'name': name,
'date': date,
'rate': rate,
'content': content,
'help_count': help_count
})
아무도 리뷰가 도움이 되었다고 체크하지 않으면 '사용자 n명이 이 리뷰가 유용하다고 평가함' 부분이 노출되지 않기 때문에 오류가 발생할 수 있습니다. 따라서 예외처리로, 해당 엘리먼트가 없을 경우에는 0으로 설정합니다.
마지막으로, 데이터를 저장합니다.
import pandas as pd
df = pd.DataFrame(review_list)
df.to_csv('google_playstore_review.csv', encoding='utf-8-sig')
'데이터 분석 > 강의 노트' 카테고리의 다른 글
matplotlib를 이용해서 데이터 시각화하기 (0) | 2024.07.30 |
---|---|
Pandas: 통계량 알아보기, 그룹화하기, 범주별 비율 구하기 (0) | 2024.07.10 |
웹 크롤링으로 데이터 가져오기 (0) | 2024.07.07 |
Pandas: 날짜 다루기, 사용자 정의 함수 적용하기, 데이터 결합하기 (0) | 2024.07.04 |
Pandas: 행과 열 가공하기, 결측치 처리하기 (0) | 2024.07.04 |