[실무 강의] **Playwright와 Pandas로 동적 웹사이트 페이지네이션 데이터 크롤링 및 CSV 저장** 완벽 마스터 튜토리얼

학습 목표

2026년 현재, 웹 환경은 단순한 정적 페이지를 넘어 복잡한 JavaScript 렌더링과 SPA(Single Page Application) 구조가 주를 이루고 있습니다. 본 강의에서는 최신 브라우저 자동화 도구인 Playwright를 사용하여 동적 웹사이트의 데이터를 수집하고, 수집된 데이터를 Pandas 라이브러리를 통해 정제하여 CSV 파일로 저장하는 실무 기술을 습득합니다. 특히 수백 페이지에 달하는 페이지네이션(Pagination) 구조를 효율적으로 순회하는 로직을 마스터하는 것이 핵심입니다.

사전 준비 사항

실습을 시작하기 전에 다음의 환경이 구성되어 있어야 합니다. 본 가이드는 2026년 표준 개발 환경을 기준으로 작성되었습니다.

  • 운영체제(OS): Windows 11, macOS Sequoia, 또는 Ubuntu 24.04 LTS 이상
  • 파이썬 버전: Python 3.10 이상 (3.12 권장)
  • IDE: Visual Studio Code (VSCode) 최신 버전
  • 필수 라이브러리 설치: 터미널(Terminal)에서 아래 명령어를 실행하여 필요한 패키지를 설치합니다.
pip install playwright pandas
playwright install chromium

위 명령어 중 playwright install chromium은 Playwright가 제어할 실제 브라우저 엔진을 설치하는 필수 단계입니다.

단계별 실습 과정

1단계: 프로젝트 초기 설정 및 라이브러리 임포트

먼저 비동기 처리를 위한 asyncio와 브라우저 제어를 위한 playwright, 데이터 처리를 위한 pandas를 불러옵니다. 현대적인 크롤러는 성능과 효율성을 위해 비동기(Async) 방식으로 작성하는 것이 원칙입니다.

import asyncio
from playwright.async_api import async_playwright
import pandas as pd
import time

2단계: Playwright 브라우저 실행 및 페이지 접속

Playwright는 headless 모드를 지원하여 백그라운드에서 빠르게 작동할 수 있지만, 디버깅 시에는 headless=False로 설정하여 브라우저의 움직임을 직접 확인하는 것이 좋습니다.

async def run_crawler():
    async with async_playwright() as p:
        # 브라우저 실행 (느린 네트워크 환경을 고려하여 slow_mo 추가 가능)
        browser = await p.chromium.launch(headless=False)
        page = await browser.new_page()
        
        # 대상 웹사이트 접속 (예시 URL)
        target_url = "https://example-dynamic-shop.com/products"
        await page.goto(target_url, wait_until="networkidle")
        
        all_data = [] # 데이터를 담을 리스트

3단계: 페이지네이션 데이터 추출 로직 구현

동적 웹사이트에서 가장 중요한 점은 데이터가 화면에 완전히 로드될 때까지 기다리는 것입니다. wait_for_selector를 활용하여 데이터 행(Row)이 나타날 때까지 대기한 후, 반복문을 통해 데이터를 수집합니다. 이후 ‘다음’ 버튼을 찾아 클릭하는 과정을 반복합니다.

        page_number = 1
        while True:
            print(f"현재 {page_number}페이지 수집 중...")
            
            # 데이터 로드 대기
            await page.wait_for_selector(".product-item")
            
            # 현재 페이지의 모든 상품 요소 선택
            products = await page.query_selector_all(".product-item")
            
            for product in products:
                name = await (await product.query_selector(".name")).inner_text()
                price = await (await product.query_selector(".price")).inner_text()
                all_data.append({"상품명": name, "가격": price})
            
            # '다음' 버튼 확인 및 클릭
            next_button = await page.query_selector("li.next-page:not(.disabled)")
            if next_button:
                await next_button.click()
                await page.wait_for_load_state("networkidle")
                page_number += 1
                await asyncio.sleep(1) # 서버 부하 방지를 위한 짧은 휴식
            else:
                print("마지막 페이지에 도달했습니다.")
                break

4단계: Pandas를 활용한 데이터 정제 및 CSV 저장

수집된 리스트 형태의 데이터를 Pandas의 DataFrame으로 변환하면 강력한 데이터 조작 기능을 사용할 수 있습니다. 중복 제거, 결측치 처리 등을 거친 후 최종적으로 CSV 파일로 내보냅니다.

        # 브라우저 종료
        await browser.close()
        
        # 데이터프레임 생성
        df = pd.DataFrame(all_data)
        
        # 데이터 정제 (예: 가격에서 '원' 표시 제거 및 숫자 변환)
        df['가격'] = df['가격'].str.replace("원", "").str.replace(",", "").astype(int)
        
        # CSV 저장 (Excel 인코딩 호환을 위해 utf-8-sig 사용)
        file_name = "crawled_products.csv"
        df.to_csv(file_name, index=False, encoding="utf-8-sig")
        print(f"성공적으로 {len(df)}개의 데이터를 {file_name}에 저장했습니다.")

결과 확인 및 유지보수 팁

모든 코드가 실행된 후 프로젝트 폴더 내에 crawled_products.csv 파일이 생성되었는지 확인하십시오. Playwright와 Pandas 조합은 다음과 같은 상황에서 매우 강력합니다.

성능 최적화 팁

  • 네트워크 차단: 이미지나 CSS 로딩을 차단하여 크롤링 속도를 2배 이상 향상시킬 수 있습니다. page.route 기능을 활용해 불필요한 리소스 요청을 가로채십시오.
  • 에러 처리: 네트워크 지연이나 갑작스러운 팝업 창에 대비하여 try-except 구문으로 예외 처리를 강화하는 것이 좋습니다.
  • 동적 대기: time.sleep()과 같은 고정 대기 시간보다는 wait_for_selectorwait_for_function을 사용하여 조건이 충족되는 즉시 실행되도록 설계하십시오.

이제 여러분은 Playwright의 브라우저 자동화 능력과 Pandas의 데이터 처리 능력을 결합한 고성능 크롤러를 구축할 수 있게 되었습니다. 이 기술은 시장 조사, 경쟁사 가격 분석, 뉴스 모니터링 등 다양한 IT 실무 현장에서 즉시 활용 가능합니다.

댓글 남기기