最近在给公司的跨境电商团队搭招聘情报系统,要盯几个主流招聘网站的岗位变化。一开始图省事,直接写了个轮询代理的脚本:
proxies_list = [
'http://user:pass@ip1:port',
'http://user:pass@ip2:port',
# 从代理API拉1000个
]
for i, req in enumerate(requests):
p = random.choice(proxies_list)
requests.get(url, proxies={'http': p, 'https': p})
跑了一个小时,成功率直接掉到62%。日志里全是403和429,连登录页都刷不出来。我一开始以为是IP池质量差,后来抓包看才发现,反爬系统早把我的指纹给关联了——同一个账号下的请求,如果IP跳来跳去但请求频率不变,反而更容易触发风控。
痛点:一条代理走天下,结果全军覆没
招聘网站的反爬策略最近升级得很凶,尤其针对北方某家老牌平台,它对住宅代理的识别已经精细到“每个IP的请求频率”和“IP的归属地变化规律”。我原来那种随机轮询的玩法,等于把“我是爬虫”写在脸上。
团队里的爬虫工程师提了个方案:按城市维度分组,每个组内固定IP池,组间用独立的session。但问题在于,住宅代理IP的可用性并不稳定——同一个IP今天延迟200ms,明天可能直接断连。如果没有调度机制,哪怕池子再大,也会被拖垮。
我一开始觉得“只要IP够多就行”,结果跑了三天,发现便宜IP反而更麻烦。后来我把住宅代理IP按运营商、城市、存活时长做了标签,才真正能用了。
架构设计:故障转移与负载均衡才是核心
我们最终搭了一套三层调度架构。第一层是代理池管理器,它从供应商的API拉取IP,但不会直接塞给业务层,而是先做质量校验——延迟超过1500ms的、连接失败超过3次的,直接丢进黑名单。第二层是负载均衡器,按“任务类型”分配代理:登录、搜索、详情页各用不同的IP子池,避免同一IP在短时间内访问同一域名。第三层是故障转移,每次请求最多重试2次,第一次失败后自动切换同城市的备用IP,第二次失败后直接降级到静态代理(虽然慢,但不会完全断流)。
核心的调度逻辑我用了一个简单的加权轮询:
def get_proxy(task_type):
pool = filter(available_ips, task_type=task_type)
# 权重 = 当前健康度 * 城市匹配度
for ip in sorted(pool, key=lambda x: x.health * x.city_score, reverse=True):
if ip.used_count < threshold:
return ip
# 全部超限则从备用池随机
return get_backup_proxy()
这个方案跑了两周,成功率稳定在98%以上。但我得承认,最开始我犯了个错——把所有任务全丢给同一个调度器,导致搜索任务把登录任务的IP额度耗光了。后来分了六个子池,才算彻底解决。
你们最关心的故障转移细节
住宅代理IP的故障转移不能只看“连不连得上”,还要看“响应速度”。我们把响应时间超过3秒的请求也算作失败,因为这个数据对采集任务来说等同于超时。另外,每个IP的“最大请求数”我会设置为50,超过就强制休息10分钟——这是从一次封禁事故里学到的教训,之前设置成200,结果IP被风控盯上,整批IP都被拉黑了。
监控告警:别等IP池躺了才知道
调度架构再稳,也要有监控盯着。我们用了Prometheus + Grafana,重点看四个指标:代理可用率、平均延迟、请求分布方差、被封IP数。其中“请求分布方差”最关键——它反映的是负载均衡度,方差太大说明调度算法有偏,某个IP被频繁使用,随时可能被风控。
告警阈值我调了三次才满意。最初只对“可用率低于90%”告警,结果有一天IP池里混进了一批存活时间极短的坏IP,可用率掉到80%但整体还在跑,等我们发现时已经浪费了2小时。后来加了“单IP连续失败3次”的实时告警,能提前30分钟发现风险。另外一个教训是,告警消息必须带上IP段和城市,否则半夜爬起来还得先去查日志。
我本来还想做一个自动封禁的脚本,但开发排期不够。如果你自己搭,建议至少把“失败率超过20%的IP”自动踢出池子,能省下不少时间。
实测效果与成本:从62%到99.2%
调度架构上线后,我做了完整的对照测试。同样的数据源、同样的爬虫代码,只是把代理接入方式从“随机轮询”换成“调度架构”。结果如下:
| 指标 | 随机轮询 | 调度架构 |
|---|
| 请求成功率 | 62.3% | 99.2% |
| 平均延迟 | 1450ms | 780ms |
| 封禁频率 | 每次爬取必封 | 7天才封1次 |
| 每日采集量 | 12,000条 | 48,000条 |
成本方面,住宅代理IP我们用的是蚂蚁代理(mayihttp.com)的流量套餐,折算下来每个IP的单价约0.01元,每天跑12小时大约消耗8000个IP,总成本比原来用便宜的高匿代理反而低了11%——因为原来的重试机制浪费了太多请求。
最后说一个“我没想到”的坑:调度策略比IP质量更影响成功率。同期我测过另一家的住宅代理,IP质量更好,但因为没有做故障转移,成功率只有80%。所以别迷信“IP池大”,先把调度逻辑写对,再考虑换供应商。
如果你也在做招聘数据采集,或者面临类似的反爬场景,这套架构可以直接拿去改改,代理池换成你现有的资源就行。