四月初,微博和小红书几乎同时收紧了设备指纹校验——同一条Cookie在几十秒内从十几个不同城市的IP发起请求,会被直接判定为账号异常。这条规则基本废掉了过去两年做SEO排名追踪和舆情监控的默认打法:每请求一换IP。我手上那个监控12个社媒平台的舆情项目,3月28日到4月2日五天里,48个采集节点的平均可用率从99.1%掉到87.4%,验证码弹窗率翻了四倍。
每请求一换IP,为什么反而更快被封
很多人对风控的理解还停留在"单个IP请求次数太多"这个层面,于是把轮换粒度调到最细,以为IP越分散越安全。实际校验逻辑恰恰相反:平台看的是一个会话的身份是否自洽——IP归属地、User-Agent、时区、Accept-Language、Cookie里的登录地,这几项要能互相解释得通。
每请求一换IP意味着同一个登录态在60秒内出现在30个城市,风控模型里这就是典型的账号共享特征。我一开始判断是IP池质量下滑,连续换了第二家、第三家供应商,可用率纹丝不动,才回头去翻轮换日志,发现根因根本不在IP质量。
| 轮换粒度 | 单IP平均请求数 | 可用率 | 验证码触发率 |
|---|
| 每请求轮换 | 1.0 | 87.4% | 12.6% |
| 30秒粘性 | 8.2 | 96.3% | 3.2% |
| 5分钟粘性 | 61.4 | 99.2% | 0.9% |
| 30分钟粘性 | 340.7 | 99.6% | 0.7% |
数据是同一批关键词、同一时间段跑出来的。拐点出现在3到5分钟之间,再往上走可用率提升不到0.5个百分点,但单IP请求量堆到340次之后,被限流(返回空结果而非封禁)的概率明显上升,这种软性降级比硬封更难排查。
粘性会话的三种落地方式,参数怎么填
知道了要粘,接下来是选接入方式。目前主流的三种,会话控制粒度差别很大:
- API提取:每次返回一批IP,每条带过期时间(常见1到5分钟),需要自建池和失效剔除逻辑
- 隧道代理:在用户名或请求头里带session ID,同一个ID固定走同一出口,到期自动切换
- 账密认证+白名单:出口完全固定,适合按地域长期作业的少量任务
隧道代理在舆情监控这种场景里最省事,因为会话切换由服务端兜底,客户端只需要管好sid的存活周期:
import requests, time
TUNNEL = 'http://user-session-{sid}:pwd@tunnel.example.com:8000'
def fetch(url, sid, retry=3):
proxies = {'http': TUNNEL.format(sid=sid),
'https': TUNNEL.format(sid=sid)}
for i in range(retry):
try:
r = requests.get(url, proxies=proxies, timeout=8)
if r.status_code == 200:
return r.text
if r.status_code in (403, 429):
time.sleep(2 ** i) # 指数退避,别硬刚
except requests.RequestException:
time.sleep(0.5)
return None
关键点在于sid的续期策略:我在本地维护一个sid到时间的映射,满4分钟才换新sid,中间所有请求复用,而不是让每次requests调用随机取出口。同一个sid下的并发控制在8以内,再多就会因为出口带宽争抢导致超时误判。
7×24场景真正难的是何时主动放弃一个出口
舆情监控和一次性采集最大的区别是:它要连跑几个月,某个出口今天能用不代表明天能用,靠人工看日志根本不现实。所以调度器必须自己判断健康度,用滑动窗口而不是累计计数,因为累计值会被历史成功稀释掉近期的恶化。
from collections import deque
win = deque(maxlen=50) # 每个sid保留最近50次结果
def healthy(win, floor=0.85):
if len(win) < 10:
return True # 样本不足不判死,避免误杀
return sum(win) / len(win) >= floor
阈值我定在0.85,低于就熔断,冷却60秒后重新探测。样本量小于10不判定,这条是踩过坑加上去的——凌晨时段请求稀疏,新sid头几次恰好失败就被判死,反而把可用节点耗光了。
实测结论与选型边界
把轮换粒度调到4分钟、单sid并发8、失败两次换sid之后,同一个舆情平台连续跑了7天:可用率99.7%,验证码触发率0.6%,日均请求46万次,没有再出现批量降级。成本上,隧道代理按天计费比按IP计费更可控,我用的方案是16元/天起,出口城市覆盖对我的地域舆情分析够用,需要的话可以在mayihttp.com查具体节点分布。
说清楚边界:这套配置适合日均百万请求以内的团队。如果你的量级到千万级,按天计费的隧道就明显不划算了,得回到API提取自建池,用本地调度换成本,代价是你得自己写失效剔除和扩容逻辑,那又是另一个工程量。
最后一句不太专业的提醒:别信"轮换越快越安全"这句话。我在同一个项目上验证了三次,结论都是反的——风控追的是会话一致性,不是IP数量。