去年Q4,一个广告验证平台的客户把需求甩过来:每天要校验 800万次 广告位的落地页展示,覆盖全国340个城市,每个城市至少200个样本点。核心要求只有一条——IP必须真落在目标城市,否则整份投放效果报告就是废纸。
我当时的判断是:这不就是个带地域定向的采集任务吗。三周之后我推翻了这个判断。下面三个坑,每一个都让我重跑过数据。
坑一:接口说IP在上海,出口在杭州
第一版方案我用的是某家动态短效代理。提取接口返回的字段写得清清楚楚:“上海电信”。跑了两周,客户的风控同事找上门:上海地区的验证结果和杭州高度重合,两组数据的相关系数 0.93。
拆开看根因:接口给的归属地来自IP库,记录的是IP的注册分配地,不等于实际出口机房的位置。运营商做省级出口池化和动态重分配之后,一批“上海IP”实际是从江苏、浙江的节点出去的。这种事在本地测一百次都测不出来,因为你的探测请求本身也在同一个出口上。
def pick_ip(city, pool):
for _ in range(5):
ip = pool.get(city)
if probe_city(ip) == city: # 出口探测,非IP库查询
return ip
return None
- 双端校验:请求前用第三方出口探测接口确认真实城市,不匹配就丢弃重取,实测丢弃率约 7%;
- 每个城市维护独立IP队列,不要从“全国池”里随机取;
- 每小时从每个城市抽20个IP跑一次探针,准确率低于96%就告警。
坑二:脏IP让平台返回降级素材
第二个坑更隐蔽。广告平台的反作弊系统会给已知代理IP段打标,命中之后不一定封你,而是返回降级素材——比如A/B测试里直接给B版本,或者干脆返回默认页。你以为在验证创意效果,其实在验证平台的兜底逻辑。
我们做了一次对照:同一广告位、同一城市,用干净家宽IP和公开代理池各取100次,素材响应体不一致率达到 23%。有一次整份“华东区素材效果报告”被推翻重做,说实话那一周挺难熬。
- 同一URL、同一UA,分别从代理IP和本地家宽各请求10次,比对响应体hash;
- 差异率超过5%,该IP段直接进黑名单,别心疼那点剩余额度;
- 采集端记录响应体长度和关键字段hash,做异常检测而不是只看状态码。
这里有个反直觉的点:池子大不等于干净。有些池子几千万IP,但被同行反复跑过,反作弊标记率高得离谱。我现在选型第一看的是纯净度检测机制,第二才看规模。
坑三:粘性会话时长定错,频控率翻7倍
广告验证要模拟真实用户:同一用户看完落地页再点二次跳转,会话得粘住。我一开始把粘性设成30分钟,想着越像真人越好。跑了七天,单IP请求数飙上去,触发频控的比例从1.2%涨到11%。
| 粘性时长 | 频控触发率 | 地域命中率 | 单IP日均请求 |
|---|
| 1分钟 | 0.8% | 94.2% | 610 |
| 5分钟 | 1.6% | 97.5% | 3200 |
| 15分钟 | 6.9% | 98.1% | 9600 |
| 30分钟 | 11.4% | 98.3% | 19200 |
结论很清楚:5分钟是拐点。再往上拉,地域命中率只多0.8个百分点,频控风险涨了7倍。这个数后来被我固化进了配置模板,不同项目只调并发不调粘性。
现在的混合方案与实测对比
三档路线我都完整跑过,预算从低到高,数据如下。
| 方案 | 地域准确率 | 可用率 | 平均延迟 | 成本 |
|---|
| 自建家宽拨号池(200条) | 98.6% | 99.2% | 42ms | 约1.2万/月 |
| 隧道代理(按天) | 97.1% | 99.5% | 18ms | 16元/天/通道 |
| 动态短效(按IP) | 96.4% | 99.9% | 8ms | 0.0022元/IP起 |
我最后选的是混合:核心20个城市用自建拨号池保准确率,长尾城市走动态短效按量付费,综合成本比全自建降了约 37%。蚂蚁代理在这个组合里承担长尾那部分,3000万+的池子覆盖365个城市,走白名单+提取接口两种认证方式,接入花了大半天。
如果你每天的量级在百万级以内,我的建议是先跑动态短效加出口校验,别一上来就自建,成本结构撑不住。千万级以上再考虑混合,那时候自建的边际收益才显现出来。
三个坑压缩成三句话:归属地不等于出口地,纯净度优先于池子规模,粘性时长有明确拐点。配置模板和探针脚本的骨架我是照着 mayihttp.com 的文档示例改的,结构可以直接复用。