빠른 답변
레지덴셜 프록시에서 스티키 세션과 IP 회전은 어떻게 작동하나요?
CrawlRelay에서 세션 ID 없는 사용자명은 보통 새 TCP 연결 시마다 다른 풀 내 IP를 받고, -session-<id>-ttl-<minutes>는 그 ID에 대해 최대 30분 동안 한 IP를 유지하지만 조기 변경될 수 있습니다. 회전은 HTTP 요청이 아닌 연결에 따라 이뤄지므로 유지 연결이 실제 IP 변경 시점을 결정합니다. 레지덴셜 트래픽은 50 GB부터 US$0.50/GB에 의해 과금됩니다. 암호화폐로 결제하며, KYC 없이 이용 가능합니다.
세션 규칙 요약
| 회전 단위 | 새로운 TCP 연결별로 풀에서 IP 할당, 보통은 다른 IP |
|---|---|
| 스티키 세션 | 사용자명 끝에 -session-<id>-ttl-<minutes> 추가 |
| 세션 길이 | 최대 30분 |
| 세션 ID | 1~32자 영숫자; 흐름당 하나의 ID |
| 세션이 조기 종료되는 이유 | 배후 레지덴셜 장치가 오프라인 상태일 때 |
| 공유 ID | 동일한 ID를 보내는 클라이언트는 동일한 출구를 공유합니다 |
| 비용 | 없음: 세션 및 회전은 GB당 요금에 포함되어 있습니다 |
세션 ID를 보낼 때 게이트웨이에서 무슨 일이 일어나나요?
게이트웨이는 각 새로운 연결에서 사용자 이름을 읽습니다. 세션 부분이 없으면 해당 연결에 대해 타겟팅에 맞는 레지덴셜 프록시 출구를 선택합니다. 세션 부분이 있으면 설정한 TTL 동안 해당 ID에 대해 동일한 출구를 유지합니다.
스티키 IP는 실제 가정용 연결이므로 TTL이 끝나기 전에 사라질 수 있습니다: 기기가 꺼지거나 Wi-Fi를 잃거나 네트워크를 변경하는 경우입니다. 긴 흐름은 출구 IP를 체크포인트에서 확인하고 전체 작업 실패 대신 체크포인트에서 다시 시작하여 이를 견뎌야 합니다.
각 라이브러리가 연결을 재사용하는 방법은?
라이브러리가 연결을 유지하면 그 연결의 모든 요청이 하나의 출구를 공유합니다. 이것이 각 동작을 의도적으로 얻는 방법입니다.
| 라이브러리 | 기본값 | 요청마다 새로운 IP | 흐름 당 하나의 IP |
|---|---|---|---|
| Python requests | Session는 연결을 유지합니다 | 헤더 Connection: close, 또는 요청 당 새 Session | 사용자 이름에 세션 ID가 포함된 하나의 Session |
| httpx | 클라이언트가 연결을 풀링합니다 | httpx.Limits(max_keepalive_connections=0) | 세션 ID 당 하나의 클라이언트 |
| aiohttp | TCPConnector는 연결을 풀링합니다 | TCPConnector(force_close=True) | 프록시 URL 사용자 이름에 세션 ID 포함 |
| Scrapy | 프록시 자격 증명 및 호스트별 풀링 | 우리의 미들웨어와 함께하는 meta={"proxy_session": "new"} | 흐름에 고정된 proxy_session |
| Playwright / Puppeteer | Chrome은 컨텍스트 별로 풀링 | 페이지 당 새 컨텍스트 | 세션 ID 당 하나의 컨텍스트 |
| Node.js undici, axios, got | 에이전트는 소켓을 유지합니다 | 요청 당 새 에이전트 또는 keep-alive 끔 | 세션 ID 당 하나의 에이전트 |
| curl | 명령 당 하나의 연결 | 이미 그런 경우입니다 | 각 명령에 동일한 세션 ID |
어떤 세션 전략이 어떤 스크래핑 작업에 적합한가요?
| 작업 | 전략 | 추천 TTL |
|---|---|---|
| 독립형 제품, 기사 또는 목록 페이지 | 회전: 세션 ID 없음 | — |
| 다음 페이지가 쿠키 또는 커서에 의존하는 페이징 | 리스팅 당 하나의 고정 세션 | 10–30분 |
| 검색 → 결과 → 상세 페이지 | 검색 당 하나의 고정 세션 | 10–20분 |
| 한 사이트의 여러 페이지를 헤드리스 브라우저로 렌더링 | 브라우저 컨텍스트 당 하나의 고정 세션 | 컨텍스트 수명, 최대 30분 |
| 여러 도시에서 페이지 표시 내용 확인 | 도시별 단기 세션 하나 | 5분 |
| 매 시간 동일 페이지 재검토 | 회전 | — |
Python에서 고정 세션 풀을 어떻게 관리하나요?
소규모 풀은 몇 개의 안정적인 레지덴셜 프록시로 부하를 분산하며, 502 또는 503 같은 오류 발생 시나 설정된 요청 수 후에 해당 출구를 교체합니다. 하지 않는 것: 403이나 429를 우회하려고 IP를 교체하지 않습니다. 이는 사이트가 속도를 줄이길 원한다는 신호이므로, 풀이 그걸 코드에 전달합니다.
import random
import uuid
import requests
GATEWAY = "gw.crawlrelay.com:7777"
BASE_USER, PASSWORD = "USERNAME-country-us", "PASSWORD"
class SlowDown(Exception):
"""The target asked us to slow down (403 or 429): back off, do not rotate."""
class StickySession:
def __init__(self, ttl=15, max_requests=50):
self.id = uuid.uuid4().hex[:10]
self.max_requests, self.used = max_requests, 0
user = "%s-session-%s-ttl-%d" % (BASE_USER, self.id, ttl)
proxy = "http://%s:%s@%s" % (user, PASSWORD, GATEWAY)
self.http = requests.Session()
self.http.proxies = {"http": proxy, "https": proxy}
class SessionPool:
EXIT_PROBLEMS = {502, 503, 504}
def __init__(self, size=5, **options):
self.options = options
self.sessions = [StickySession(**options) for _ in range(size)]
def _replace(self, i):
self.sessions[i].http.close()
self.sessions[i] = StickySession(**self.options)
def get(self, url, **kwargs):
i = random.randrange(len(self.sessions))
s = self.sessions[i]
s.used += 1
try:
r = s.http.get(url, timeout=(10, 30), **kwargs)
except requests.exceptions.RequestException:
self._replace(i) # dropped exit or timeout: start a fresh session
raise
if r.status_code in (403, 429):
raise SlowDown("%s returned %d" % (url, r.status_code))
if r.status_code in self.EXIT_PROBLEMS or s.used >= s.max_requests:
self._replace(i)
return r
pool = SessionPool(size=5, ttl=15, max_requests=50)
print(pool.get("https://api.ipify.org").text)고정 IP가 변경되었는지 어떻게 알죠?
세션 흐름 시작과 각 체크포인트에서 https://api.ipify.org 같은 IP 에코 서비스를 요청해 결과를 비교하세요. 변경되면 세션 뒤의 출구가 바뀐 것입니다: 마지막 체크포인트부터 흐름을 재시작하거나 새 세션을 여세요. 세션 ID와 함께 기록해, 디버깅 시 IP 변경과 사이트 행동을 구분할 수 있습니다.
어떤 세션 실수가 가장 큰 비용을 초래하나요?
- 다단계 과정의 매 요청마다 회전하기: 사이트가 카트, 커서, 검색 토큰이 국가 간에 바뀌는 것을 감지해 초기화합니다.
- 모든 작업자에 세션 ID 하나만 사용하기: 세션은 하나의 흐름용이며, 각 작업자와 흐름에 고유 ID를 부여해야 합니다.
- 작업 시간보다 훨씬 긴 세션 유지: 2분 작업에 30분 TTL은 IP를 불필요하게 점유하고 로그 해석을 어렵게 만듭니다.
- 429 오류를 IP 문제로 오해하기: 새 IP 변경으로 사이트 규칙이 바뀌지 않습니다; 속도 조절이 필요합니다. 429 Too Many Requests 참조]
- 요청마다 회전한다는 가정: Keep-alive가 출구를 유지하므로 사용 라이브러리 문서를 참고하세요.
세션과 회전에 관한 질문들
고정 세션은 얼마나 지속되나요?
스티키 세션은 설정한 시간(ttl, 분 단위) 동안 동일한 IP를 유지하며 최대 30분까지 가능합니다. 예를 들어 레지덴셜 장치가 오프라인 되면 IP가 더 빨리 변경될 수 있습니다.. 작업 흐름보다 약간 긴 TTL을 선택하고 체크포인트에서 출구를 확인하세요.
고정 세션이 회전보다 비용이 더 드나요?
아니요. CrawlRelay는 GB 단위 트래픽 과금이며, 세션, 회전, 타깃팅이 모두 포함되어 있습니다. 고정 세션은 연결을 유지해 매 요청마다 TLS 핸드셰이크가 필요 없으므로 트래픽 절약도 가능합니다.
매 요청마다 IP를 회전하는 것이 스크래핑에 더 좋나요?
독립적인 페이지일 경우 회전이 부하를 분산하고 같은 IP로 오랜 시간 사이트 접근을 피합니다. 쿠키 기반 페이지네이션 등 상태가 필요한 경우 흐름이 깨집니다. 대부분 크롤링은 둘을 혼합: 아이템 간 회전, 흐름 내 고정.
정확한 IP를 선택할 수 있나요?
아니요. 레지덴셜 게이트웨이는 항상 변하는 풀에서 출구를 할당하며 이름(username) 타깃팅에 맞게 배정합니다. 국가, 도시, 미국 주, 우편번호, ASN은 선택 가능하며 세션으로 IP 고정은 가능하지만 특정 주소 예약은 불가합니다.
회전과 세션은 모든 요금제에 포함
US$1.50는 1 GB용, US$0.50/GB는 50 GB에서 제공합니다.