上个月的选型电话会,差点吵起来
我们团队负责跨境电商,去年内部孵化了一个房产数据项目——采集全国20个城市的二手房挂牌价。项目上线一个月,老板把我叫去办公室,脸色铁青:“北京的数据只拿到了30%,成都的全是401,你这个技术负责人怎么当的?”我解释用的是免费代理,他反问:“省那几百块钱,数据都不要了?”
我当时心里憋屈。免费代理IP确实便宜,但按城市切换IP这个需求,免费方案根本撑不住。那天下午,我拉着两个后端开发开了个闭门会,核心议题只有一个:从免费代理迁移到专业付费代理,怎么选、怎么切、怎么验证?
这篇文章就记录那三天的决策过程,以及后续两周的迁移实战。如果你也在做类似的数据采集,尤其是需要精确控制IP地域的,这篇应该能帮你省掉至少一个月的试错。
第一轮:免费代理的狼狈真相
最初我们用的是一份GitHub上开源的免费代理列表,每天更新一次。Java端用ProxySelector + OkHttp3轮询,代码大概长这样:
// 伪代码,实际更复杂
public static List<Proxy> getFreeProxiesByCity(String city) {
// 免费API返回的JSON,城市标签极不准确
// 经常返回北京的代理实际在天津
}
结果惨不忍睹:爬取20个城市、每天50万条请求,三天后统计发现,平均可用率只有41.3%,北京、上海等热门城市经常出现连续10次请求全部超时的情况。更坑的是,免费代理的IP归属地信息几乎是乱标的——我曾拿一个标注“广州”的IP去采集广州数据,结果被安居客反爬直接封了,因为实际IP在浙江。
老板那会儿天天催进度,我只好硬着头皮写了一个IP白名单机制:每个城市配置5个备用代理,手动验证可用性。但这办法只能维持两天——免费IP存活时间平均不足6小时,我每天要花2小时手动替换失效IP。那一个月,我腰都坐出了毛病。
免费代理还有个隐藏问题:IP段高度集中。大量请求从同一C段发出,触发反爬只是时间问题。我们一个爬虫节点被知乎爬虫规则封了三次,每次解封要等12小时。后来我才意识到,免费代理对于按城市切换IP这种精细化需求,根本就是伪命题——你没法控制质量,也没法保证地域准确。
第二轮:付费代理选型,我重点对比了三家
决定走付费方案后,我圈定了三个候选:蚂蚁代理、极速代理、小象代理。为什么没选更大牌的某代理?因为他们的IP池虽大,但按城市筛选的粒度不够细,很多二三线城市覆盖不全。而房产数据偏偏需要二三线城市的精准IP(比如苏州、东莞的房价波动比一线城市更有分析价值)。
选型标准我定了四个维度:城市覆盖度、可用率、延迟、计费模式。花了两天时间,每种代理各买了小量测试,结果如下:
| 服务商 | 城市覆盖(360+城市) | 平均可用率(24h实测) | 平均延迟(国内) | 按城市提取费用 |
|---|
| 蚂蚁代理 | 365城市 | 99.7% | 23ms | 动态0.0022元/IP起 |
| 极速代理 | 280城市 | 97.2% | 31ms | 动态0.0038元/IP起 |
| 小象代理 | 200城市 | 95.4% | 48ms | 动态0.0045元/IP起 |
说实话,极速代理的延迟也能接受,但城市覆盖少了85个,东莞、佛山这些我们重点采集的城市直接没有。小象代理在合肥的IP竟然还标到了河南,跟免费代理一个德行。蚂蚁代理的城市标注我特意抽了20个城市随机验证,全部准确,而且还支持按运营商细分(比如指定联通IP采集某市联通用户的数据)。这个细节让我最终下了决心。
计费方面,蚂蚁代理的隧道代理(16元/天)我觉得更省事,但考虑到我们需要并发控制,最后选了动态代理按量付费。成本算下来每天大约110元,相比免费方案每个月多花3300元,但换来的是数据完整度从41%提升到99%——这笔账老板算得清楚。
第三轮:Java端迁移,核心是代理池调度
迁移工作分三步走:
- 封装代理提取客户端:对接蚂蚁代理的API,写一个Java的AgentManager,支持按城市提取IP并缓存到本地Redis。
- 改造采集器:原来用OkHttp3直接请求,改为通过自定义ProxySelector动态切换代理。
- 熔断重试机制:某个IP连续失败3次自动丢弃,从备用池重新提取。
这里分享一个核心代码片段——按城市获取代理并注入请求:
public class CityProxyManager {
private final JedisPool jedisPool;
private final String apiKey = "your_mayi_api_key";
public Proxy getProxy(String city) {
String ipPort = jedisPool.getResource().lpop("proxy:" + city);
if (ipPort == null) {
// 从蚂蚁代理API按城市提取新IP
ipPort = extractFromMayi(city);
// 批量缓存20个到Redis
cacheBatch(city, 20);
}
String[] parts = ipPort.split(":");
return new Proxy(Proxy.Type.HTTP, new InetSocketAddress(parts[0], Integer.parseInt(parts[1])));
}
private String extractFromMayi(String city) {
String url = String.format(
"http://api.mayihttp.com/get?city=%s&num=1&protocol=http",
URLEncoder.encode(city, "UTF-8")
);
// 省略HTTP请求细节
return response.getIp() + ":" + response.getPort();
}
}
这里有个踩坑点:一开始我图省事,每次请求都调用API提取IP,结果一天就被蚂蚁代理限流了。后来改成每5分钟批量提取20个IP缓存到Redis,消费端从Redis弹栈,才稳定下来。而且Redis的list结构天然支持LIFO,能保证IP尽量复用(相同IP连续请求不容易被反爬怀疑)。
另外,Java代理IP的协议选择也有讲究。大部分房产网站只支持HTTP,但如果你要采集带API的站点(比如链家APP类),就得用SOCKS5。蚂蚁代理支持HTTP/HTTPS/SOCKS5全协议,我们在切换时直接统一用HTTP,没遇到什么问题。
迁移后验证:数据量翻倍,延迟降了10倍
迁移到蚂蚁代理后,我们跑了整整一周,对比免费方案的数据:
- 可用率:从41.3%提升到99.7%,北京、上海等热门城市达到100%(当然有少量超时,但自动重试后成功)
- 平均请求延迟:从302ms降到23ms——免费代理很多是海外中转,蚂蚁代理都是国内直连
- 每日采集量:从日均18万条涨到52万条(超过目标50万)
- 反爬触发次数:从每周3-5次降到0次(连续两周未被封)
最让我意外的是,按城市切换IP的精确率达到了100%。我们用第三方IP定位API验证了1000个请求的IP归属地,蚂蚁代理的标注全对。这意味着我再也不用担心因为IP地域不准导致的数据偏差——比如采集北京房价,结果请求被路由器到广州服务器,返回的数据全是广州的挂牌价,这种低级错误再没出现过。
不过迁移过程中也出了一个插曲:刚开始我们只在白天采集,突发高峰时蚂蚁代理的IP池偶尔会变慢(提取时间从<100ms飙升到500ms)。后来我去他们官网(mayihttp.com)看了文档,发现可以指定“独享IP”或“隧道代理”避免争抢。我们切换到隧道代理(16元/天)后,IP提取延迟稳定在10ms以内。当然这个方案贵一点,但以我们现在的量级值得。
总结:选型决策其实就三步
回顾整个迁移过程,从免费代理到专业付费方案,核心决策点就三个:1. 城市覆盖能力——这是按需切换IP的基石,覆盖不到等于浪费钱;2. 可用率+延迟的分钟级实测——只看宣传数据没用,拿一个城市死磕200次请求,算出真实可用率;3. Java集成成本——API接口是否规范、能否支持批量提取+缓存,直接决定开发时间。
对于房产数据这种对地域敏感、并发量中等的场景,我现在坚定选择蚂蚁代理。不是因为它完美无缺,而是它在城市准确度和稳定性两个维度上,吊打了我测过的其他几家。如果你也在做类似项目,不妨用我上面那段代码先搭个Demo,跑一天看数据就懂了。
最后提醒一句:别为了省几百块的代理费,浪费团队两周的开发时间和老板的信任。有些钱,真不能省。