로테이팅 레지덴셜 프록시는 규모를 위해 만들어졌다. 요청마다 새로운 IP를 쓰거나, 최대 30분까지 유지되는 고정 세션을 쓴다. 그런데 이것은 전혀 다른 종류의 작업에는 정확히 맞지 않는다. 하루 종일 계정에 로그인된 상태를 유지하거나, 결제나 모니터링 세션을 몇 시간 동안 끊기지 않게 유지하거나, 매번 같은 위치에서 스토어의 판매자 계정을 관리하는 경우다. 이런 경우 사이트는 하나의 일관된 방문자를 기대하며, IP가 바뀌면 탈취된 세션처럼 보인다.
ISP 프록시는 바로 이런 용도로 만들어졌다. 각 프록시는 전체 결제 기간 동안 사용자가 선택한 도시와 인터넷 제공업체에 그대로 머문다. 하지만 좋은 프록시만으로는 설정의 절반밖에 되지 않는다. 나머지 절반은 세션의 다른 모든 요소도 똑같이 일관되게 유지하는 것이다. 이 가이드는 고객들에게 권장하는 설정 방법을 코드와 함께 다룬다.
로테이팅 대신 ISP 프록시가 필요한 경우
| 작업 내용 | 사용할 것 |
|---|---|
| 여러 사이트에서 많은 페이지를 수집하는 작업 | 로테이팅 레지덴셜 프록시 |
| 30분 이내에 끝나는 다단계 플로우 | 레지덴셜 고정 세션 |
| 몇 시간 동안 지속되어야 하는 세션 | ISP 프록시 |
| 매일 자신의 계정에 로그인 상태 유지 | ISP 프록시 |
| 특정 도시와 제공업체에서 사이트가 어떻게 보이는지 확인 | ISP 프록시 |
30분이라는 기준이 실질적인 경계선이다. Shifter의 레지덴셜 고정 세션은 최대 30분까지 지속된다. 그보다 길거나, 내일 다시 같은 계정으로 돌아와야 하는 작업이라면 ISP 프록시를 사용해야 한다.
Shifter의 ISP 프록시 작동 방식
- 배치한 모든 IP는 고유한 사용자명을 가지며, 플랜 내 모든 사용자명은 하나의 비밀번호를 공유한다.
- 모든 프록시는 동일한 호스트와 포트인
isp.shifter.io:443을 통해 HTTP(S) 또는 SOCKS5로 연결된다. - 각 IP를 배치할 때 **도시와 ISP(ASN)**를 120개국 중에서 선택한다.
- 각 프록시는 플랜이 활성화되어 있는 동안 해당 도시와 ISP를 유지한다.
- 뒤에 있는 IP 주소는 시간이 지나면서 갱신될 수 있다. 가정용 광대역 인터넷이 가끔 제공업체로부터 새 주소를 받는 것과 같은 방식이다. 도시와 제공업체는 동일하게 유지된다.
- 대역폭은 무제한이며, 플랜은 IP당 가격이 책정된다.
마지막에서 두 번째 항목은 지속적인 로그인에 중요하다. 설정은 주소가 가끔 바뀔 수 있다는 점을 전제하고, 변하지 않는 것, 즉 위치, 제공업체, 브라우저 프로필에 의존해야 한다.
다섯 가지 설정 원칙
1. 계정당 하나의 프록시, 절대 공유하지 않는다. 모든 계정에 각자의 ISP 프록시 사용자명을 부여하고 그 짝을 고정시켜라. 한 IP에 두 계정이 있으면 연결된 것처럼 보이고, 한 계정이 여러 IP를 거치면 서로 다른 장소에서 접근하는 것처럼 보인다.
2. 각 IP를 계정이 실제로 존재하는 곳에 배치한다. 계정이 시카고에 있는 스토어에 속한다면, 그 IP는 시카고의 제공업체에 배치하라. 올바른 도시와 레지덴셜 제공업체에서의 로그인은 계정의 평소 패턴처럼 보인다.
3. 계정별로 지속적인 브라우저 프로필을 유지한다. 쿠키, 로컬 스토리지, 저장된 세션이 로그인 상태를 유지시켜준다. 계정별 프로필 디렉터리에 저장하고 매번 재사용하라. 실행할 때마다 새 브라우저를 쓰면 매번 새로운 로그인이 되는데, 이것이 바로 인증 요청을 유발하는 원인이다.
4. 브라우저가 프록시와 일치하도록 만든다. 시간대와 언어는 출구의 위치와 일치해야 한다. 가장 간단한 방법은 출구에 위치를 물어본 뒤 그 응답으로 브라우저를 설정하는 것이다. 프록시 지역, 시간대, 로케일 일치시키기 가이드에서 전체 신호 목록을 다룬다.
5. 시작하기 전에 출구를 확인한다. 계정을 열기 전에 프록시가 예상된 도시와 예상된 제공업체에 있는지 확인하라. 그렇지 않다면 잘못된 장소에서 로그인하는 대신 중단하라.
코드
아래 모듈은 Python과 Playwright로 다섯 가지 원칙을 실제로 구현한다. 계정-프록시 매핑을 검증하고, ip-info.com(무료 IP 지리위치 API)을 통해 출구를 확인하며, 출구 자체에서 가져온 시간대로 해당 계정의 프록시에 고정된 지속 브라우저 프로필을 연다.
from pathlib import Path
import requests
ISP_GATEWAY = "isp.shifter.io:443"
def validate_assignments(accounts):
"""One ISP proxy per account, and no proxy shared between accounts."""
problems, seen_accounts, owner = [], set(), {}
for a in accounts:
if a["account"] in seen_accounts:
problems.append(f"{a['account']}: listed twice")
seen_accounts.add(a["account"])
other = owner.setdefault(a["isp_username"], a["account"])
if other != a["account"]:
problems.append(f"{a['isp_username']}: shared by {other} and {a['account']}")
return problems
def check_exit(account, password, get=requests.get):
"""Ask the exit where it is, and compare with where this account belongs."""
proxy = f"http://{account['isp_username']}:{password}@{ISP_GATEWAY}"
info = get("http://ip-info.com/json", proxies={"http": proxy, "https": proxy}, timeout=20).json()
problems = []
if info.get("city") != account["city"]:
problems.append(f"city is {info.get('city')}, expected {account['city']}")
if info.get("asn") != account["asn"]:
problems.append(f"ASN is {info.get('asn')}, expected {account['asn']}")
return {"ip": info.get("ip"), "timezone": info.get("timezone"), "problems": problems}
def browser_options(account, password, exit_info, profile_root):
"""Persistent Chromium profile for one account, pinned to its own ISP proxy."""
return {
"user_data_dir": str(Path(profile_root) / account["account"]),
"proxy": {"server": f"http://{ISP_GATEWAY}",
"username": account["isp_username"], "password": password},
"timezone_id": exit_info["timezone"],
"locale": account["locale"],
"viewport": {"width": 1440, "height": 900},
}
def open_account(playwright, account, password, profile_root="profiles"):
"""Check the exit first; only then open the account's own browser profile."""
exit_info = check_exit(account, password)
if exit_info["problems"]:
raise RuntimeError(f"{account['account']}: " + "; ".join(exit_info["problems"]))
options = browser_options(account, password, exit_info, profile_root)
return playwright.chromium.launch_persistent_context(**options)
사용 예:
import os
from playwright.sync_api import sync_playwright
from isp_sessions import open_account, validate_assignments
ACCOUNTS = [
{"account": "store-us", "isp_username": "us-chicago-illinois-as7922-XXXXX",
"city": "Chicago", "asn": 7922, "locale": "en-US"},
{"account": "store-de", "isp_username": "de-berlin-berlin-as3320-XXXXX",
"city": "Berlin", "asn": 3320, "locale": "de-DE"},
]
password = os.environ["ISP_PASSWORD"]
problems = validate_assignments(ACCOUNTS)
if problems:
raise SystemExit("\n".join(problems))
with sync_playwright() as p:
browser = open_account(p, ACCOUNTS[0], password)
page = browser.pages[0] if browser.pages else browser.new_page()
page.goto("https://example.com/account")
# ... the account's work; cookies and storage persist in profiles/store-us
browser.close()
XXXXX 접미사는 플랜 페이지에 나와 있는 사용자명으로 교체하라. 이 페이지에는 모든 사용자명이 도시와 ISP와 함께 나열되어 있다. 이 예시에서 profiles/store-us인 프로필 디렉터리는 실행 사이에 계정의 로그인 상태를 유지시켜주는 핵심이다. 반드시 백업하고, 절대 두 계정이 같은 프로필을 가리키게 하지 마라.
매핑 검사, 출구 검사(기록된 응답 대상), 그리고 Playwright의 Chromium을 이용한 브라우저 옵션을 테스트했다. 출구 검사는 실제 프록시를 대상으로 실행하려면 활성화된 ISP 플랜이 필요하다.
세션을 몇 시간 동안 유지하기
- 꾸준하고 사람다운 속도를 유지한다. 사람이 계정을 사용할 때는 클릭하고, 읽고, 기다린다. 분당 수백 건의 액션이 폭주하면 프록시가 아무리 좋아도 자동화된 것처럼 보인다.
- 열려 있는 브라우저를 재사용한다. 작업마다 브라우저를 다시 실행하는 대신, 작업 세션이 지속되는 동안 하나의 브라우저를 열어 두어라.
- 긴 휴지기 후에는 출구를 다시 확인한다. 몇 시간 뒤에 작업을 재개한다면 출구 검사를 다시 실행하라. 주소가 갱신될 수 있으므로, 사이트가 가끔 로그인 확인을 요청할 수 있다. 동일한 도시, 제공업체, 프로필을 유지한다면 이는 실제 사용자가 가정용 라우터가 재시작된 후 겪는 경험과 같다.
- 문제를 해결하겠다고 계정을 다른 프록시로 바꾸지 마라. 계정이 챌린지를 받았을 때 다른 도시나 제공업체로 바꾸면 상황이 더 나빠진다. 원인을 해결하고 짝은 그대로 유지하라.
문제 해결
| 증상 | 가능한 원인 | 해결 방법 |
|---|---|---|
407 Proxy Authentication Required | 잘못된 사용자명 또는 비밀번호 | 플랜 페이지에서 자격 증명을 다시 복사하라. 각 IP는 고유한 사용자명을 가진다 |
| 출구 검사에서 잘못된 도시가 표시됨 | 사용자명이 다른 배치에 속함 | 플랜 페이지의 목록과 사용자명을 대조하라 |
| 매 실행마다 로그아웃됨 | 매번 새로운 브라우저 프로필 사용 | 계정별 지속 프로필 디렉터리를 사용하라 |
| 반복적인 인증 요청 | 시간대나 언어가 출구와 일치하지 않거나, 계정이 프록시 간에 옮겨짐 | 출구의 위치에서 브라우저를 설정하고 계정당 하나의 프록시를 유지하라 |
| 특정 IP에서 요청이 느리거나 실패함 | 해당 배치의 문제 | 문서에 있는 연결 확인을 실행하고 해당 사용자명과 함께 지원팀에 문의하라 |
계정을 책임감 있게 사용하는 것에 대한 참고
이러한 기법들은 사용할 권한이 있는 계정, 즉 자신의 비즈니스 계정, 허락을 받은 고객의 계정, 자체 서비스의 테스트 계정을 위한 것이다. 모든 플랫폼에는 자동화와 한 사람 또는 기업이 운영할 수 있는 계정 수에 대한 자체 규칙이 있다. 일관된 설정은 정당한 작업이 플래그되지 않도록 지켜주는 것이지, 플랫폼의 규칙을 우회하는 수단이 아니며 그런 용도로 사용해서는 안 된다.
FAQ
긴 세션에 로테이팅 레지덴셜 프록시를 사용할 수 있나요?
어느 정도까지만 가능하다. Shifter의 레지덴셜 고정 세션은 최대 30분까지 지속된다. 그보다 오래 걸리는 세션이나 매일 다시 돌아오는 로그인의 경우, 전체 결제 기간 동안 도시와 ISP를 유지하는 ISP 프록시를 사용하라.
ISP 프록시의 IP 주소도 바뀌나요?
플랜이 활성화되어 있는 동안 도시와 ISP는 고정되어 있다. 프록시 뒤의 IP 주소는 가정용 광대역 인터넷처럼 시간이 지나면서 갱신될 수 있다. 설정은 변하지 않는 요소인 위치, 제공업체, 지속 브라우저 프로필을 중심으로 구성하라.
하나의 ISP 프록시를 몇 개의 계정이 공유해야 하나요?
하나다. 각 계정에 자체 프록시를 부여해서 각각이 별개의 가정처럼 보이게 하고 어떤 두 계정도 연결된 것처럼 보이지 않게 하라.
지속적인 브라우저 프로필이 필요한가요?
로그인의 경우 그렇다. 프로필은 로그인 상태를 유지시켜주는 쿠키와 스토리지를 담고 있다. 프로필이 없으면 매 실행마다 새로운 기기로 시작하게 되어 인증 요청을 받을 가능성이 훨씬 높아진다.
결론
긴 세션과 지속적인 로그인에는 로테이션이 아니라 일관성이 필요하다. 각 계정에 그 계정이 실제로 존재하는 도시에 배치한 자체 ISP 프록시를 부여하고, 계정별로 지속적인 브라우저 프로필을 유지하고, 브라우저의 시간대와 언어를 출구를 기준으로 설정하고, 시작하기 전마다 출구를 확인하라. 이것들이 갖춰지면 계정은 매일 똑같이 보이게 되는데, 이것이 바로 사이트가 확인하려는 전부다. ISP 프록시와 레지덴셜 프록시 비교 글에서 두 방식 간의 더 폭넓은 선택지를 다룬다.