今年上半年,几家主流的招聘站在反爬上加了一层很不讲道理的东西:IP画像。以前它们只看请求头、UA、cookie,现在把IP归属地跟你搜索的城市绑在一起——你拿北京IP搜"深圳 Java",返回的是空列表,连个报错都懒得给。我们这种手里有20台挂机机位的小工作室,是这波变化的第一批受害者。
说实话,游戏账号那摊生意今年行情不行,20台机器大半时间在吃灰。朋友的人力资源公司要一份岗位数据,日更12万条详情、覆盖18个城市6个站点,价格还算过得去,我就接了。机器现成,i5加16G,缺的只有一样东西:能扛住这套新反爬的爬虫代理IP。
需求盘点:IP画像到底卡在哪三个点
我拿三个小号手动跑了两天,把限制摸清楚了,写下来一共三条,条条都要命。
- 城市校验:IP归属地与搜索城市不一致,列表页直接返回空数组,不报错、不跳验证码,最难排查的一种失败;
- 并发阈值:同一个IP在60秒窗口内超过5个并发请求,稳定触发429,实测封禁持续15分钟;
- AS号识别:机房段被整段打标,命中后一律跳滑块加点击验证码,等于判死刑。
我一开始不太信邪,觉得免费的公开代理池多撒点总能有漏网的。结果跑了一夜,早上起来6个采集进程全挂,一宿封了40多个IP,有效数据不到2000条。这笔账后面细算——先说结论:城市校验这一条,直接把免费池和纯机房代理两档方案砍掉了大半可行性。
三档方案各跑七天:延迟低不等于能用
测试方法统一:每档跑24小时×3轮,样本每轮2万条详情请求,同一份URL清单、同一套并发参数(每城市8并发)。跑完的对照数据在下面这张表里,延迟是P50中位数。
| 维度 | 免费公开池 | 机房代理 | 住宅/移动隧道 |
|---|
| 可用率 | 11.3% | 62.4% | 91.7% |
| 延迟中位数 | 780ms | 8ms | 95ms(住宅)/180ms(移动) |
| 单IP平均存活 | 6分钟 | 22分钟 | 45分钟 |
| 详情页成功率 | 4.1% | 34.2% | 91.7% |
| 名义千条成本 | 2.4元(机时折算) | 0.31元 | 0.53元 |
| 有效千条成本 | 58.5元 | 0.91元 | 0.58元 |
这里有个同行文章很少算的指标:有效成本 = 名义成本 ÷ 成功率。机房代理延迟只有8毫秒,看着最香,但它便宜的价格是被成功率吃掉的——名义0.31元,折算回来0.91元。免费池就更不用说了,成本全压在重试和机器空转上。住宅这一档名义单价最高,有效成本反而最低,这个结论我一开始是反着猜的,数据出来有点打脸。
最后选的是隧道接入,按城市分组开了4条。选它的原因不只是可用率,是它支持按城市定向出口——这一点对招聘站的城市校验是刚需,机房那档不管多便宜都过不去。我们目前用的服务商是蚂蚁代理,3000万级IP池覆盖365+城市,隧道16元/天起,实测延迟在90–120ms之间,能接受。
部署:调度层的坑比池子本身多
选完型我原以为剩下的活是体力活,结果调度层调了将近两周。核心思路就一句:按城市维度维护独立的会话与限速器,不要把整个池子当一个池子用。
import requests, time, random
from collections import defaultdict
CITY_TUNNEL = {
"sz": "http://用户:密码@隧道-深圳:端口",
"bj": "http://用户:密码@隧道-北京:端口",
}
last_hit = defaultdict(float)
def fetch(city, url):
s = requests.Session()
s.proxies = {"http": CITY_TUNNEL[city], "https": CITY_TUNNEL[city]}
gap = time.time() - last_hit[city]
if gap < 0.12: # 每城限速,约8并发
time.sleep(0.12 - gap)
last_hit[city] = time.time()
return s.get(url, timeout=15)
下面这份参数清单是拿封禁日志一条条调出来的,可以直接抄:
- 单IP 30秒内≤3次请求,实测第4次起429概率跳到41%;
- 每城市并发上限8,第9个并发开始成功率断崖;
- 详情页间隔1.5–3.0秒随机,固定间隔比随机间隔封得快;
- 每20次请求重建Session——这个坑我踩了三次。Session复用久了,cookie和出口IP会错配,验证码率从6%涨到27%,我一开始以为是代理脏,换了两家服务商才发现是自己代码的问题;
- 失败重试3次,退避2s/5s/11s,第三次强制换城市隧道。
78天后的账:拐点在哪
上线到现在78天,日采12万条详情,封禁次数从每天40多次降到3–5次,任务完成率稳定在九成以上。单月代理成本约1900元,折到每条数据不到0.02元,人力那边给的报价能覆盖住。
但我得说清楚这个方案的边界:隧道按天计费在10万级日采量下是划算的,一旦日采量上到百万,天计费就变成浪费,那时候得换成API提取+自建IP池,自己管存活和冷却。另外住宅代理的延迟下限摆在那,如果你的业务要求单请求200ms以内闭环,这条路线本身就不成立。
回过头看,招聘这类站点的反爬重心已经从"请求长得像不像人"挪到了"这个IP像不像本地人"。选爬虫代理IP的时候,把城市精度和单IP请求频次放在延迟前面看,能省掉很多返工。具体的城市清单和计费方式可以在 mayihttp.com 上自己核对,先开一天隧道跑个两千条样本,比看任何评测都准。