헤드리스 브라우저는 JavaScript를 렌더링하므로 일반 HTTP 클라이언트가 다루지 못하는 최신 사이트를 처리합니다. 하지만 브라우저는 여전히 모든 요청을 하나의 IP에서 보내며, 사이트가 그 주소에 속도 제한을 걸거나 핑거프린팅하는 순간 자동화가 적발됩니다. Playwright와 Puppeteer에서 프록시를 사용하면 트래픽을 여러 IP에 분산시키고, 제대로만 하면 자동화가 평범한 사용자처럼 보이게 만듭니다. 다음은 Python과 Node 양쪽에서 실제로 작동하는 설정입니다.
브라우저 실행 시 프록시를 설정하세요. 인증은 별도의 username과 password 필드로 전달하세요 — 서버 URL에 자격 증명을 인라인으로 넣지 마세요:
from playwright.sync_api import sync_playwright
PROXY = {
"server": "http://gate.jibaoproxy.com:10001",
"username": "USERNAME",
"password": "PASSWORD",
}
with sync_playwright() as p:
browser = p.chromium.launch(proxy=PROXY, headless=True)
page = browser.new_page()
page.goto("https://httpbin.org/ip")
print(page.inner_text("body"))
browser.close()
JIBAO는 게이트웨이에서 HTTP와 SOCKS5를 모두 제공합니다. 브라우저 자동화에는 HTTP 엔드포인트를 사용하세요: Playwright와 Puppeteer는 인증된 SOCKS5 프록시를 지원하지 않으므로, 인증이 있는 HTTP가 신뢰할 수 있는 선택입니다.
const { chromium } = require('playwright');
(async () => {
const browser = await chromium.launch({
headless: true,
proxy: {
server: 'http://gate.jibaoproxy.com:10001',
username: 'USERNAME',
password: 'PASSWORD',
},
});
const page = await browser.newPage();
await page.goto('https://httpbin.org/ip');
console.log(await page.innerText('body'));
await browser.close();
})();
Playwright에서 가장 깔끔하게 로테이션하는 방법은 BrowserContext당 하나의 IP입니다. 각 컨텍스트는 격리된 세션(자체 쿠키와 캐시)이므로, 각각을 서로 다른 출구 IP에 바인딩하면 단일 브라우저 프로세스에서 병렬 신원을 얻을 수 있습니다:
from playwright.sync_api import sync_playwright
def ctx_proxy(session_id):
return {
"server": "http://gate.jibaoproxy.com:10001",
"username": f"USERNAME-session-{session_id}",
"password": "PASSWORD",
}
with sync_playwright() as p:
browser = p.chromium.launch(headless=True)
for i in range(3):
context = browser.new_context(proxy=ctx_proxy(f"ctx{i}"))
page = context.new_page()
page.goto("https://httpbin.org/ip")
print(i, page.inner_text("body"))
context.close()
browser.close()
각 컨텍스트는 고유한 스티키 세션 토큰을 사용하므로 IP가 컨텍스트 내에서는 안정적으로 유지되지만(로그인 흐름에 좋음) 컨텍스트 간에는 다릅니다(여러 계정을 병렬로 운영하기에 좋음). 이것은 GoLogin이나 Dolphin Anty 같은 안티-디텍트 브라우저가 자동화하는 패턴입니다 — 우리의 안티-디텍트 프록시 설정 가이드를 보세요.
Puppeteer는 프록시 서버를 Chromium 실행 플래그로 설정한 다음, 페이지 객체에서 인증합니다:
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch({
headless: 'new',
args: ['--proxy-server=http://gate.jibaoproxy.com:10001'],
});
const page = await browser.newPage();
await page.authenticate({ username: 'USERNAME', password: 'PASSWORD' });
await page.goto('https://httpbin.org/ip');
console.log(await page.evaluate(() => document.body.innerText));
await browser.close();
})();
프록시가 프로세스 수준 플래그이기 때문에 하나의 Puppeteer 브라우저는 하나의 IP를 사용합니다. 로테이션하려면 신원마다 새 브라우저를 실행하거나(더 무거움) 연결마다 IP를 바꾸는 게이트웨이를 통해 로테이션을 구동하세요.
세션 쿠키를 생성하는 모든 흐름은 그 수명 내내 동일한 IP를 유지해야 합니다. IP-A에서 발급된 쿠키가 갑자기 IP-B에서 나타나면 세션 하이재킹으로 읽혀 재인증이나 차단을 유발합니다. 로그인된 계정마다 하나의 컨텍스트(또는 하나의 브라우저)를 유지하고, 전체 세션 동안 하나의 스티키 세션 토큰에 고정하세요.
주거용 IP는 필요조건이지만 충분조건은 아닙니다. 사이트는 브라우저의 TLS/JA4 핸드셰이크, HTTP/2 프레임 순서, canvas, WebGL, navigator 속성도 읽습니다. 기본 헤드리스 Chromium은 navigator.webdriver = true와 헤드리스 핑거프린트를 누출하여 최고의 IP조차 무력화합니다. 스텔스 플러그인과 현실적인 실행 플래그로 완화하세요:
// Node: puppeteer-extra + stealth
const puppeteer = require('puppeteer-extra');
const Stealth = require('puppeteer-extra-plugin-stealth');
puppeteer.use(Stealth());
// Realistic launch flags
const browser = await puppeteer.launch({
headless: 'new',
args: [
'--proxy-server=http://gate.jibaoproxy.com:10001',
'--disable-blink-features=AutomationControlled',
'--window-size=1920,1080',
],
});
어떤 신호를 누출하고 있는지 정확히 보려면, 자동화된 브라우저를 JIBAO의 무료 JA3/JA4 핑거프린트 체커에 돌려보세요. 핸드셰이크가 왜 플래그되는지에 대한 더 깊은 메커니즘은 TLS 핑거프린팅 우회와 완전한 Cloudflare 우회 레시피를 읽어보세요.
headless=False로 설정해 대상이 실제로 봇에게 무엇을 보여주는지 지켜보세요.신규 사용자는 가입 시 500MB를 받고, 첫 충전 시 추가 보너스를 받습니다. 기간 한정 혜택입니다.