粘性会话与轮换
session 和 time 参数的准确语义、会话绑定到底绑了什么,以及轮换模式的真实行为。
两种模式:带 session + time 是粘性,不带就是轮换。这一篇要把它们实际保证了什么说清楚——这里的措辞差别会直接影响你的方案能不能跑。
粘性会话
curl -x 'http://USERNAME-country-US-session-job1-time-30:PASSWORD@GATEWAY_HOST:58971' \
https://api.ipify.org
1–64 字节,只允许 ASCII 字母、数字、.、-。
大小写敏感:Job1 和 job1 是两个独立会话。
单位分钟,取值 1–120。
会话与出口 IP
同一代理账号使用相同的 session 值和筛选条件时,通常会在指定时长内保持同一个出口 IP。住宅设备可能离线,因此粘性会话不保证 IP 永久不变。
相同 session 值搭配不同操作系统时,会分别使用独立会话。例如,session-job1 搭配 os-ios、os-windows 或不指定 OS,分别视为独立会话。
会话何时生效
会话在首次成功建立代理连接后生效。首次连接失败时,会话尚未开始计时,可以稍后重试。
会话过期与连接失败
会话到期后,下一次新连接会重新分配符合筛选条件的出口 IP,结果可能与之前相同。
有效会话暂时无法连接时,请求会返回错误。暂不可用为 503 service_unavailable,连接失败为 502,超时为 504。可以有限重试,或使用新的 session 值创建会话。已有 TCP 连接不会因为会话到期而自动断开。
会话时长
time 支持 1–120 分钟。根据实际操作所需时间设置即可;如果流程只需要几分钟,无需设置为 120 分钟。
轮换模式
不带 session 就是轮换:
curl -x 'http://USERNAME-country-US:PASSWORD@GATEWAY_HOST:58971' https://api.ipify.org
每个新 TCP 连接重新分配符合筛选条件的出口 IP,分配结果可能重复。
怎么强制新连接
各语言里的做法:
import requests
proxy = "http://USERNAME-country-US:PASSWORD@GATEWAY_HOST:58971"
proxies = {"http": proxy, "https": proxy}
# 每次用新 Session(新连接池)
for _ in range(5):
with requests.Session() as session:
print(session.get("https://api.ipify.org",
proxies=proxies, timeout=30).text)
# 或者在同一个 Session 上禁用 keep-alive
headers = {"Connection": "close"}
用不同 session 值做并发隔离
需要同时跑多个互不干扰的会话时,给每条用不同的 session 值:
import concurrent.futures
import requests
def fetch(worker_id: int) -> str:
user = f"USERNAME-country-US-session-w{worker_id}-time-30"
proxy = f"http://{user}:PASSWORD@GATEWAY_HOST:58971"
return requests.get(
"https://api.ipify.org",
proxies={"http": proxy, "https": proxy},
timeout=30,
).text
with concurrent.futures.ThreadPoolExecutor(max_workers=8) as pool:
for ip in pool.map(fetch, range(8)):
print(ip)
八个 worker 各有独立的会话,各自拿到不同的出口 IP 并在 30 分钟内保持。
怎么选
| 场景 | 模式 |
|---|---|
| 登录 → 翻页 → 提交的多步流程 | 粘性,time 覆盖整个流程时长 |
| 列表页大规模翻页采集 | 轮换 |
| 需要同 IP 但只有几分钟 | 粘性,time 按实际需要设置 |
| 账号必须一直同 IP | 换静态住宅,不要用粘性会话 |
| 并发多任务互不干扰 | 粘性 + 每任务不同 session 值 |