背景:之前爬某政务公开网站的时候,最开始日均被封IP超过100个,换代理的成本都快比项目收益高了。折腾了半个月优化,现在连续爬了3个月,零封锁,代理成本降了90%。
一、被封的血泪史
最开始我以为反爬就是换个UA就行,结果被教育的很惨:
- 刚爬10分钟,IP直接封24小时
- UA换了,还是被封,甚至换了IP还是被识别
- 用代理池爬,爬了半天所有代理都被拉黑了
- 最后直接弹出验证码,人工都解不过来
后来我总结出来,现在的反爬已经不是单点防护了,是全链路检测,你只要有一个地方不符合真实用户特征,就会被封。
二、完整对抗方案架构
这套方案是我踩了无数坑总结出来的,覆盖了99%的常见反爬检测点,只要按这个做,几乎不会被封。
三、核心实现要点
1. 请求头全字段伪装
别只改User-Agent,现在反爬会检测所有请求头字段,要和真实浏览器完全一致:
# 真实Chrome的请求头,直接复制浏览器的就行HEADERS={"accept":"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7","accept-encoding":"gzip, deflate, br","accept-language":"zh-CN,zh;q=0.9,en;q=0.8","cache-control":"max-age=0","sec-ch-ua":"\"Google Chrome\";v=\"123\", \"Not:A-Brand\";v=\"8\", \"Chromium\";v=\"123\"","sec-ch-ua-mobile":"?0","sec-ch-ua-platform":"\"Windows\"","sec-fetch-dest":"document","sec-fetch-mode":"navigate","sec-fetch-site":"none","sec-fetch-user":"?1","upgrade-insecure-requests":"1","user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36"}我之前就是漏了sec-ch-ua这些新字段,导致UA换了还是被识别,现在所有请求头都和浏览器完全一致,就没问题了。
2. TLS指纹伪装
这个是很多人忽略的点,现在反爬会检测TLS握手的指纹,哪怕你请求头全对,TLS指纹和浏览器不一样,还是会被封。我用curl-impersonate来模拟Chrome的TLS指纹:
# 用curl-impersonate发起请求,TLS指纹和真实Chrome完全一致importsubprocessdeffetch_with_curl(url,proxy=None):cmd=["curl-impersonate-chrome",url,"-H","accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8","-H","accept-language: zh-CN,zh;q=0.9","-H","user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36","--compressed","--connect-timeout","10","--max-time","30"]ifproxy:cmd.extend(["--proxy",proxy])result=subprocess.run(cmd,capture_output=True,text=True)returnresult.stdoutifresult.returncode==0elseNone用了这个之后,TLS指纹和真实Chrome100%一致,反爬根本识别不出来你是爬虫。
3. 行为层伪装
请求和传输层都对了,行为不对还是会被封:
- 请求间隔随机化:不要固定每秒爬N次,要随机化,比如1-3秒爬一次,模拟人的点击间隔
- 页面行为模拟:爬取页面后随机停留几秒,模拟滚动页面、点击无关链接这些操作,不要一访问页面就爬完就走
- 请求顺序模拟:先访问首页,再访问列表页,再访问详情页,不要直接请求详情页,和真实用户的浏览路径一致
4. 风险控制
- 限流:每个域名每秒最多爬1-2次,比真实用户访问还慢,反爬根本不会注意你
- 失败降级:如果连续3次请求失败,自动暂停10分钟,换代理换Cookie再试,不要硬爬
- 告警:如果成功率低于90%,自动发告警,人工介入调整策略,不要等到被封死了才发现
四、踩坑经验
- 代理IP被标记:我之前用的代理池很多IP已经被标记为爬虫IP了,哪怕你伪装的再好还是会被封,后来换了纯净的住宅代理,就没问题了
- Cookie关联检测:我之前同一个Cookie用多个IP访问,直接被封了Cookie,后来改成一个Cookie绑定1-2个IP,就没问题了
- Canvas指纹检测:有些网站会检测Canvas指纹,我之前没管,结果同样的配置,有的机器能爬有的不能,后来加了Canvas指纹随机化,就都能爬了
五、效果总结
优化后:
- 日均被封IP从100个降到0
- 代理成本从每月3000降到300
- 请求成功率从60%升到98%
- 已经连续稳定爬了3个月,没出现过封锁
下一篇我会讲更高阶的设备指纹绕过方案,哪怕反爬检测你的浏览器特征,也能完美绕过。