代理一用就被拦?先搞清楚对方到底在看什么
很多人遇到的情况是:代理明明换好了,IP 也是新的、能连通,但请求发出去不是返回 403,就是弹验证码,或者干脆给你一个空页面。这时候大多数人第一反应是"IP 被封了",于是换一批 IP,结果还是一样。
问题往往不在 IP 本身,而在于你整套请求"看起来不像一个正常用户"。对方的风控系统通常会从三个层面给你打分:
第一层是 IP 层:这个 IP 属于什么类型、历史请求是否被标记过、它所在的城市和你声明的语言时区对不对得上;
第二层是协议层:请求头字段是否自洽、TLS 握手指纹像不像浏览器、HTTP 版本和头顺序有没有异常;
第三层是行为层:访问间隔是不是精确到毫秒的固定值、路径是不是像机器人一样一条直线、有没有停顿和回看。
三层里任何一层露馅,都会被判定为"代理流量"或"自动化流量"。所以只换 IP 不修特征,基本等于换件外套不换脸。
第一层:请求头,最容易露馅的地方
请求头是对方第一眼就能看到的东西,也是绝大多数人翻车的地方。常见的坑有这么几个:
1. UA 里带着脚本痕迹。默认情况下很多请求库会把自己的名字写进 User-Agent,比如一眼就能看出是脚本在访问。这种 UA 连伪装都算不上,直接就被拦。
2. 头字段缺失或多余。真实浏览器请求网页,一定会带 Accept、Accept-Language、Accept-Encoding、Upgrade-Insecure-Requests 这些字段。少一个就等于自我介绍"我是程序"。
3. 代理相关的头没清理。有些代理会在转发时自动加上 X-Forwarded-For、Via、Proxy-Connection 之类的字段,这等于在脑门上贴着"我经过代理"四个字。这也是为什么要用高匿代理而不是透明代理。
4. 语言、时区、IP 归属地互相打架。IP 显示在某个城市,Accept-Language 却是别的语种,时间戳也对不上,这种矛盾在风控系统里是高分异常项。
5. 每次请求头一模一样。字节级完全一致的请求头组合,本身就是一种机器指纹。正常用户在不同页面、不同时间发出的请求,头部多少会有细微变化。
下面是一组相对"像浏览器"的请求头写法,注意字段顺序也要稳定:
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
"Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8",
"Accept-Encoding": "gzip, deflate, br",
"Connection": "keep-alive",
"Upgrade-Insecure-Requests": "1",
"Referer": "https://目标站点首页路径/",
}
# 注意三点:不出现脚本名、不出现代理头、字段顺序固定不变
第二层:TLS 指纹,看不见却最致命
这一层是很多人完全不知道的地方。你用 HTTPS 访问网站时,客户端在正式发数据之前要先和服务器"握手",握手的第一个包里会带上:支持的 TLS 版本、一串加密套件、一串扩展、椭圆曲线参数、应用层协议列表等等。
把这些信息的组合算个哈希,就得到所谓的 TLS 指纹(业内常说的 JA3、JA4 就是这类算法)。关键在于:同一个请求库、同一个版本发出的握手包,指纹几乎是固定的。
也就是说,你把 UA 改得再像浏览器,只要握手包还是脚本库那套参数,服务器一看指纹就知道:"UA 说是浏览器,握手却是脚本程序",这个矛盾比 UA 本身更致命。很多站点甚至不看 UA,直接拿指纹做第一道筛子。
所以整改方向很明确:让握手行为贴近真实浏览器。实操上有两条路,一是直接在真实浏览器环境里发起请求(自动化浏览器方案),二是使用支持复刻主流浏览器握手指纹的请求方案。不管走哪条路,最后一定要做"自洽检查":UA 声称的浏览器版本、头部顺序、HTTP 版本、TLS 指纹四者必须对得上,不能一个说新版本浏览器、握手却是老旧参数。
第三层:行为节奏,机器和人的差别在"不规律"
前两层修好了,很多人还是会被拦,原因在行为层。风控系统会统计你的访问曲线,机器人的特征其实很好认:
间隔太整齐。每隔 2 秒一次,连续几百次,人类做不出这种精度。
并发太陡。平时安静,突然几百个请求同时打过来,典型的分批跑任务形状。
路径太直。只请求详情页,从不加载图片、样式、脚本资源,也不点任何内链,这在真实浏览里不可能出现。
没有停留。打开就走,从不回看、不翻页、不修改参数。
作息反常。某个账号或某个 IP 段 24 小时匀速运转,没有任何低谷。
整改的核心思路是引入合理的随机性和完整的浏览路径:把固定 sleep 换成随机区间,把并发从"猛冲"改成"平滑限速",让采集任务带上页面资源请求和站内跳转,按业务真实高峰时段分配流量,夜间主动降速。
import random, time
def human_delay():
# 不是固定 2 秒,而是在区间内波动,偶尔来一次长停顿
if random.random() < 0.1:
time.sleep(random.uniform(8, 20))
else:
time.sleep(random.uniform(1.2, 4.8))
一张表自查:症状、原因、整改动作
| 症状 | 最可能的原因 | 整改动作 |
|---|---|---|
| 直接返回 403,无验证码 | TLS 指纹与 UA 不匹配 | 改用可复刻浏览器握手的请求方案,并做四要素自洽检查 |
| 频繁弹滑块或图片验证 | 行为节奏过于规律 | 随机化间隔、降低并发、补充完整浏览路径 |
| 部分请求成功、部分失败 | IP 池里混进了被标记的 IP | 换成纯净度高、可控制切换频率的代理资源 |
| 请求头正常仍被识别 | 转发头泄露了代理信息 | 使用高匿代理,确认不附加 X-Forwarded-For、Via |
| 换 IP 后立刻又被拦 | 只换了 IP,其他特征没变 | 把 IP、请求头、指纹、节奏当成一个整体一起调整 |
别忘了 IP 资源本身:干净比数量更重要
特征伪装做得再好,如果拿到的 IP 本身就是"脏"的——被大量用户反复使用、频繁触发风控、归属地乱七八糟,那照样跑不通。IP 的纯净度、稳定性和可控性,是整条链路的地基。
这块可以看下天启HTTP。它提供的是国内代理 IP 服务,产品线覆盖短效代理、长效静态代理、独享代理和隧道代理,支持 HTTP、HTTPS 与 SOCKS5 协议,通过 API 接口提取 IP,可以按业务需要设置切换频率,IP 为高匿转发,不会把真实来源和代理信息写进请求头。节点覆盖国内多个城市,可以按地区选取,方便把 IP 归属地和账号、语言、时区做对齐——这正是上面第二层和第三层都需要的条件。
选的时候建议先做小流量测试:拿一批 IP 跑真实业务请求,看成功率、响应延迟和连续可用时长,再决定用哪种类型。独享型适合对稳定性要求高的长期任务,短效型适合高频轮换的采集场景,隧道代理适合不想自己维护 IP 池的团队。
一套可以照着做的整改顺序
第一步,先定位。用同一批 IP 分别跑"原始请求"和"改造后的请求",看返回码差异。如果原始请求全挂、改造后部分通,说明问题在特征层而不是 IP 层。
第二步,修协议层。清理 UA 和多余的代理头,补齐浏览器常规字段,固定顺序,然后处理 TLS 指纹,确保四要素自洽。
第三步,调节奏。把固定间隔换成随机区间,并发从高到低逐步加压,找出目标站点的容忍阈值。
第四步,控 IP。把切换频率、地区分布和业务节奏匹配起来,避免一个 IP 短时间内承担过多请求。
这四步里,前三步是"伪装",第四步是"底料"。三者一起改,成功率才会真正上来。
常见问题
Q:为什么我换了 IP 还是被识别?
因为识别不只看 IP。请求头、TLS 指纹、访问节奏任何一项异常,风控都能判断出这是自动化流量。只换 IP 相当于换了外套没换脸,建议按本文三层逐一排查。
Q:TLS 指纹到底是什么,普通用户需要关心吗?
它是客户端握手时携带的一组参数组合算出来的标识,相当于连接层的"身份证"。只要你的请求是程序发出的,就一定会带上某种指纹,所以做采集类业务时有必要关心它是否和声明的浏览器一致。
Q:请求头照抄浏览器就一定安全吗?
不一定。头部只是表象,如果握手参数、HTTP 版本、字段顺序对不上,反而会形成更明显的矛盾。一致性比"像不像"更重要。
Q:访问间隔设置成随机就够了吗?
随机只是第一步。完整的浏览路径、页面资源加载、合理的停留时间、符合作息规律的流量曲线,都是行为层评分的组成部分。
Q:天启HTTP 适合什么样的业务?
适合面向国内站点的采集、数据核对、账号多开管理、接口测试等需要稳定国内 IP 的场景。它提供的是国内代理 IP 服务,不适用于需要海外 IP 的业务,也没有住宅类 IP 产品,选型时请按实际需求匹配。
Q:怎么判断是 IP 的问题还是特征的问题?
最简单的办法是控制变量:用同一套请求代码,分别配不同的 IP 池跑一遍;再用同一批 IP,分别用原始代码和改造后的代码跑一遍。哪一组差异明显,问题就出在那一层。





