自动化爬虫被检测?中间人代理改写JS破局
作者:问题终结者2026.11.06 20:06浏览量:0简介:浏览器自动化采集常因 navigator.webdriver 等环境特征被风控脚本识别。本文剖析检测原理,给出一套基于本地中间人代理拦截并改写检测 JS 的完整方案:从定位特征脚本、编写响应改写钩子,到前置注入、指纹与行为加固、验证方法与合规边界,帮助读者系统性提升自动化采集的隐蔽性与稳定性。
一、问题背景:自动化浏览器为什么会被“一眼看穿”
在数据采集场景中,登录态是绕不开的一环:只有完成登录、拿到有效 Cookie,才能访问价格、评价等核心接口。而登录环节几乎必然遭遇滑块验证、行为校验等风控手段,很多团队会选择用浏览器自动化工具(驱动真实浏览器按脚本执行操作)来模拟人工流程。
问题在于,成熟的风控系统对这类自动化环境有一整套识别手段,常见检测点包括:
- 规范属性暴露:WebDriver 规范(浏览器自动化协议)定义了 navigator.webdriver 属性,浏览器被驱动接管时该值为 true,等于“自报家门”。
- 注入残留:自动化驱动启动时会向页面注入辅助脚本,在 window、document 上留下 driver_evaluate、webdriver_evaluate 等一系列特征属性,部分驱动还会挂载以 $cdc 开头的疑似随机属性。
- 静态特征扫描:风控 JS 会把上述特征串硬编码进代码,运行时枚举 window/document 属性逐个比对,一旦命中即判定为机器环境,轻则对请求返回错误响应,重则触发验证码甚至封禁账号。
- 环境指纹异常:UA 与真实内核不匹配、缺少正常浏览器应有的插件与字体、Canvas/WebGL 指纹异常、时区语言不一致等。
- 行为与网络特征:鼠标轨迹过于平直、点击间隔均匀、请求频率规律化、出口 IP 为数据中心地址等。
其中前三类属于“环境特征”,识别成本最低、命中率最高,也是大多数初学者卡住的地方。
二、常见应对思路与它们的天花板
面对检测,常见做法有三种,各有局限:
- 修改启动参数:通过浏览器命令行开关关闭“受控模式”相关特性,可以让 navigator.webdriver 返回 false。但它只能解决单一检测点,注入残留等其他特征依然存在。
- 前置注入脚本:利用自动化框架提供的“页面脚本执行前注入”能力,用 Object.defineProperty 把 navigator.webdriver 重定义为 false,并顺带删除部分特征属性。覆盖面比前者大,但风控 JS 一旦深度混淆、多文件加载或校验自身完整性,逐点对抗会非常疲惫。
- 网络层釜底抽薪:既然检测逻辑写在某段 JS 里,那就让这段 JS “照常运行,但看不见任何特征”。在流量链路上对响应体做改写,把特征串统一替换成无害占位符,这就是本文的重点:基于本地中间人代理的方案。
思路三的优势在于:不与风控代码逐属性缠斗,而是让它扫描的目标批量“消失”;同时改写发生在响应到达浏览器之前,对页面逻辑完全透明。
三、中间人代理方案原理
中间人代理(MITM Proxy)在本机启动一个代理进程,浏览器所有 HTTP/HTTPS 流量先经过它再发往服务器。代理持有自己签发的 CA 证书,因此能够解密 TLS 流量,查看并修改请求与响应。多数此类工具都支持“脚本钩子”:请求到达时触发 request 钩子,响应返回时触发 response 钩子,我们正是在 response 钩子里对检测 JS 做字符串替换。
一个关键细节:很多风控 JS 除了检测,还承担生成签名、Token 等职责。如果把整个文件直接拦截掉(返回空内容),往往导致后续接口签名缺失、请求全部失败。更稳妥的做法是“改写而非删除”——让脚本继续执行,只是它要找的特征全部不存在。
四、实战步骤
步骤 1:环境准备
- 准备 Python 环境,通过包管理器安装一款支持 Python 脚本扩展的中间人代理工具(此类工具多为开源项目,选择活跃维护的即可)。
- 按工具文档生成 CA 证书,并在本机系统/浏览器中信任该证书,否则 HTTPS 流量无法解密。注意:信任自签证书仅限自己的测试环境,不要在不受控设备上使用。
步骤 2:让流量走代理
- 将系统代理或浏览器代理指向 127.0.0.1:8001(端口可自定)。
- 自动化浏览器也可以在启动参数中指定代理,保证被驱动的浏览器同样经过代理链路。
步骤 3:启动代理监听
以监听模式启动代理并指定端口(各工具命令不同,以所用工具文档为准),确认日志中出现监听 8001 端口的提示。
步骤 4:定位检测脚本
- 打开目标网站,用浏览器开发者工具的 Sources/Network 面板全局搜索特征词,如 webdriver、driver-evaluate、headless 等。
- 找到命中最集中、URL 相对稳定的那份 JS(下文以 risk-check.js 代称)。实践中它通常是一个体积较大、深度混淆的风控脚本,可能由独立路径甚至独立域名发布。
- 记录其 URL 特征片段,改写规则建议匹配路径前缀而非完整文件名,以便兼容版本号变化。
步骤 5:编写改写脚本
# driver_pass.py# 说明:不同代理工具的脚本接口略有差异,下面以常见的# "response(flow) 钩子"约定演示核心逻辑,接口名以所用工具文档为准。import logginglogger = logging.getLogger("driver_pass")# 特征串清单:风控 JS 会逐一枚举这些属性来判断自动化环境WEBDRIVER_KEYS = ["webdriver","__driver_evaluate","__webdriver_evaluate","__driver_unwrapped","__webdriver_unwrapped","_WEBDRIVER_ELEM_CACHE","driver-evaluate","webdriver-evaluate","webdriverCommand","webdriver-evaluate-response","__webdriverFunc","__webdriver_script_fn","__$webdriverAsyncExecutor",# 部分驱动还会在 window 上留下以 $cdc 开头的特征属性,# 以及包含具体驱动名称的字符串,可按需扩充清单。]def response(flow):# 1) 只处理命中的风控脚本,避免误伤正常业务 JSif "risk-check" not in flow.request.url:returntext = flow.response.texthit = False# 2) 把带引号的属性名替换成无害占位符for key in WEBDRIVER_KEYS:token = '"{}"'.format(key)if token in text:text = text.replace(token, '"NO-SUCH-ATTR"')hit = True# 3) 处理压缩代码中的布尔探测:navigator 被压缩成短变量 t,# 出现 t.webdriver 的访问,直接替换为 false,# 让 "if (t.webdriver)" 走"非自动化"分支if "t.webdriver" in text:text = text.replace("t.webdriver", "false")hit = True# 4) 防止旧 JS 被缓存,导致改写不生效flow.response.headers["Cache-Control"] = "no-store"if hit:logger.info("rewritten: %s", flow.request.url)flow.response.text = text
几个工程细节需要强调:
- 替换时带上双引号包裹,避免把页面正文或注释里恰好出现的 webdriver 字样误伤;
- “t.webdriver” 这类短变量替换存在误伤风险(其他代码可能出现同样文本),生产环境建议改用带单词边界的正则替换;
- 日志用于确认命中情况,调试期务必打开,规则失效时它是第一现场。
步骤 6:带脚本重启代理并验证
- 退出原代理进程,加载改写脚本重新启动,仍监听 8001 端口。
- 清理浏览器缓存后访问目标站,在控制台执行:
navigator.webdriver // 期望 false 或 undefinedObject.keys(window).filter(k => /webdriver|driver/i.test(k)) // 期望空数组
- 完整走一遍登录与滑块流程,观察接口是否恢复正常响应。
五、别只改 JS:配套加固清单
改写检测脚本解决的是“环境特征”,但要长期稳定运行,还需叠加以下手段:
- 前置注入:在页面任何脚本执行前,用 Object.defineProperty 把 navigator.webdriver 重定义为 false 或 undefined,并清理已知残留属性,与网络层改写形成双保险。
- 指纹一致性:UA、平台、时区、语言保持自洽;必要时处理 Canvas/WebGL 指纹与插件列表,避免“参数说了谎、指纹说实话”。
- 行为拟人:随机化操作间隔、用贝塞尔曲线模拟鼠标轨迹、加入滚动与停顿,避免匀速直线式的机器操作。
- 网络层治理:使用干净的代理 IP 池,控制并发与频率,避免规律化请求模式。
- 版本监控:风控 JS 会不定期更新特征与文件名,建议对响应体做抽样 diff,一旦规则命中率归零,及时更新特征清单。
六、规模化与工程化建议
当采集任务从单机走向规模化,可以把上述链路迁移到云上:采集程序部署在云服务器,改写代理作为旁路组件统一维护;抓取结果写入对象存储,过程日志接入日志服务,规则命中率与任务成功率接入监控告警,任务分发通过消息队列解耦。这些能力属于通用云产品品类,主流云厂商(如百度智能云)均有对应服务,按需组合即可,无需绑定特定实现。
七、合规提醒
反检测技术本身中立,但使用有边界:仅在你有权访问的系统上、以遵守服务条款与 robots 协议为前提开展采集;控制请求频率,不抓取个人隐私与敏感数据,不对目标系统造成干扰或破坏。理解攻防原理的价值在于构建更健壮的工程能力,落地时请务必守住法律与职业道德底线。

登录后可评论,请前往 登录 或 注册