[실무 강의] **Playwright로 시작하는 동적 웹페이지 실시간 데이터 크롤링 (바로 따라하기)** 완벽 마스터 튜토리얼

학습 목표

본 강의의 목표는 2026년 현재 가장 강력하고 효율적인 브라우저 자동화 도구인 Playwright를 활용하여, 기존의 정적 크롤링 방식으로는 수집하기 어려운 동적 웹페이지(SPA, React, Vue.js 기반)의 실시간 데이터를 완벽하게 추출하는 기술을 습득하는 것입니다. Selenium보다 빠르고 안정적인 Playwright의 핵심 기능을 실무 수준으로 마스터하게 됩니다.

사전 준비 사항

실습을 시작하기 전, 다음의 환경이 구성되어 있어야 합니다. 본 가이드는 2026년 최신 안정화 버전을 기준으로 작성되었습니다.

  • 운영체제(OS): Windows 11 이상, macOS Sequoia 이상, 또는 Linux (Ubuntu 22.04 LTS+)
  • 개발 도구: Visual Studio Code (VS Code) 최신 버전
  • 언어 환경: Python 3.11 버전 이상 권장
  • 필수 라이브러리 설치: 터미널(Terminal) 또는 명령 프롬프트(CMD)에서 아래 명령어를 순차적으로 실행하세요.
# Playwright 라이브러리 설치
pip install playwright

# 필요한 브라우저 엔진(Chromium, Firefox, WebKit) 설치
playwright install

환경 설정이 완료되었다면 이제 본격적인 크롤링 실습을 진행하겠습니다.

단계별 실습 과정

1단계: Playwright 기본 구조 이해하기

Playwright는 동기(Sync) 방식과 비동기(Async) 방식을 모두 지원합니다. 대규모 데이터 크롤링이나 실시간 성능이 중요한 실무에서는 asyncio를 활용한 비동기 방식을 주로 사용합니다. 먼저 브라우저를 실행하고 페이지를 여는 기본 코드를 작성해 보겠습니다.

import asyncio
from playwright.async_api import async_playwright

async def run():
    async with async_playwright() as p:
        # 브라우저 실행 (headless=False로 설정하면 브라우저가 뜨는 것을 볼 수 있습니다)
        browser = await p.chromium.launch(headless=False)
        page = await browser.new_page()
        
        # 대상 URL 접속
        await page.goto("https://example.com")
        print(await page.title())
        
        await browser.close()

asyncio.run(run())

2단계: 동적 요소 로딩 대기 (Wait Strategy)

동적 웹페이지는 JavaScript가 실행된 후에야 데이터가 화면에 나타납니다. 단순히 페이지를 로드하는 것만으로는 데이터를 가져올 수 없습니다. Playwright의 `wait_for_selector` 기능을 사용하여 특정 요소가 나타날 때까지 기다려야 합니다.

# 특정 CSS 선택자가 나타날 때까지 최대 10초 대기
await page.wait_for_selector(".dynamic-content-item", timeout=10000)

3단계: 무한 스크롤 및 실시간 데이터 렌더링 처리

최신 웹사이트들은 스크롤을 내릴 때마다 새로운 데이터를 불러오는 ‘무한 스크롤’ 방식을 채택합니다. 이를 해결하기 위해 페이지 하단으로 스크롤을 내리는 로직을 추가합니다.

async def scroll_to_bottom(page):
    # 페이지 끝까지 스크롤을 내리는 JavaScript 실행
    await page.evaluate("window.scrollTo(0, document.body.scrollHeight)")
    # 데이터 로딩을 위한 대기
    await page.wait_for_timeout(2000)

4단계: 데이터 추출 및 실무 활용

이제 화면에 렌더링된 요소들 중에서 필요한 텍스트나 속성 값을 추출합니다. 여러 개의 아이템을 한 번에 가져올 때는 `query_selector_all` 또는 `locator`를 사용합니다.

# 모든 상품 리스트 아이템 가져오기
items = await page.locator(".product-card").all()

for item in items:
    name = await item.locator(".title").inner_text()
    price = await item.locator(".price").inner_text()
    print(f"상품명: {name}, 가격: {price}")

5단계: 네트워크 이벤트 모니터링 (고급 기술)

Playwright의 진정한 강력함은 API 응답을 직접 가로채는 기능에 있습니다. 화면에 보이기 전, 서버에서 클라이언트로 전송되는 JSON 데이터를 직접 캡처할 수 있습니다.

async def handle_response(response):
    if "api/v1/products" in response.url:
        data = await response.json()
        print("API 데이터 수집 완료:", data)

page.on("response", handle_response)

위와 같이 네트워크 레벨에서 데이터를 수집하면 훨씬 정확하고 빠른 크롤링이 가능합니다.

결과 확인

최종 통합 소스코드

모든 과정을 통합한 실무형 크롤러 코드입니다. 이 코드는 동적 페이지 접속, 대기, 스크롤, 데이터 추출, 브라우저 종료의 전 과정을 포함합니다.

import asyncio
from playwright.async_api import async_playwright

async def main():
    async with async_playwright() as p:
        browser = await p.chromium.launch(headless=True)
        context = await browser.new_context(user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36")
        page = await context.new_page()

        # 1. 사이트 접속
        print("데이터 수집 중...")
        await page.goto("https://www.example-dynamic-shop.com", wait_until="networkidle")

        # 2. 동적 로딩 대기
        await page.wait_for_selector(".item-list")

        # 3. 스크롤 처리
        for _ in range(3):
            await page.mouse.wheel(0, 1000)
            await asyncio.sleep(1)

        # 4. 데이터 추출
        products = await page.locator(".item").all()
        results = []
        for p in products:
            title = await p.locator(".name").get_attribute("innerText")
            results.append(title)

        # 5. 결과 출력
        print(f"총 {len(results)}개의 데이터를 수집했습니다.")
        for i, res in enumerate(results[:5]):
            print(f"{i+1}. {res}")

        await browser.close()

if __name__ == "__main__":
    asyncio.run(main())

성공적인 실행 결과

코드를 실행하면 터미널에 수집된 데이터의 개수와 상위 리스트가 출력됩니다. 만약 오류가 발생한다면 `headless=False`로 설정하여 브라우저의 동작을 직접 눈으로 확인하며 디버깅하세요. Playwright는 자동 대기(Auto-waiting) 기능이 내장되어 있어 기존 Selenium에 비해 타임아웃 오류가 현저히 적습니다. 이제 여러분은 어떤 복잡한 동적 웹사이트라도 자유자재로 요리할 수 있는 실무 능력을 갖추게 되었습니다.

댓글 남기기