블로그로 돌아가기

Playwright에서 헤드리스 테스트 및 파싱을 위한 프록시 설정: 완벽 가이드

프레임워크 Playwright에서 헤드리스 테스트와 파싱을 위한 프록시 연결 방법을 코드 예제, IP 회전 및 안티봇 방어 우회와 함께 설명합니다.

📅2026년 5월 8일
```html

Playwright는 브라우저 자동화, 헤드리스 테스트 및 데이터 파싱을 위한 가장 강력한 도구 중 하나입니다. 그러나 올바르게 설정된 프록시가 없으면 스크립트가 빠르게 IP 차단을 받을 수 있습니다: 웹사이트는 자동화된 요청을 인식하고 이를 차단하는 방법을 배웠습니다. 이 가이드에서는 Playwright에서 프록시를 연결하는 모든 방법을 다룰 것입니다 — 기본 구성에서 IP 회전 및 Cloudflare 우회까지.

Playwright에서 프록시가 필요한 이유와 언제 필수인지

Playwright는 실제 브라우저(Chromium, Firefox 또는 WebKit)를 백그라운드에서 실행합니다 — 이것이 바로 헤드리스입니다. 사이트의 관점에서 당신은 일반 사용자처럼 보이지만, 특정 시점까지입니다. 하나의 IP에서 시간당 수백 개의 요청이 발생하기 시작하면, 보호 알고리즘은 즉시 반응합니다: CAPTCHA, 임시 차단, 완전 차단.

다음은 프록시가 필수인 구체적인 시나리오입니다:

  • 마켓플레이스 파싱 — Wildberries, Ozon, Avito, Yandex.Market은 하나의 IP에서 50–100개의 요청이 발생하면 스크립트를 차단합니다.
  • 경쟁사 가격 모니터링 — 15분마다 검사를 실행하면 IP를 변경하지 않고 몇 시간 내에 차단됩니다.
  • 지리적 위치 테스트 — 독일, 미국 또는 카자흐스탄의 사용자에게 사이트가 어떻게 보이는지 확인해야 합니다.
  • 양식 작성 및 계정 등록 — 플랫폼은 계정을 IP에 연결하고 대량 등록을 차단합니다.
  • SEO 모니터링 — Google 및 Yandex에서 위치를 수집하려면 IP를 지속적으로 변경해야 하며, 그렇지 않으면 검색 엔진이 CAPTCHA를 표시합니다.
  • A/B 기능 테스트 — 일부 기능은 특정 국가 또는 지역의 사용자에게만 제공됩니다.

중요한 점은 Playwright 자체가 당신을 익명으로 만들어주지 않는다는 것입니다. 프록시 없이 모든 요청은 당신의 실제 IP 주소에서 발생합니다. 프록시를 추가하는 것은 모든 자동화 스크립트의 안정적인 작동을 위한 첫 번째이자 가장 중요한 단계입니다.

💡 알아두어야 할 점

Playwright는 전체 브라우저, 개별 컨텍스트(BrowserContext) 및 심지어 개별 페이지 수준에서 프록시를 지원합니다. 이는 유연성을 제공하며, 서로 다른 페이지가 동시에 서로 다른 IP를 통해 작동할 수 있습니다.

헤드리스 자동화를 위한 프록시 유형 선택하기

모든 프록시가 Playwright에 동일하게 적합한 것은 아닙니다. 선택은 작업에 따라 다릅니다: 무엇을 파싱하는지, 사이트의 보호가 얼마나 공격적인지, 요청량은 얼마나 되는지에 따라 다릅니다.

프록시 유형 신뢰 수준 속도 적합한 용도
데이터 센터 낮음 매우 높음 엄격한 보호가 없는 파싱, 테스트
주거용 높음 중간 Cloudflare가 있는 사이트, 마켓플레이스, 소셜 미디어
모바일 최대 중간 Facebook, TikTok, Instagram, 엄격한 봇 방지
SOCKS5 출처에 따라 다름 높음 범용 프로토콜, Playwright에서 지원됨

대부분의 파싱 작업에 최적의 선택은 회전하는 주거용 프록시입니다. 이들은 실제 주택 사용자 IP를 가지고 있어 사이트가 이를 데이터 센터로 인식하지 않고 자동으로 차단하지 않습니다. 공격적인 보호가 있는 사이트(Cloudflare Bot Management, Akamai)에는 모바일 프록시를 사용하는 것이 좋습니다 — 이들의 IP는 이동통신사에 속해 있어 최대한의 신뢰를 얻습니다.

Playwright는 http, httpssocks5 프로토콜을 지원합니다. 중요한 점: SOCKS5는 일부 버전에서 username:password를 통한 인증을 직접 지원하지 않습니다 — 오류 섹션에서 자세히 설명합니다.

Playwright에서 프록시 기본 설정 (JavaScript 및 Python)

Playwright는 브라우저를 시작할 때 proxy 매개변수를 통해 프록시를 설정할 수 있습니다. 이것은 가장 간단한 방법입니다 — 모든 브라우저 요청은 지정된 프록시 서버를 통해 전송됩니다.

JavaScript / Node.js

const { chromium } = require('playwright');

(async () => {
  const browser = await chromium.launch({
    proxy: {
      server: 'http://proxy.example.com:8080'
    }
  });

  const page = await browser.newPage();
  await page.goto('https://httpbin.org/ip');
  
  const content = await page.textContent('body');
  console.log(content); // 프록시 서버의 IP를 보여줍니다.

  await browser.close();
})();

Python

from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch(
        proxy={
            "server": "http://proxy.example.com:8080"
        }
    )
    
    page = browser.new_page()
    page.goto("https://httpbin.org/ip")
    
    print(page.text_content("body"))  # 프록시의 IP를 보여줍니다.
    
    browser.close()

SOCKS5의 경우 서버 주소에서 스킴만 변경하면 됩니다:

# Python — SOCKS5 프록시
browser = p.chromium.launch(
    proxy={
        "server": "socks5://proxy.example.com:1080"
    }
)

프록시가 작동하는지 빠르게 확인하려면 https://httpbin.org/ip 또는 https://api.ipify.org를 열어보세요 — 응답에는 당신의 실제 IP가 아닌 프록시 서버의 IP가 있어야 합니다.

로그인 및 비밀번호로 인증하는 프록시

대부분의 상업용 프록시 제공업체는 로그인 및 비밀번호 인증을 사용합니다 — 이는 표준 관행입니다. Playwright는 프록시 객체의 usernamepassword 필드를 통해 이를 지원합니다.

JavaScript

const browser = await chromium.launch({
  proxy: {
    server: 'http://gate.proxyprovider.com:7777',
    username: 'your_login',
    password: 'your_password'
  }
});

Python

browser = p.chromium.launch(
    proxy={
        "server": "http://gate.proxyprovider.com:7777",
        "username": "your_login",
        "password": "your_password"
    }
)

또한 로그인과 비밀번호를 프록시 서버의 URL에 직접 전달할 수 있습니다 — 이는 문자열을 동적으로 생성할 때 편리합니다:

# URL에서 인증 (Python)
proxy_url = f"http://{login}:{password}@gate.proxyprovider.com:7777"

browser = p.chromium.launch(
    proxy={"server": proxy_url}
)

⚠️ 주의

프록시의 로그인과 비밀번호를 코드에 직접 저장하지 마세요! 환경 변수를 사용하세요 (os.environ in Python 또는 process.env in Node.js) 또는 .env 파일과 dotenv 라이브러리를 사용하세요.

.env를 통한 안전한 저장 (Python)

import os
from dotenv import load_dotenv
from playwright.sync_api import sync_playwright

load_dotenv()

PROXY_SERVER   = os.getenv("PROXY_SERVER")
PROXY_LOGIN    = os.getenv("PROXY_LOGIN")
PROXY_PASSWORD = os.getenv("PROXY_PASSWORD")

with sync_playwright() as p:
    browser = p.chromium.launch(
        proxy={
            "server":   PROXY_SERVER,
            "username": PROXY_LOGIN,
            "password": PROXY_PASSWORD
        }
    )
    # ...

프록시 회전: 각 요청마다 IP 변경하기

하나의 프록시만으로는 많은 요청을 할 경우 차단을 피할 수 없습니다. 본격적인 파싱을 위해서는 IP 회전이 필요합니다 — 특정 간격으로 프록시 서버를 자동으로 변경하거나 각 새로운 요청마다 변경해야 합니다.

Playwright에서 회전을 위한 두 가지 접근 방식이 있습니다:

접근 방식 1: 회전하는 프록시 엔드포인트

대부분의 주거용 프록시 제공업체는 연결할 때마다 IP를 자동으로 변경하는 단일 게이트웨이 주소를 제공합니다. 회전 로직을 작성할 필요가 없습니다 — 이는 제공업체 측에서 내장되어 있습니다.

# 하나의 엔드포인트 — 브라우저가 연결할 때마다 새로운 IP
browser = p.chromium.launch(
    proxy={
        "server":   "http://rotating.proxyprovider.com:8888",
        "username": "your_login",
        "password": "your_password"
    }
)

접근 방식 2: 프록시 목록을 통한 수동 회전

정적 프록시 목록이 있는 경우, 각 반복마다 새로운 브라우저 또는 컨텍스트를 생성하여 수동으로 회전을 구현할 수 있습니다:

import random
from playwright.sync_api import sync_playwright

PROXY_LIST = [
    {"server": "http://proxy1.example.com:8080", "username": "user", "password": "pass"},
    {"server": "http://proxy2.example.com:8080", "username": "user", "password": "pass"},
    {"server": "http://proxy3.example.com:8080", "username": "user", "password": "pass"},
]

URLS_TO_SCRAPE = [
    "https://example.com/page1",
    "https://example.com/page2",
    "https://example.com/page3",
]

with sync_playwright() as p:
    for url in URLS_TO_SCRAPE:
        proxy = random.choice(PROXY_LIST)  # 랜덤 프록시
        
        browser = p.chromium.launch(proxy=proxy)
        page = browser.new_page()
        
        page.goto(url)
        # ... 데이터 파싱 ...
        
        browser.close()  # 브라우저를 닫고 IP 변경

접근 방식 3: BrowserContext를 통한 회전 (브라우저 재시작 없이)

with sync_playwright() as p:
    browser = p.chromium.launch()  # 프록시 없는 브라우저
    
    for i, url in enumerate(URLS_TO_SCRAPE):
        proxy = PROXY_LIST[i % len(PROXY_LIST)]  # 순환
        
        # 새로운 프록시로 새로운 컨텍스트 생성 — 브라우저 재시작보다 빠름
        context = browser.new_context(proxy=proxy)
        page = context.new_page()
        
        page.goto(url)
        # ... 파싱 ...
        
        context.close()  # 브라우저는 닫지 않고 컨텍스트만 닫기
    
    browser.close()

세 번째 접근 방식은 대량 파싱에 가장 효율적입니다. 브라우저를 재시작하는 데는 2–4초가 걸리지만, 새로운 컨텍스트를 생성하는 데는 100밀리초도 걸리지 않습니다.

컨텍스트 및 페이지 수준의 프록시

Playwright는 유연한 아키텍처를 지원합니다: 하나의 브라우저는 여러 개의 격리된 컨텍스트를 가질 수 있으며, 각 컨텍스트에는 고유한 프록시가 있습니다. 이를 통해 하나의 프로세스 내에서 여러 IP로 동시에 작업할 수 있습니다.

다양한 프록시를 가진 여러 컨텍스트 (병렬 파싱)

const { chromium } = require('playwright');

(async () => {
  const browser = await chromium.launch();

  // 컨텍스트 1 — 독일의 프록시
  const context_de = await browser.newContext({
    proxy: {
      server: 'http://de-proxy.example.com:8080',
      username: 'user',
      password: 'pass'
    }
  });

  // 컨텍스트 2 — 미국의 프록시
  const context_us = await browser.newContext({
    proxy: {
      server: 'http://us-proxy.example.com:8080',
      username: 'user',
      password: 'pass'
    }
  });

  const page_de = await context_de.newPage();
  const page_us = await context_us.newPage();

  // 병렬 실행
  await Promise.all([
    page_de.goto('https://example.com'),
    page_us.goto('https://example.com')
  ]);

  // 두 페이지는 서로 다른 IP를 봅니다
  console.log('DE IP:', await page_de.textContent('body'));
  console.log('US IP:', await page_us.textContent('body'));

  await browser.close();
})();

이 접근 방식은 지리적 위치 테스트에 이상적입니다: 여러 국가의 사용자에게 사이트가 어떻게 표시되는지 동시에 확인할 수 있으며, 여러 브라우저 인스턴스를 실행할 필요가 없습니다.

💡 성능 팁

최대 병렬성을 위해 Python에서는 asyncio를 사용하거나 Node.js에서는 Promise.all을 사용하세요. 하나의 브라우저는 메모리에 큰 부담 없이 10–20개의 병렬 컨텍스트를 유지할 수 있습니다.

봇 방지 우회: Cloudflare, Akamai, DataDome

프록시는 솔루션의 일부에 불과합니다. 현대의 봇 방지 시스템은 동시에 수십 가지 신호를 분석합니다: 브라우저 지문, 마우스 행동, 양식 작성 속도, HTTP 헤더 등. 좋은 프록시가 있어도 이러한 요소를 고려하지 않으면 차단될 수 있습니다.

1. 헤드리스 모드 마스킹

Playwright는 헤드리스 모드에서 쉽게 식별할 수 있는 특징이 있습니다: 특정 값의 navigator.webdriver, 플러그인 없음, 비표준 화면 크기. playwright-stealth 라이브러리를 사용하여 마스킹하세요:

# Python: 설치
# pip install playwright-stealth

from playwright.sync_api import sync_playwright
from playwright_stealth import stealth_sync

with sync_playwright() as p:
    browser = p.chromium.launch(
        proxy={
            "server":   "http://residential.proxyprovider.com:8888",
            "username": "user",
            "password": "pass"
        }
    )
    page = browser.new_page()
    stealth_sync(page)  # 마스킹 적용
    
    page.goto("https://bot.sannysoft.com")  # 봇 감지 테스트
    browser.close()

2. 현실적인 User-Agent 및 viewport

context = browser.new_context(
    proxy={
        "server":   "http://proxy.example.com:8080",
        "username": "user",
        "password": "pass"
    },
    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",
    viewport={"width": 1920, "height": 1080},
    locale="ko-KR",
    timezone_id="Europe/Moscow"  # 프록시의 지리적 위치와 일치해야 합니다!
)

3. 인간 행동 모방

import time
import random

# 행동 간의 무작위 지연
def human_delay(min_ms=500, max_ms=2000):
    time.sleep(random.randint(min_ms, max_ms) / 1000)

page.goto("https://example.com")
human_delay()

# 즉각적인 대신 부드러운 스크롤
page.evaluate("window.scrollBy({top: 500, behavior: 'smooth'})")
human_delay(300, 800)

# 클릭 전에 마우스 이동
page.mouse.move(100, 200)
human_delay(100, 300)
page.mouse.move(300, 400)
human_delay(100, 200)
page.click("button#submit")

4. 타임존과 프록시의 지리적 위치 일치

이는 종종 무시되지만, 봇 방지 시스템은 일치를 확인합니다: 만약 당신의 프록시가 모스크바에 있고 브라우저가 UTC-8 (로스앤젤레스) 타임존을 보여준다면 — 이는 빨간 깃발입니다. 항상 사용되는 프록시의 지리적 위치에 맞게 timezone_id를 설정하세요.

일반적인 오류 및 수정 방법

Playwright에서 프록시를 사용할 때 개발자들은 종종 동일한 문제에 직면합니다. 각 문제를 구체적인 해결책과 함께 살펴보겠습니다.

오류 1: ERR_PROXY_CONNECTION_FAILED

원인: 잘못된 프록시 주소 또는 포트, 프록시가 사용할 수 없음, 잘못된 인증 정보.
해결책: Playwright를 실행하기 전에 curl을 통해 프록시의 가용성을 확인하세요:

# curl을 통한 프록시 확인
curl -x http://user:[email protected]:8080 https://api.ipify.org

오류 2: SOCKS5가 인증을 수용하지 않음

원인: Playwright (Chromium)는 username/password를 통한 SOCKS5 인증을 제한적으로 지원합니다.
해결책: 인증이 있는 HTTP 프록시를 사용하거나 비밀번호 없이 ssh -D를 통해 로컬 SOCKS5 터널을 설정하세요.

오류 3: 프록시는 작동하지만 사이트가 여전히 차단함

원인: 블랙리스트에 있는 데이터 센터 프록시 사용; 헤드리스 모드가 마스킹되지 않음; 너무 높은 요청 빈도.
해결책: 주거용 또는 모바일 프록시로 전환하고 playwright-stealth를 추가하며 요청 간 지연을 늘리세요.

오류 4: 실제 IP 유출 (DNS 유출)

원인: DNS 요청이 프록시를 우회할 수 있습니다.
해결책: Playwright는 HTTP 프록시를 사용할 때 기본적으로 DNS를 프록시를 통해 전달합니다. 그러나 https://dnsleaktest.com를 사용하여 헤드리스 브라우저에서 확인하세요.

오류 5: 프록시 사용 시 느린 속도

원인: 주거용 프록시는 데이터 센터 프록시보다 느리며; 프록시 서버까지의 거리가 멀다.
해결책: 지리적으로 가까운 위치의 프록시를 선택하세요. 익명성에 대한 엄격한 요구 사항이 없는 작업에는 데이터 센터 프록시를 사용하세요 — 이들은 훨씬 빠릅니다.

오류 빠른 해결책
ERR_PROXY_CONNECTION_FAILED curl 확인, 로그인/비밀번호, 포트 가용성 확인
407 Proxy Auth Required 프록시 구성에 username 및 password 추가
사이트가 CAPTCHA를 표시함 주거용 프록시로 유형 변경, stealth 추가
IP가 회전 중 변경되지 않음 요청 간 컨텍스트/브라우저를 닫기
연결 타임아웃 goto()에서 timeout 늘리기, 더 가까운 프록시 선택

결론 및 권장 사항

Playwright에서 프록시 설정은 일회성이 아닌 자동화 도구 아키텍처의 일부입니다. 올바르게 선택된 프록시 유형, 적절한 IP 회전 및 헤드리스 모드 마스킹이 결합되어 공격적인 봇 방지 보호가 있는 사이트에서도 안정적인 작동을 제공합니다.

특정 작업에 대한 프록시 유형 선택에 대한 요약은 다음과 같습니다:

  • 엄격한 보호가 없는 공개 데이터 파싱 — 빠른 데이터 센터 프록시가 적합합니다.
  • 마켓플레이스 (Wildberries, Ozon), 뉴스 집계기 — 회전하는 주거용 프록시가 필요합니다.
  • 소셜 미디어 (Instagram, Facebook, TikTok) 및 Cloudflare가 있는 사이트 — 모바일 또는 주거용 프록시만 사용하세요.
  • 지리적 위치 테스트 — 필요한 국가에서 어떤 유형의 프록시든지, 타임존 일치가 중요합니다.
  • 높은 빈도의 대량 파싱 — 게이트웨이 엔드포인트가 있는 회전하는 주거용 프록시를 사용하세요.

Playwright에서 파싱 시스템이나 자동화 테스트 시스템을 구축하고 차단 없이 안정적인 작업이 필요하다면 주거용 프록시를 고려하는 것이 좋습니다 — 이들은 사이트의 신뢰 수준이 높고 단일 엔드포인트를 통해 IP 회전을 지원하여 Playwright와의 통합을 몇 줄의 코드로 간소화합니다.

```