학습 목표
현대적인 쇼핑몰 웹사이트는 React, Vue, Next.js와 같은 프레임워크를 사용하여 페이지를 동적으로 렌더링합니다. 과거의 BeautifulSoup 방식만으로는 자바스크립트가 실행된 후의 데이터를 가져오기에 한계가 있습니다. 본 강의의 목표는 2026년 현재 가장 강력한 웹 자동화 도구인 Playwright를 활용하여, 복잡한 동적 페이지 구조를 가진 쇼핑몰에서 상품 리뷰 데이터를 안정적으로 수집하는 기술을 습득하는 것입니다. 이 과정을 통해 여러분은 단순 크롤링을 넘어 브라우저 제어와 데이터 정제까지 실무 수준의 역량을 갖추게 될 것입니다.
사전 준비 사항
실습에 앞서 아래의 환경을 반드시 구축해야 합니다. 본 강의는 최신 기술 스택을 기준으로 작성되었습니다.
- 운영체제(OS): Windows 10/11, macOS Sequoia 이상, 또는 Linux(Ubuntu 22.04+)
- 코드 에디터: Visual Studio Code (VSCode) 권장
- 파이썬 버전: Python 3.11 이상 (비동기 처리를 위해 최신 버전 권장)
- 필수 라이브러리 설치: 터미널(CMD)에서 아래 명령어를 순차적으로 입력하세요.
pip install playwright pandas
playwright install chromium위 명령어 중 playwright install chromium은 크롤링에 필요한 브라우저 엔진을 시스템에 설치하는 핵심 단계입니다. 설치가 완료되었다면 실습 준비가 모두 끝난 것입니다.
단계별 실습 과정
1단계: 프로젝트 초기설정 및 브라우저 실행
먼저 파이썬 파일을 생성하고(예: crawler.py), Playwright의 비동기 라이브러리를 호출합니다. Playwright는 asyncio를 기반으로 작동하여 다량의 페이지를 동시에 처리할 때 매우 효율적입니다.
import asyncio
from playwright.async_api import async_playwright
import pandas as pd
async def crawl_reviews():
async with async_playwright() as p:
# 브라우저 실행 (headless=False로 설정하면 작동 과정을 눈으로 볼 수 있습니다)
browser = await p.chromium.launch(headless=False)
context = await browser.new_context(
user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
)
page = await context.new_page()
# 대상 쇼핑몰 URL 접속
target_url = "https://example-shopping-mall.com/product/12345"
await page.goto(target_url)
await page.wait_for_load_state("networkidle")
print("페이지 로드 완료!")여기서 user_agent를 설정하는 이유는 봇 탐지를 우회하기 위함입니다. 실무에서는 실제 사용자의 브라우저 정보를 입력하는 것이 필수적입니다.
2단계: 리뷰 섹션으로 이동 및 동적 요소 대기
대부분의 쇼핑몰은 리뷰가 하단에 위치하며, ‘리뷰’ 탭을 클릭해야 데이터가 로드됩니다. Playwright의 click() 함수와 wait_for_selector()를 사용하여 이 과정을 자동화합니다.
# 리뷰 탭 클릭 (선택자는 실제 사이트에 맞춰 수정 필요)
review_tab_selector = "button#tab-review"
await page.click(review_tab_selector)
# 리뷰 리스트가 나타날 때까지 대기
review_list_selector = ".review-container"
await page.wait_for_selector(review_list_selector, timeout=10000)
print("리뷰 섹션 진입 성공!")3단계: 데이터 파싱 및 반복 수집 루프
이제 화면에 보이는 리뷰들을 리스트 형태로 가져옵니다. query_selector_all을 사용하여 여러 개의 리뷰 요소를 한 번에 잡고, 각각의 텍스트와 별점을 추출합니다.
reviews_data = []
# 현재 페이지의 리뷰 아이템들 추출
items = await page.query_selector_all(".review-item")
for item in items:
user_id = await (await item.query_selector(".user-name")).inner_text()
rating = await (await item.query_selector(".score")).get_attribute("data-rating")
content = await (await item.query_selector(".comment-text")).inner_text()
date = await (await item.query_selector(".date")).inner_text()
reviews_data.append({
"작성자": user_id.strip(),
"평점": rating,
"내용": content.strip().replace('\n', ' '),
"날짜": date
})
print(f"{len(reviews_data)}개의 리뷰를 추출했습니다.")4단계: 페이지네이션(다음 페이지) 처리
단일 페이지 크롤링만으로는 부족합니다. 하단의 ‘다음’ 버튼을 찾아 클릭하고, 새로운 리뷰가 로드될 때까지 기다리는 로직을 추가합니다.
# 다음 페이지 버튼 클릭 예시 (최대 5페이지까지)
for i in range(2, 6):
next_button = await page.query_selector(f"a.page-link:has-text('{i}')")
if next_button:
await next_button.click()
await page.wait_for_timeout(2000) # 네트워크 지연 고려
# 추가 수집 로직 수행...5단계: 데이터 저장 및 브라우저 종료
수집된 데이터를 Pandas의 DataFrame으로 변환하여 CSV 파일로 저장합니다. 엑셀에서 바로 열어볼 수 있도록 utf-8-sig 인코딩을 사용합니다.
df = pd.DataFrame(reviews_data)
df.to_csv("shopping_reviews.csv", index=False, encoding="utf-8-sig")
print("데이터 저장 완료: shopping_reviews.csv")
await browser.close() # 브라우저 종료결과 확인
모든 코드를 작성한 후 터미널에서 python crawler.py를 실행하십시오. 브라우저가 자동으로 열리며 쇼핑몰에 접속하고, 리뷰 탭을 누른 뒤 데이터를 긁어모으는 과정을 실시간으로 확인할 수 있습니다.
성공적인 크롤링을 위한 팁:
1. 선택자 확인: 웹사이트의 HTML 구조는 수시로 변경됩니다. 크롬 개발자 도구(F12)를 활용해 .review-item과 같은 클래스명이 정확한지 수시로 확인하세요.
2. 속도 조절: 너무 빠른 요청은 IP 차단의 원인이 됩니다. page.wait_for_timeout(1000)을 적절히 섞어 인간적인 속도로 크롤링하세요.
3. 예외 처리: 리뷰가 없는 상품이나 품절된 상품 페이지에 접속했을 때 코드가 멈추지 않도록 try-except 문으로 감싸주는 것이 실무 기술의 핵심입니다.
이제 여러분은 Playwright를 통해 어떤 복잡한 쇼핑몰이라도 데이터를 자유자재로 다룰 수 있는 기초 체력을 갖추게 되었습니다. 수집된 데이터를 바탕으로 감성 분석이나 시장 트렌드 파악 등 더 고차원적인 데이터 분석에 도전해 보세요.


