셀레니움에서 플레이라이트로
넘어간 이유
차세대 브라우저 자동화 툴의 핵심 장점과 환경 세팅
셀레니움(Selenium)은 2004년 등장한 이래 20년 넘게 브라우저 자동화의 표준이었다. 하지만 최근 몇 년 사이 흐름이 빠르게 바뀌고 있다. 2026년 기준, TestGuild 설문에서 Playwright 사용률이 Selenium을 넘어섰고, GitHub 스타 수도 Playwright(74,000+)가 Selenium(32,000+)을 크게 앞선다.
나도 몇 년간 셀레니움을 써왔다가 플레이라이트로 완전히 넘어갔다. 왜 바꿨는지, 뭐가 다른지, 그리고 환경 세팅은 어떻게 하는지 정리해본다.
🤦 셀레니움의 고질적인 문제들
셀레니움을 오래 쓴 사람이라면 공감할 만한 것들이다.
1) WebDriver 지옥. 크롬이 업데이트될 때마다 ChromeDriver 버전이 안 맞아서 터진다. 매번 드라이버를 다운로드하고 경로를 맞춰줘야 한다. Selenium 4에서 Selenium Manager가 추가됐지만, 여전히 완벽하지 않다.
2) 대기(wait) 코드의 늪. 요소가 로딩될 때까지 기다리는 코드를 매번 수동으로 작성해야 한다. WebDriverWait, expected_conditions, 심지어 time.sleep(3) 같은 하드코딩까지. 동적 웹페이지가 많아질수록 이 문제는 점점 심해진다.
3) 느린 실행 속도. Selenium은 WebDriver 프로토콜(HTTP 기반)로 브라우저와 통신한다. 명령 하나하나가 HTTP 요청/응답을 거치기 때문에 지연이 누적된다. 테스트 수가 수백 개를 넘어가면 체감 차이가 확연하다.
4) 불안정한 테스트(Flaky Tests). 같은 코드인데 어떤 때는 성공하고 어떤 때는 실패한다. 요소가 보이기 전에 클릭하거나, 다른 요소에 가려진 상태에서 상호작용하려고 해서 생기는 문제다. 디버깅에 많은 시간을 빼앗긴다.
⚡ 플레이라이트가 해결한 것들
📊 핵심 비교표
| 항목 | SELENIUM | PLAYWRIGHT |
|---|---|---|
| 출시 | 2004년 | 2020년 (Microsoft) |
| 통신 방식 | WebDriver (HTTP) | CDP (WebSocket) ✓ |
| 실행 속도 | 상대적 느림 | 20~30% 빠름 ✓ |
| 자동 대기 | 수동 wait 필요 | Auto-Wait 내장 ✓ |
| 브라우저 설치 | 드라이버 수동 관리 | 자동 다운로드 ✓ |
| 지원 언어 | Java, Python, C#, JS, Ruby, PHP, Kotlin |
JS/TS, Python, Java, C# |
| 브라우저 | Chrome, FF, Safari, Edge, IE, Opera |
Chromium, Firefox, WebKit |
| 네트워크 인터셉트 | 제한적 | 기본 내장 ✓ |
| 디버깅 도구 | 외부 플러그인 필요 | Trace Viewer 등 내장 ✓ |
| 병렬 실행 | Selenium Grid 별도 구성 | 테스트러너 기본 지원 ✓ |
| GitHub Stars | ~32,000 | ~74,000+ ✓ |
⚠️ Selenium이 여전히 유리한 경우: IE/Opera 등 레거시 브라우저 지원이 필요하거나, Ruby/PHP 기반 프로젝트이거나, 기존에 대규모 Selenium 테스트 스위트가 구축되어 있는 경우에는 무리하게 마이그레이션하지 않는 것이 현실적이다.
💻 코드로 보는 차이
같은 작업을 Selenium과 Playwright로 작성했을 때 차이를 보자. 구글에서 "Playwright"를 검색하는 간단한 예시다.
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.Chrome()
driver.get("https://www.google.com")
# 검색창이 나타날 때까지 명시적으로 대기
search = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.NAME, "q"))
)
search.send_keys("Playwright" + Keys.RETURN)
# 결과가 로딩될 때까지 또 대기
WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.ID, "search"))
)
print(driver.title)
driver.quit()
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch()
page = browser.new_page()
page.goto("https://www.google.com")
# Auto-wait: 알아서 기다렸다가 입력
page.fill('[name="q"]', "Playwright")
page.press('[name="q"]', "Enter")
# Auto-wait: 알아서 기다렸다가 확인
page.wait_for_selector("#search")
print(page.title())
browser.close()
보이는가? Selenium은 WebDriverWait, expected_conditions, By 등 여러 모듈을 임포트하고, 대기 로직을 직접 작성해야 한다. Playwright는 Auto-Wait가 내장되어 있어서 요소가 준비될 때까지 자동으로 기다린다. 코드가 짧고 직관적이다.
🛠️ 플레이라이트 환경 세팅 (Python)
# 패키지 설치
pip install playwright
# 브라우저 바이너리 다운로드 (Chromium, Firefox, WebKit)
playwright install
# 특정 브라우저만 설치하고 싶다면
playwright install chromium
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch(headless=False) # 브라우저 보면서 실행
page = browser.new_page()
page.goto("https://example.com")
print(page.title())
browser.close()
import asyncio
from playwright.async_api import async_playwright
async def main():
async with async_playwright() as p:
browser = await p.chromium.launch()
page = await browser.new_page()
await page.goto("https://example.com")
print(await page.title())
await browser.close()
asyncio.run(main())
# 브라우저 옵션
browser = p.chromium.launch(
headless=True, # 헤드리스 모드
slow_mo=500, # 동작 사이 500ms 딜레이 (디버깅용)
)
# 컨텍스트 옵션 (독립 세션)
context = browser.new_context(
viewport={"width": 1920, "height": 1080},
user_agent="커스텀 UA 문자열",
locale="ko-KR",
timezone_id="Asia/Seoul",
)
# 네트워크 인터셉트 (이미지 차단 예시)
page.route("**/*.{png,jpg,jpeg,gif}", lambda route: route.abort())
# 스크린샷 & PDF
page.screenshot(path="screenshot.png", full_page=True)
page.pdf(path="page.pdf")
# Trace 녹화 (디버깅)
context.tracing.start(screenshots=True, snapshots=True)
# ... 작업 수행 ...
context.tracing.stop(path="trace.zip")
# → playwright show-trace trace.zip 으로 확인
# 터미널에서 실행하면 브라우저가 열리고,
# 조작하는 모든 동작이 Python 코드로 변환된다
playwright codegen https://example.com
# 특정 언어로 생성
playwright codegen --target python https://example.com
# 모바일 디바이스 에뮬레이션
playwright codegen --device="iPhone 13" https://example.com
💡 Docker에서 사용하려면: playwright install --with-deps chromium 으로 시스템 의존성까지 함께 설치하면 Ubuntu/Debian 컨테이너에서 바로 사용할 수 있다. 공식 Docker 이미지(mcr.microsoft.com/playwright/python)도 제공된다.
✅ 정리
셀레니움이 나쁜 도구라는 건 아니다. 20년간 브라우저 자동화의 표준이었고, 거대한 생태계와 커뮤니티가 있다. 레거시 브라우저 지원이 필요하거나, 이미 대규모 Selenium 인프라가 구축되어 있다면 굳이 바꿀 이유는 없다.
하지만 새로 시작하는 프로젝트라면 Playwright를 추천한다. Auto-Wait, 브라우저 자동 설치, 네트워크 인터셉트, Trace Viewer, Codegen 등 현대적인 웹 자동화에 필요한 기능이 기본으로 들어 있다. 셀레니움에서 플러그인이나 우회 코드로 해결하던 것들이 Playwright에서는 그냥 된다.
특히 Python 기반으로 크롤링, 자동화, 테스트를 하는 사람이라면 전환 비용 대비 얻는 것이 확실히 크다.
WebDriver 지옥에서 벗어나고 싶다면
Playwright를 한번 써보자.
돌아갈 생각이 안 날 거다.
'Tech & Science > Cloud & IT' 카테고리의 다른 글
| Python datetime.utcnow() DeprecationWarning 해결 방법 (0) | 2025.05.22 |
|---|---|
| Docker에서 시간대(TZ)를 Asia/Seoul로 변경하는 방 (1) | 2025.05.22 |
| Docker 컨테이너 재부팅 후 Flask 접속 불가? 원인과 해결 방법 총정리 (0) | 2025.05.22 |
| SQLite에서 PRIMARY KEY 제거하는 방법 완전 정리 (+실습 예제) (1) | 2025.05.22 |
| SIM 스와핑이란? 당신의 번호를 노리는 해커의 기술 (4) | 2025.05.10 |
