웹 스크래핑을 하다 보면 같은 사이트에서 번갈아 로그인이 풀리거나, 장바구니가 비워지거나, 페이지네이션 토큰이 거부되는 현상을 겪게 됩니다. 원인은 대부분 하나입니다 — 매 요청마다 출구 IP가 바뀌기 때문에 서버가 세션 무결성을 위반으로 간주합니다. 이 문제를 해결하려면 고정형 vs 회전형 프록시 세션의 차이를 정확히 이해하고, 각 작업에 맞는 세션 전략을 선택해야 합니다.
고정형 vs 회전형 프록시 세션: 핵심 차이점
두 방식의 본질적인 차이는 출구 IP의 수명 주기에 있습니다:
- 회전형(Rotating) 프록시 세션: 게이트웨이가 매 HTTP 요청마다 새로운 출구 IP를 할당합니다. 1,000개의 요청을 보내면 최대 1,000개의 서로 다른 IP에서 트래픽이 나갑니다. 대량의 공개 데이터를 수집할 때 IP당 요청 빈도를 낮춰 차단을 회피하는 데 적합합니다.
- 고정형(Sticky) 프록시 세션: 하나의 레지덴셜 IP를 지정된 TTL(보통 1분~30분) 동안 고정합니다. 동일한 세션 ID를 사용하는 모든 요청이 같은 IP로 나가므로, 서버는 정상 사용자의 연속 행동으로 인식합니다.
| 구분 | 회전형 세션 | 고정형 세션 |
|---|---|---|
| 출구 IP | 요청마다 변경 | TTL 동안 고정 (1–30분) |
| 세션 상태 유지 | 불가능 | 가능 (쿠키, CSRF, 장바구니) |
| 차단 회피 전략 | IP 분산 | 정상 사용자 행동 모방 |
| 적합한 작업 | 대량 공개 데이터 수집 | 로그인, 결제, 페이지네이션 |
| 동시 세션 수 | 사실상 무제한 | TTL 및 IP 풀에 비례 |
기술적 배경: 왜 세션 고정이 필요한가?
많은 웹사이트는 보안을 위해 세션 상태를 클라이언트의 IP에 바인딩합니다. 즉, 로그인 시 인증 토큰을 발급하고 그 토큰을 최초 인증 IP와 연결합니다. 이후 요청이 다른 IP에서 오면 서버는 세션 하이재킹으로 간주해 토큰을 무효화합니다.
이런 IP 바인딩 세션은 다음 시나리오에서 특히 흔합니다:
- 로그인 인증: 세션 쿠키가 최초 로그인 IP와 검증됩니다.
- CSRF 토큰: 폼 제출 시 토큰이 발급된 IP와 일치해야 합니다.
- 전자상거래 장바구니: 카트 상태가 IP 단위로 관리되는 경우가 많습니다.
- 페이지네이션 토큰: 검색 결과의 다음 페이지 토큰이 원래 요청 IP와 연결됩니다.
예를 들어, 어떤 이커머스 플랫폼에서 상품 목록을 10페이지까지 수집한다고 가정해 봅시다. 1페이지를 요청할 때 서버가 'next_page_token'을 발급하고 이를 요청 IP와 바인딩합니다. 회전형 프록시를 쓰면 2페이지 요청 시 IP가 달라져 토큰이 거부됩니다. 이때는 고정형 세션이 필수입니다.
이러한 동작은 MDN의 쿠키 보안 문서에서 설명하는 Same-Origin 및 IP 기반 검증 메커니즘과 일맥상통하며, 실제로 많은 API가 이 패턴을 따릅니다.
세션 제어 구현: ProxyHat 사용자명 토큰
ProxyHat에서 세션 제어는 프록시 사용자명에 토큰을 추가하는 방식으로 이루어집니다. 별도의 API 호출이나 사전 설정이 필요 없습니다 — 인증 자격증명 안에 모든 제어가 인코딩됩니다.
회전형 세션 (기본값)
세션 토큰 없이 사용자명만 지정하면, 게이트웨이가 매 요청마다 새로운 IP를 할당합니다:
http://user:pass@gate.proxyhat.com:8080
고정형 세션 + 국가 지정
사용자명에 -session- 토큰과 -country- 토큰을 추가하면, 지정된 국가의 레지덴셜 IP가 해당 세션 ID 동안 고정됩니다:
http://user-session-abc123-country-US:pass@gate.proxyhat.com:8080
이 URL로 보내는 모든 요청은 TTL이 만료될 때까지 동일한 미국 레지덴셜 IP를 사용합니다. 세션 ID는 임의의 문자열이며, 새 ID를 생성하면 새 IP가 할당됩니다.
도시 단위 지정
http://user-session-abc123-country-DE-city-berlin:pass@gate.proxyhat.com:8080
베를린 레지덴셜 IP를 세션에 고정합니다. 지역 타겟팅이 필요한 현지화 테스트나 지역별 가격 비교에 유용합니다. 자세한 위치 옵션은 ProxyHat 위치 페이지에서 확인하세요.
실무 코드 예제
Python: 요청별 회전 (Rotating)
대량의 공개 데이터를 수집할 때는 매 요청마다 새 IP를 쓰는 회전형이 적합합니다. requests 라이브러리를 사용한 예제입니다:
import requests
from itertools import cycle
# ProxyHat 회전형 엔드포인트 — 세션 토큰 없음
proxy_url = "http://user:pass@gate.proxyhat.com:8080"
proxies = {
"http": proxy_url,
"https": proxy_url,
}
targets = [
"https://httpbin.org/ip",
"https://httpbin.org/headers",
"https://httpbin.org/user-agent",
]
for url in targets:
resp = requests.get(url, proxies=proxies, timeout=10)
print(f"{url} → {resp.json()}")
# 각 요청마다 다른 출구 IP가 사용됨
이 코드는 세션 토큰을 지정하지 않으므로, 게이트웨이가 각 GET 요청에 대해 새로운 레지덴셜 IP를 할당합니다.
Node.js: 고정형 세션으로 다단계 플로우 유지
로그인 → 상품 조회 → 장바구니 추가 → 결제 페이지 로드 같은 다단계 플로우에서는 같은 IP를 유지해야 합니다. https-proxy-agent를 사용한 예제입니다:
const { HttpsProxyAgent } = require('https-proxy-agent');
// 고정형 세션 — session-abc123으로 IP 고정, 미국 IP 사용
const sessionId = 'order-flow-' + Date.now();
const proxyUrl = `http://user-session-${sessionId}-country-US:pass@gate.proxyhat.com:8080`;
const agent = new HttpsProxyAgent(proxyUrl);
async function runMultiStepFlow() {
// Step 1: 로그인
const loginRes = await fetch('https://example-shop.com/api/login', {
method: 'POST',
agent,
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ user: 'testuser', pass: 'testpass' })
});
const cookies = loginRes.headers.get('set-cookie');
// Step 2: 상품 조회 (같은 IP에서 세션 쿠키 전달)
const productRes = await fetch('https://example-shop.com/api/product/12345', {
agent,
headers: { 'Cookie': cookies }
});
// Step 3: 장바구니 추가 (동일 IP 필수)
const cartRes = await fetch('https://example-shop.com/api/cart/add', {
method: 'POST',
agent,
headers: { 'Cookie': cookies, 'Content-Type': 'application/json' },
body: JSON.stringify({ productId: 12345, qty: 1 })
});
console.log('Cart response:', cartRes.status);
// 모든 단계가 같은 레지덴셜 IP에서 실행됨
}
runMultiStepFlow().catch(console.error);
핵심은 sessionId를 모든 단계에서 동일하게 유지하는 것입니다. ProxyHat 게이트웨이는 같은 세션 ID에 대해 같은 IP를 반환합니다. 자세한 연결 파라미터는 ProxyHat 공식 문서를 참조하세요.
운영 가이드: TTL 튜닝, 세션 재활용, 동시 세션 수
세션 TTL 튜닝
고정형 세션의 TTL은 일반적으로 1분에서 30분 사이입니다. 작업 유형에 따라 적절한 값을 선택해야 합니다:
- 로그인 후 단일 API 호출: 1–5분이면 충분합니다.
- 다단계 결제 플로우: 10–15분을 권장합니다. 결제 단계 사이에 사용자 입력이 있을 수 있기 때문입니다.
- 긴 페이지네이션: 20–30분이 안전합니다. 대량 페이지 수집 중 IP가 바뀌면 처음부터 다시 시작해야 할 수 있습니다.
TTL이 만료되면 세션 ID가 더 이상 유효하지 않으므로, 새 세션 ID를 생성해 새 IP를 할당받아야 합니다.
429/403 발생 시 세션 재활용
고정형 세션을 사용 중 HTTP 429(Too Many Requests) 또는 403(Forbidden)를 받으면, 해당 IP가 대상 사이트에 의해 제한되었을 가능성이 높습니다. 이때는:
- 현재 세션 ID를 폐기합니다.
- 새 세션 ID를 생성해 새 IP를 할당받습니다.
- 요청 빈도를 10–20% 낮춘 후 재시도합니다.
이 전략은 웹 스크래핑 사용 사례 페이지에서 더 자세한 회복 패턴을 확인할 수 있습니다.
동시 세션 수 가이드
동시 고정형 세션 수는 대상 사이트의 rate limit과 ProxyHat 플랜의 동시 연결 한도에 의해 결정됩니다. 일반적인 가이드라인:
- 단일 도메인: 동시 세션 10–20개를 넘지 마세요. 같은 도메인에 너무 많은 IP가 동시 접속하면 패턴이 감지됩니다.
- 다중 도메인: 도메인당 10–20개 세션을 유지하면서 전체 50–100개 동시 세션까지 확장할 수 있습니다.
- 요청 간격: 각 세션당 초당 1–3 요청을 넘기지 않는 것이 안전합니다.
예를 들어, 5개 도메인에서 각각 15개 세션을 운영하면 총 75개 동시 세션이 필요합니다. ProxyHat 요금제에서 필요한 동시 세션 수를 지원하는 플랜을 선택하세요.
회전형이 고정형보다 유리한 경우
모든 작업에 고정형이 필요한 것은 아닙니다. 다음 시나리오에서는 회전형이 명확히 우위입니다:
- SERP 스크래핑: Google, Bing 검색 결과를 수집할 때는 IP당 1–2개 요청만 보내면 되므로 회전형이 효율적입니다. SERP 추적 사용 사례에서 자세한 전략을 확인하세요.
- 공개 페이지 대량 수집: 로그인이 필요 없는 공개 상품 페이지, 뉴스 기사, 블로그 포스트 등을 수집할 때는 세션 상태가 필요 없으므로 회전형으로 충분합니다.
- IP당 요청 한도가 낮은 사이트: 단일 IP당 시간당 10개 요청만 허용하는 사이트에서 10,000개 페이지를 수집하려면 회전형이 유일한 방법입니다.
반대로, 다음 시나리오에서는 고정형이 필수입니다:
- 로그인이 필요한 페이지 수집
- 장바구니 또는 위시리스트 조작
- 페이지네이션 토큰이 IP에 바인딩된 API
- 결제 또는 예약 플로우 자동화
법적 고려사항
프록시 세션 전략과 무관하게, 웹 스크래핑에는 법적 리스크가 따릅니다. 미국에서는 Computer Fraud and Abuse Act (CFAA)가 무단 접근을 규제하며, 유럽에서는 GDPR이 개인정보 보호를 요구합니다.
실무 권장사항:
- 대상 사이트의
robots.txt와 이용약관(ToS)을 확인하세요. - 개인정보(PII)를 수집하는 경우 GDPR/CCPA 적용 여부를 검토하세요.
- 인증이 필요한 페이지를 스크래핑할 때는 특히 주의하세요 — 일부 사이트는 이를 명시적으로 금지합니다.
- 요청 빈도를 합리적으로 유지하여 대상 서버에 부하를 주지 마세요.
프록시는 기술적 도구일 뿐, 법적 면책 사유가 아닙니다. 모든 스크래핑 활동은 해당 관할권의 법률과 대상 사이트의 이용약관을 준수해야 합니다.
핵심 요약
- 회전형 세션은 매 요청마다 새 IP를 할당하여 대량 공개 데이터 수집에 적합합니다.
- 고정형 세션은 하나의 IP를 TTL 동안 유지하여 로그인, 장바구니, 페이지네이션 등 상태 기반 작업에 필수입니다.
- ProxyHat에서는 사용자명에
-session-ID토큰을 추가하는 것만으로 고정형 세션을 활성화할 수 있습니다. -country-US와-city-berlin토큰으로 지역 타겟팅을 함께 제어할 수 있습니다.- 429/403 응답 시 세션 ID를 교체하고 요청 빈도를 낮추세요.
- 단일 도메인당 동시 세션은 10–20개를 유지하고, 요청 간격은 초당 1–3회를 넘지 마세요.
- 공개 데이터 대량 수집에는 회전형을, 상태 기반 플로우에는 고정형을 선택하세요.






