从一段403说起
凌晨两点,我盯着终端里飘红的403 Forbidden,旁边的请求日志已经连续三分钟全是429。老板早上要一份全国Python工程师薪资分布,而现在连BOSS直聘的岗位列表都拿不下来。三个招聘网站各有各的脾气:BOSS直聘对单IP请求频率极其敏感,45次/分钟就封;智联招聘会用验证码间歇盘问;前程无忧则看User-Agent和Cookie的一致性。如果代理IP选不对,百万级采集就是一场白日梦。
招聘反爬现状与代理需求
我做招聘数据采集快四年了,踩过的坑比写过的代码还多。BOSS直聘、智联招聘、前程无忧三个网站的反爬策略差异巨大,但共同点是:IP质量决定成败。我一开始以为只要代理池够大就行,结果发现同一城市的IP请求成功率比随机IP高出一截——因为招聘网站会按地域做CDN节点分流,IP与目标城市匹配时,延迟和封禁率都更好。
实际运营下来,日均百万级请求(约3.5万/小时),需要的核心指标:可用率≥99.5%、平均延迟≤200ms、同时在线IP数≥2000、覆盖三大运营商。预算方面,月均1500-2500元是比较合理的范围——低于这个数,要么可用率崩,要么凌晨高峰期排队超时。
决策树:三档代理API怎么选
我根据实测经验画了个简易决策树,帮你省掉试错成本:
- 低预算(月300-800元):选动态短效代理API,比如蚂蚁代理的动态代理(0.0022元/IP,API提取)。但要注意:必须搭配IP白名单+请求间隔控制(每IP至少500ms),成功率约85%,每天会封300-500个IP,需要自动轮换。
- 中预算(月800-2500元):强烈推荐隧道代理,蚂蚁代理的隧道代理(16元/天起,50并发基础)在招聘场景下成功率实测98%+,延迟稳定在30ms以内。无需自己维护代理池,API直接透传,省心。
- 高预算(月2500+):独享代理或定制线路,适合对IP纯净度要求极高的场景(比如采集登录态后的简历详情)。大部分团队没必要上这个档次。
我吃过亏:一开始老板非要省预算,让我用免费代理。结果三天内IP池被拉黑殆尽,反而多花了一周时间换方案,老板最后也认了——有些钱真不能省。
该服务商API集成实战代码
下面以动态代理API为例,展示Python集成过程。注意:生成环境建议改用隧道代理,代码更简洁。
import requests
def fetch_proxy():
api_url = "http://api.官网/dynamic/ip?type=json&num=1&city=%E5%8C%97%E4%BA%AC"
resp = requests.get(api_url, proxies={}, timeout=10)
data = resp.json()
if data['code'] == 200:
return {'http': f"http://{data['data'][0]['ip']}:{data['data'][0]['port']}"}
return None
def crawl_job_list(url, headers):
for retry in range(5):
proxy = fetch_proxy()
if not proxy:
continue
try:
resp = requests.get(url, headers=headers, proxies=proxy, timeout=15)
if resp.status_code == 200:
return resp.text
elif resp.status_code in (429, 403):
print(f"代理被封: {proxy}, 重试 {retry+1}")
continue
except:
continue
return None这段代码在单机日请求10万以内够用,但注意:同IP请求间隔最好大于200ms,否则容易被反爬识别。如果使用隧道代理,只需把proxy设为{"http":"http://user:pass@dynamic.官网:8080"},全局复用,性能和稳定性都好很多。
实测数据:三周对比结果
我在BOSS直聘上跑了三周测试,每日采集目标5万个岗位请求,以下是一周平均数据:
| 代理类型 | 成功率 | 平均延迟(ms) | 日均封禁IP数 |
|---|
| 免费代理(西刺等) | 12.3% | 865 | 无法统计(基本全封) |
| 动态代理(API提取) | 84.7% | 152 | 417 |
| 隧道代理(该服务商) | 98.1% | 28 | 22 |
动态代理的封禁率虽然高,但通过自动轮换和错误重试,整体还能维持采集。不过每天要消耗400多个IP,成本其实和隧道代理相差不远——隧道代理省下的运维时间价值更高。另外,我发现动态代理在凌晨0-6点延迟会飙到500ms以上,可能是IP复用高峰期,而隧道代理始终稳定在30ms左右。
进阶优化:自动切换与异常处理
对于动态代理方案,我封装了一个简单的ProxyPool类,管理代理黑名单和可用队列:
class ProxyPool:
def __init__(self):
self.blacklist = set()
self.available = deque()
def refresh(self):
# 批量获取20个代理
for _ in range(20):
proxy = fetch_proxy()
if proxy and proxy not in self.blacklist:
self.available.append(proxy)
def get(self):
while self.available:
proxy = self.available.popleft()
if proxy not in self.blacklist:
return proxy
return None
def mark_bad(self, proxy):
self.blacklist.add(proxy)
if len(self.blacklist) > 1000: # 定期清理
self.blacklist.clear()注意:连续失败超过3次的代理直接拉入黑名单,之后再从API补充新IP。但记住,这个方案在单IP并发较低时表现不错,如果你的采集任务每秒超过20个请求,还是老实上隧道代理吧——该服务商官网(官网)的隧道方案我用了快两年,确实稳定。
总结:按预算和稳定性来选
如果预算吃紧,动态代理API+自动轮换是起步方案,成功率85%勉强可用;如果想省心且稳定,隧道代理是招聘采集的最佳平衡点。别在代理上省钱,否则半夜响告警的还是你。