简而言之:现代封锁机制主要发生在四个层面:网络层、请求签名层、浏览器层和行为层。首先利用状态码和验证页面诊断问题所在的层级,然后通过合理组合轮换式住宅代理、浏览器级头部信息、TLS 冒充、隐形浏览器以及类人行为时序来解决问题。当请求量过大或反机器人技术过于复杂,导致自行解决不再经济合算时,可将请求层交由托管 API 处理。
引言
如今,要实现不被封锁的网页抓取,已不再仅仅是更换 User-Agent 字符串或添加一秒延迟那么简单。到了 2026 年,防御严密的目标站点会将 IP 声誉、TLS 指纹识别、头部分析、JavaScript 挑战、浏览器指纹特征以及行为模型层层叠加,而其中任何一层都可能悄无声息地终结你的抓取流程。 如果您在 Cloudflare、Akamai、DataDome 或 Human(原 PerimeterX)后端运行生产环境爬虫,您可能已亲身体验过这种情况:运行数月的同一爬虫突然返回 403 错误、CAPTCHA 验证页面,甚至更糟的是,返回看似真实的虚假数据。
本指南正是我们当初在针对现代反机器人技术栈扩展爬虫时,曾希望拥有的实战手册。 它采用四层思维模型,使每种技术都能对应到具体的检测面;在您动用工具之前提供一个分诊流程;并最终给出一个客观的决策框架,帮助您判断何时应继续构建自研方案,何时应转而使用托管式爬取 API。代码示例采用 Python 编写,但其中的思路可直接应用于 Node.js、Go 以及任何支持 HTTP 的平台。
为何在2026年,不被封禁的网页抓取变得更加困难
反机器人防御已演变为多层级的产品体系,而非单一功能。如今,单次页面请求在返回任何实际HTML数据之前,必须经过IP信誉评分、TLS指纹匹配、头部标准化、JavaScript挑战评估以及行为分析等多重关卡。大多数反机器人系统会自动检测并封锁爬虫,这正是为何许多上季度还能正常运行的项目,本季度却悄然停止返回数据。
思考如何在不被封锁的情况下进行网页抓取的有效方法,是将其想象为由四层检测机制构成的堆栈。每次封锁的根本原因都恰好源于其中一层,而我们将要探讨的每种技术也恰好针对其中一层。
- 第 1 层,网络层:您连接所用的 IP 地址、其 ASN、滥用历史、地理位置,以及单个 IP 发送请求的频率。网站通过分析 IP 地址的行为来标记 IP,寻找不合理的请求频率、可疑模式或已知的数据中心 IP 范围。
- 第 2 层,请求签名:客户端在 HTTP 和 TLS 层级如何进行自我识别。这包括 User-Agent 字符串、完整的头部信息及其顺序、客户端提示、JA3 或 JA4 TLS 指纹,以及 HTTP/2 SETTINGS 帧。真实的浏览器会发送一组一致的头部信息;缺失或矛盾的头部信息则会暴露破绽。
- 第3层,浏览器:真实浏览器暴露的JavaScript执行面。Canvas、WebGL、AudioContext、字体枚举、
navigator对象、可用插件、时区和区域设置。一个使用默认选项的无头 Chrome 会通过这个执行面泄露数十种机器人信号。 - 第 4 层,行为:请求的间隔、鼠标是否移动、滚动深度是否变化,以及点击顺序是否类似于真人阅读网页。一个全天候每秒仅发送一次请求的爬虫,极易被检测出来。
防御方会对各层信号进行交叉核对。一个来自巴西的住宅IP地址,若搭配 Chrome/120 User-Agent 和 en-US Accept-Language标头存在内部矛盾,仅此不匹配就足以导致挑战失败。本指南的其余部分将依次剖析各层,并将其整合为针对特定供应商的应对策略。
在进行任何更改前先诊断封锁原因
我们在未被封禁的网络爬取中观察到的最大错误,就是直接跳到工具层面。工程师们更换代理提供商、安装隐身插件、增加延迟,最终却得到一个依然失败的“弗兰肯斯坦式”爬虫,因为实际的封禁发生在不同的层面上。请先进行诊断。
首先捕获完整的请求与响应,包括状态码、响应头、正文以及任何重定向链。然后将观察到的内容映射到最可能的检测层:
|
症状 |
可能的检测层 |
首要排查事项 |
|---|---|---|
|
HTTP 403 且无正文或包含微小 JSON 错误 |
第 1 或第 2 层 |
IP声誉、缺失头部字段、TLS指纹不匹配 |
|
HTTP 429 加上 |
第 4 层 |
并发数过高或固定间隔的请求 |
|
HTTP 503 状态码,并显示 Cloudflare 或 DataDome 插页 |
第 2 层或第 3 层 |
JavaScript 验证需要真实浏览器;HTTP 客户端无法通过 |
|
重定向循环至 |
第 2 层或第 3 层 |
Cookie/会话未持久化,或 JS 挑战未解决 |
|
HTTP 200 状态码,但列表为空、产品虚假或价格被打乱 |
第 1 层或第 4 层 |
向被标记的客户端提供蜜罐数据;地址看起来可疑 |
|
验证码页面(hCaptcha、reCAPTCHA、Turnstile) |
第 1 层或第 3 层 |
IP声誉差,或浏览器指纹标记为自动化 |
几个经验法则。连接瞬间直接返回403状态码,几乎总是意味着第1层或第2层:在尝试其他操作前,请先使用全新的住宅IP和真实的Chrome请求头。 若返回 503 状态码并伴随大量 JavaScript 的插页,几乎总是第 2 或第 3 层问题:你需要使用 TLS 伪装客户端或隐形浏览器。无提示的虚假数据是最糟糕的情况,因为它可能让你的数据集被污染数天;如果抓取到的值看似合理但存在细微错误,说明该网站正在对你的指纹进行影子封禁。
在排查故障时务必保存原始响应。使用开发者工具将其与真实浏览器的请求进行对比,缺失或矛盾的信号通常几分钟内就能显现。我们维护了一份内部排查手册,记录了[爬虫被封锁的最常见原因]的典型模式,这是你能做的最划算的调试投资。
第 1 层:代理基础设施
如果你只想在网页抓取方案中解决一个问题以避免被封,那就优化你的 IP 地址。抓取工具被封的最常见原因就是 IP 声誉不佳,无论你如何调整请求头或伪装成浏览器,都无法挽救一个已被所有封禁列表列入黑名单的数据中心 IP 范围。 代理是爬虫与目标服务器之间的中介,它能让每次请求看起来都来自不同的网络位置,这也是大规模网页爬取不被封禁的基础。
正确的代理策略取决于两个关键问题:目标网站能容忍何种类型的IP,以及你应如何轮换代理池。若这两点处理不当,后续所有防护层都将难以奏效;若处理得当,第2层至第4层的防护将变得更加灵活。接下来的两个小节将详细探讨这两个选择。
数据中心、住宅、ISP 和移动代理的对比
这四种实用的代理类型在IP来源、目标端感知效果、成本以及被封禁频率方面存在差异。
|
代理类型 |
来源 |
典型用途 |
抗封堵能力 |
|---|---|---|---|
|
数据中心 |
云服务和托管服务提供商 |
防御较弱的目标、内部工具、公共API |
对主要反僵尸网络供应商的抗阻能力较低;整个ASN常被列入封锁名单 |
|
ISP(静态住宅IP) |
托管于数据中心的真实 ISP 分配 IP 范围 |
持久会话、基于账户的爬取 |
中等;优于数据中心但仍可能被标记 |
|
住宅(轮换) |
通过经授权的对等网络连接的真实宽带 |
电商、旅游、社交媒体及多数防御严密的目标 |
高;流量与普通用户无异 |
|
移动(3G/4G/5G) |
运营商分配的移动IP地址 |
优先支持移动端的网站,以及对IP流量限制非常严格的网站 |
极高;运营商NAT意味着每个IP地址由大量真实用户共享 |
一个实用的经验法则。如果目标是一个没有指定反机器人服务商的小型网站,数据中心IP通常可行且成本低廉得多。如果响应中出现Cloudflare、Akamai、DataDome或PerimeterX的验证挑战,请直接升级为轮换住宅IP,因为数据中心IP可能需要数周时间才能稳定生效,期间会造成资金浪费。 移动IP仅适用于最难攻克的目标和预算最高的情况,因为这是最昂贵的代理类别,且资源确实稀缺。
免费代理列表几乎会立即暴露你的行踪。其IP池规模微小,且所有使用同一列表的爬虫都会共享这些IP,更常见的是,在你发现它们之前,它们往往已被列入商业封禁名单。这类资源仅适用于快速实验,绝不可用于生产环境。
对于大多数工程师而言,2026年的正确选择是具备国家级定位功能且拥有充足IP池的付费住宅代理网络。其计费方式按每千兆字节而非按IP地址计算,因此[规划住宅代理预算]主要在于估算带宽,而非IP地址数量。
IP轮换策略、会话粘性与地理定位
若使用不当,拥有庞大的代理池也毫无意义。有三项设置决定了IP轮换究竟是真正有益还是暗中造成损害:轮换频率、会话粘性以及地理定位。
轮换频率。对于产品列表或搜索结果等无状态抓取,采用循环轮询(Round-robin)并在每次请求中使用新 IP 是最安全的默认设置。其优势在于,单个 IP 发送的流量永远不足以显得异常。缺点是,任何依赖 Cookie、购物车或登录会话的流量都会立即中断,因为服务器在每个跳转点都会看到不同的客户端。
会话粘性。对于多步骤流程、登录、使用服务器端游标的分页,以及任何使用 Cookie 或 CSRF 令牌的功能,您需要一个在可配置时长内保持不变的粘性 IP。大多数服务商支持 1 分钟至 30 分钟甚至更长的时长。请选择能完成流程的最短时长。在高流量端点上使用长时间的粘性会话,正是单个住宅 IP 积累足够流量从而被标记的原因。
地理定位。部分网站会根据国家/地区限制内容或定价,且许多服务会将访问本地专属服务的国际流量标记为异常。例如,仅服务于巴西的巴西外卖网站,在检测到得克萨斯州的住宅IP时,会礼貌地重定向或直接封禁。请将地理定位代理与匹配的 Accept-Language 标头以及在所有启动的浏览器中保持一致的时区,否则只是用一种不一致换取另一种不一致。
在代码层面,这通常意味着通过 country 和 session_id 查询字符串:
proxy = f"http://user-country-br-session-{uuid.uuid4().hex}:{password}@proxy.example.net:7777"
按请求轮换会丢弃会话 ID;粘性轮换则会在不同请求间复用该 ID。这两种方式在每个爬虫中切换的成本都应较低。
第二层:逼真的请求特征
即使拥有完美的住宅IP,如果您的客户端将自身标识为 python-requests/2.x。真实的浏览器会按特定顺序发送一组连贯的头部,使用特定的密码套件列表进行 TLS 协商,并通过特定的 SETTINGS 帧使用 HTTP/2。只要其中任何一项不匹配,请求就会在响应正文甚至尚未生成之前就被识别为自动化请求。
这是大多数自研爬虫泄露最多信号的层级,部分原因在于库默认使用会暴露身份的值,部分原因在于简单的修复方案——仅伪造 User-Agent——已不再足够。接下来的两个子章节将涵盖两个不可或缺的环节:构建浏览器级别的标头集,以及规避 TLS 和 HTTP/2 指纹识别。只要这两点都做对,对于任何仅支持 HTTP 的目标,第二层就不再是问题。
构建完整的浏览器级头部集
User-Agent 头部会告知服务器发起请求的浏览器及其版本,而默认的 cURL 或 python-requests 代理会立即将你标记为非浏览器流量。但仅发送伪造的 User-Agent 而忽略其他内容同样糟糕,因为真实的浏览器会按特定顺序发送一整套一致的头部信息。
最简洁的工作流程是:从开发者工具中复制真实的 Chrome 请求,将其固定为模板,并仅轮换那些在不同用户间实际会变化的值。一个最简生产环境头字段集如下所示:
HEADERS = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
"(KHTML, like Gecko) Chrome/124.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": "en-US,en;q=0.9",
"Accept-Encoding": "gzip, deflate, br, zstd",
"Sec-Ch-Ua": '"Chromium";v="124", "Google Chrome";v="124", "Not.A/Brand";v="24"',
"Sec-Ch-Ua-Mobile": "?0",
"Sec-Ch-Ua-Platform": '"Windows"',
"Sec-Fetch-Site": "none",
"Sec-Fetch-Mode": "navigate",
"Sec-Fetch-User": "?1",
"Sec-Fetch-Dest": "document",
"Upgrade-Insecure-Requests": "1",
}
几点规则。请确保客户端提示(Sec-Ch-Ua*)需与 User-Agent 保持一致。若声明使用 Chrome 124,则客户端提示必须显示 Chrome 124。切勿在每次请求中随机轮换 User-Agent:单个人类会话仅使用一个浏览器,因此在页面加载间切换 Chrome 和 Firefox 本身就是机器人信号。为 Referer ,使请求看起来像点击而非瞬间跳转。许多工程师会为非首页设置 Referer: https://www.google.com/ ,而后续页面则使用前一个 URL。
标头顺序也很重要。某些反机器人系统会对标头顺序进行哈希处理,因此即使所有值都正确,那些按字母顺序重新排序标头的库仍可能失败。这就是你最终必须放弃原生 requests ,转而采用针对爬取优化的[更深入的HTTP头部策略]。
规避 TLS 和 HTTP/2 指纹识别
一旦你的标头看起来正确,下一个暴露你的信号就是 TLS 握手本身。TLS 指纹识别基于客户端在 TLS 握手期间发送的特定值来唯一识别客户端,包括 TLS 版本、支持的密码套件、扩展列表以及所有这些的顺序。 有两种常见格式将这些信息汇总为哈希值:JA3 和较新的 JA4,反机器人供应商都会将这些哈希值与已知的浏览器配置文件进行比对。
对于爬虫而言,问题在于 python-requests, urllib3, aiohttp, node-fetch 所有这些工具生成的 TLS 握手过程都与 Chrome 或 Firefox 截然不同。它们会根据底层 OpenSSL 或 BoringSSL 库的偏好协商密码套件,并按该库偏好的顺序进行,这种握手过程与真实浏览器的区别显而易见。许多机器人检测系统主要依据这一特征来拦截请求,甚至在检查请求头之前就已采取行动。 若想详细了解每个步骤的具体表现,Mozilla开发者网络(MDN)关于TLS握手过程的概述是一份极具价值的入门指南。
解决方法是使用能在字节级别模拟特定浏览器 TLS 栈的客户端。有两个值得了解的选项:
curl-impersonate这是一个基于 cURL 的分支,其 TLS 和 HTTP/2 栈经过了修补,生成的握手数据与 Chrome、Edge、Firefox 或 Safari 完全一致。你可以将其作为即插即用的curl_chrome120二进制文件安装,并在爬虫中调用它。tls-client是一个 Python(和 Go)库,它封装了一个经过修补的 Go TLS 实现,以模拟浏览器握手,并提供命名配置文件,例如chrome_124和firefox_125。若您希望保持纯 Python 环境,这是更便捷的选择。
HTTP/2 也有其独特的指纹特征。不同浏览器在 SETTINGS 帧、头部伪头部以及流优先级方面存在差异,现代检测器也会对这些值进行哈希计算。上述两个库均支持 HTTP/2 层,因此选择其中任何一个都能通过一次切换同时获得这两种指纹特征。
实用技巧:当您更改伪装配置文件时,请同步调整 User-Agent 以保持一致。一个声称是 Firefox 却像 Chrome 那样协商 TLS 的请求,比原本的不匹配更强烈地表明这是机器人。
第 3 层:针对 JavaScript 密集型目标的隐形浏览器
如果目标站点提供 JavaScript 验证、交互式控件,或是在客户端构建 DOM 的单页应用,那么无论 HTTP 客户端的指纹多么完美,都无法正常工作。你需要一个能执行 JavaScript 的真实浏览器,而这通常意味着需要使用无头浏览器——一种无需用户界面、通过编程方式控制的自动化浏览器。
其代价相当高昂。单个无头 Chrome 实例便会轻松占用数百兆字节的内存,而在一台机器上并行运行多个实例,很快就会触及远低于 HTTP 客户端所能承受的内存上限。启动浏览器也需要数秒而非数毫秒,因此并发限制和预热池模式比在 requests.
请仅在必要时使用隐身浏览器,而非将其作为默认选择。若能逆向工程出单页应用(SPA)背后的 JSON 端点(我们稍后会介绍),请优先采用该方案。当无法实现时,接下来的两个小节将详细讲解当前 2026 年的隐身技术栈,以及如何强化主流自动化库而非与其对抗。
Camoufox、Nodriver、undetected_chromedriver 和 curl-impersonate
2026 年的隐身技术栈已从基于 Selenium 的重量级封装工具转向更小巧、补丁更激进的工具。
undetected_chromedriver是该领域的元老级工具。它修补了 Chrome 中最明显的自动化特征,移除了navigator.webdriver,并调整 CDP 接口以避免暴露自身。它对许多中级目标仍然有效,但厂商已开始跟进其补丁,因此应将其视为已知特征而非万能解药。- Nodriver 是一款较新的 Python 工具,它通过 DevTools 协议驱动 Chrome,无需 WebDriver,从而消除了整类自动化特征。当您需要浏览器级执行但希望最小化 WebDriver 暴露面时,这是一个不错的默认选择。
- Camoufox 是一款针对爬取任务进行过调优的 Firefox 定制版本。根据其公开定位,它利用 Firefox 的灵活性来改变那些基于 Chromium 的工具难以改变的指纹特征,因此对于针对 Chrome 深度优化的检测器最为有效。在将其投入生产环境前,请务必确认其当前的维护状态。
curl-impersonate它根本不是浏览器,但仍应纳入讨论范围,因为对于相当多的目标而言,一个伪装成 TLS 的 HTTP 请求就已足够,且能避免真实浏览器带来的所有开销和脆弱性。在考虑 Chrome 之前,请先尝试它。
如何选择。请按以下顺序尝试: curl-impersonate 或 tls-client 优先;若页面确实需要 JavaScript,则升级至 Nodriver;若基于 Chromium 的隐身模式被检测到,请尝试 Camoufox;若您受限于旧版 Selenium 管道,请对其进行加固(见下一小节),而非从头重写。这些工具均非静态目标;随着检测器和补丁的演进,预计每隔几个季度需重新评估您的选择。
强化 Playwright、Puppeteer 和 Selenium
大多数团队已经构建了基于 Playwright、Puppeteer 或 Selenium 的自动化技术栈。与其从头重写,不如强化现有方案。
以下三个插件承担了大部分工作:
playwright-stealth修复了最明显的 Playwright 指纹泄露问题:navigator.webdriver,包括插件数组、语言设置、WebGL 供应商字符串。puppeteer-extra-plugin-stealth这是 Puppeteer 的对应版本,且正在积极维护中。- SeleniumBase UC 模式在底层对 Selenium 进行了相同补丁的封装,并集成了 undetected-chromedriver,这是针对传统 Selenium 代码库最经济的升级方案。
插件虽不可或缺,但仅靠它们还不够。以下几个操作细节同样至关重要:
- 设置合理的视口。默认的无头模式尺寸如
800x600等,会被识别为机器人信号。请使用常见分辨率,例如1366x768或1920x1080. - 确保语言、时区和地理位置与代理服务器匹配。一个
en-US语言环境和America/New_York的巴西代理在内部存在矛盾。 - 使用持久的用户数据目录。一个没有任何历史记录、Cookie、扩展程序和字体缓存的原始浏览器配置文件本身就是一种指纹。在流程允许的情况下,跨运行重复使用配置文件。
- 安装与您声称的操作系统相符的字体和插件。Windows User-Agent 搭配 Linux 字体集将导致一致性检查失败。
- 禁用您不需要的自动化友好标志。
--disable-blink-features=AutomationControlled是典型的示例。
看起来“过于干净”的配置文件会触发与明显自动化配置文件相同的启发式检测。目标是模拟一个可信的、平庸的真实用户,而非全新安装的环境。
第 4 层:行为模拟
即使拥有干净的 IP、完美的请求头、真实的 TLS 指纹以及经过强化的隐身浏览器,您的爬虫仍可能因行为信号而被标记。真实用户会暂停、以不均匀的速度滚动、悬停后再点击,并花不同长短的时间阅读页面。 一个爬虫如果数小时内每隔 1.000 秒发送完全相同的请求,或者加载页面后立即访问一个人类绝不会手动输入的深度嵌套 URL,仅凭时间间隔就很容易被检测出来。
这一层也是最容易解决的,因为它不需要新的基础设施。它只需要抛弃“爬取速度必须尽可能快”这一假设。接下来的两个小节将介绍两个最重要的模式:带有适当退避机制的抖动请求速率,以及浏览器内的类人交互模式。二者结合,便能弥合隐形爬虫与真实用户之间的差距。
随机化请求频率并添加指数级回退
一个每天 24 小时、每秒精确发送一次请求的爬虫很容易被检测到,因为没有真实用户会以这种方式使用网站。两项改动就能解决最严重的问题。
延迟抖动。基于真实分布生成的随机间隔是避免被基于速率的检测器封禁的网络爬虫基础,且实现成本几乎为零。简单的对数正态或均匀抖动可避免请求时间戳中明显的“梳状”分布:
import random, time
def polite_sleep(min_s=1.5, max_s=4.5):
time.sleep(random.uniform(min_s, max_s))
429 和 503 状态码的指数退避。现代 API 和许多 Web 服务器都提供了 RateLimit-Limit, RateLimit-Remaining以及 RateLimit-Reset 头部,以及 Retry-After 在 429 状态码中。请务必读取这些信息,切勿忽视。一个务实的循环:
def fetch_with_backoff(url, max_retries=5):
delay = 2.0
for attempt in range(max_retries):
r = session.get(url, headers=HEADERS)
if r.status_code in (429, 503):
retry_after = float(r.headers.get("Retry-After", delay))
time.sleep(retry_after + random.uniform(0, 1))
delay *= 2
continue
return r
raise RuntimeError(f"giving up on {url}")
并发限制。即使使用了抖动,从一个家庭IP同时建立200个连接也显得异常。请针对每个IP设置并发上限,而非仅做全局限制;50个IP地址各建立一个连接访问同一主机,看起来要比一个IP同时保持50个连接自然得多。避开高峰时段进行调度(例如在服务器当地时间午夜刚过时),也能大幅降低被察觉的风险。
多样化爬取模式并模拟鼠标活动
对于基于浏览器的抓取,行为信号不仅体现在时间上,还延伸至 DOM 本身。现代检测器会追踪滚动深度、鼠标移动轨迹、聚焦元素的停留时间、点击顺序,甚至表单中的按键节奏。
以下三种模式值得纳入设计:
- 自然滚动,再操作。在点击“加载更多”按钮或提取数据之前,应分两到三次不规则地滚动页面,而非一次性跳转到底部。Playwright 的
mouse.wheel等工具可轻松实现这一点。 - 先悬停,后点击。真实用户会将光标移动至目标位置,有时会超出目标范围并进行修正。Selenium的鼠标交互API和Playwright的
mouse.move支持中间步骤,因此一条短暂的曲线轨迹就足以模拟人类行为。 - 改变点击顺序。从列表中提取项目时,不要总是先点击第一张卡片,再点击第二张,然后是第三张。在合理范围内打乱顺序;人类的浏览方式本就杂乱无章。
同等重要的是:切勿过度。一个滚动 4,000 像素、悬停时间精确到 800 毫秒、并生成毫米级精准贝塞尔曲线鼠标轨迹的爬虫,同样是一种指纹,只不过是更复杂的指纹罢了。将随机性限制在现实的范围内。如果真实用户在产品页面停留两到十秒,不要仅仅因为“更像人类”就引入三十秒的停顿。
爬行模式同样重要。要多样化入口点,像好奇的用户那样点击链接(相关商品、面包屑导航、搜索),并避免只猛攻深层分页URL却从未访问首页。会话图的形态本身就是一种信号。
应对超越 TLS 的高级指纹识别
浏览器/设备指纹识别通过收集操作系统版本、浏览器版本、导航栏字段、插件、字体及图形行为等软硬件细节,为每位访客构建近乎唯一的标识符。TLS是其中最显著的单一信号,但供应商还在其上叠加了至少六种JavaScript层面的识别途径:
- Canvas 指纹识别。浏览器渲染一个包含文本和图形的不可见 2D 画布,然后对生成的像素进行哈希运算。不同设备间驱动程序和字体的细微差异使得哈希值在每台设备上保持稳定。
- WebGL。供应商和渲染器字符串(
UNMASKED_VENDOR_WEBGL,UNMASKED_RENDERER_WEBGL)结合精度和着色器行为,可识别 GPU 和驱动程序。隐形插件必须始终如一地伪造这些信息,否则就会暴露在假操作系统下的真实 GPU。 - AudioContext。静音音频缓冲区中的采样率和处理伪影在不同系统上的哈希值各异,且出人意料地稳定。
- 字体枚举。可用字体列表高度依赖于操作系统和区域设置。声称运行 Windows 10 却没有 Windows 默认字体的浏览器值得怀疑。
navigatorsurface.userAgent,platform,hardwareConcurrency,deviceMemory,languages,webdriver. 来自干净隐身配置文件的默认值往往相互矛盾。- 时区、区域设置和分辨率。
Intl.DateTimeFormat().resolvedOptions().timeZone,navigator.language以及屏幕尺寸必须彼此一致,并符合您的 IP 地理位置。
让大多数团队中招的故障模式是信号之间的不一致,而非任何单一的错误信号。一个美国的住宅IP、一个 en-US Accept-Language、 Europe/Bucharest 时区,以及隐藏在 Windows 用户代理后面的 Linux WebGL 渲染器,其可疑程度远高于这些因素单独出现的情况。将指纹强化视为一致性问题:选择一个目标用户画像(Windows 11、Chrome 124、en-US、美国东部时区、GTX 级 GPU 字符串),并确保所有接口呈现一致的信息。
现成的反检测浏览器能自动为你实现这种一致性,但在生产环境中信任它们之前,请务必通过指纹测试页面验证其补丁。
在不耗尽预算的情况下处理 CAPTCHA
验证码(CAPTCHA)可以是谜题、图片网格、勾选框或隐形挑战,用于区分人类与机器人。验证码通常在 IP 地址看起来可疑时触发,因此最经济的验证码策略是预防:使用更好的代理、更优的请求头、更完善的指纹,并降低请求速率,从而从源头上避免触发机制。
当预防措施失效时,您有三种选择:
- 自行解决。2Captcha、CapMonster 和 Anti-Captcha 等服务会接收挑战图片或令牌,将其交给工人池或机器学习模型处理,并返回一个解决方案令牌供您的爬虫提交。这种方法虽然可行,但成本和延迟会迅速累积。 粗略估算:每 1,000 次图像识别约需 1 至 3 美元,每 1,000 次 reCAPTCHA 验证码处理约需 1.50 至 3 美元(制定预算前请核实当前价格)。若爬虫每天发送 100 万次请求,其中 5% 触发了 CAPTCHA,仅识别费用一项,每日支出就相当可观。
- 将请求层卸载出去。托管式爬取 API 会将 CAPTCHA 作为请求的一部分进行处理,并自动解决或绕过验证,因此您只需为成功获取的 HTML 付费,且完全不会接触到验证挑战。在规模化应用时,这种方案通常比自建代理加 CAPTCHA 处理栈更经济。
- 避开表层。许多验证码保护的页面并非获取数据的唯一途径。搜索 API、JSON 接口和产品数据源通常会直接提供相同内容,且不包含验证层;接下来我们将介绍如何发现这些替代途径。
正确的解决方案通常是预防(针对大部分请求)与破解或卸载(针对剩余请求)相结合。全量破解几乎总是成本最高的策略。
避开蜜罐陷阱并遵守 robots.txt
蜜罐是指那些被刻意隐藏在真实用户视线之外、却对无经验爬虫可见的链接或 DOM 元素。一旦点击,网站会将您的指纹记录为自动化行为,并可能在未来每次请求中封禁同一客户端。在 JavaScript 中,经典的蜜罐模式很容易被识别:
function isLikelyHoneypot(el) {
const s = getComputedStyle(el);
if (s.display === "none" || s.visibility === "hidden") return true;
if (parseFloat(s.opacity) === 0) return true;
const r = el.getBoundingClientRect();
if (r.left < -1000 || r.top < -1000) return true; // off-screen
if (s.color === s.backgroundColor) return true; // color-matched text
return false;
}
当您使用无头浏览器进行爬取时,请在跟随任何链接前运行此过滤器。当您解析静态 HTML 时,最经济的近似方法是读取内联 style 属性的 display:none, visibility:hidden,并忽略文本颜色与周围背景相匹配的链接。 position 值,并忽略文本颜色与周围背景色相匹配的链接。
robots.txtRFC 9309 中定义的是第二项关键要素。这是一个位于域名根目录下的文件,用于告知爬虫哪些路径禁止访问以及允许请求的频率。忽视该文件是导致被监控合规性的网站立即封禁 IP 的最快途径之一;即使在技术上未强制执行,它也明确表明了运营商的意图。在浏览器中将 /robots.txt ,或使用 Node.js 的等效实现,并同时遵守这两项规则。 urllib.robotparser 或 Node.js 的等效工具进行解析,并同时遵守 Disallow 规则和 Crawl-delay 指令。遵守 robots.txt 也是在您的抓取行为面临法律审查时可辩护的立场。
反向工程隐藏的 API 和移动端点
令人惊讶的是,许多看似“JavaScript 渲染”的内容,实际上是以 JSON 格式从页面在后台调用的内部 API 传来的。找到该 API 通常是你能采取的最具突破性的举措,因为它既绕过了渲染层,又跳过了 HTML 解析层,且其防护措施往往远不如公开的 HTML 严格。
操作流程:
- 打开 Chrome 开发者工具,进入“网络”选项卡,按 Fetch/XHR 过滤。
- 重新加载页面并重现操作(搜索、滚动、筛选、分页)。
- 按响应大小或域名排序。该 API 通常是
*.json或/api/*同一源或子域的 URL。 - 右键单击该请求并选择“复制为 cURL”。这将原样提供 URL、头部信息和正文内容。通过 Python 或 Node 重放该请求,并确认是否收到相同的 JSON 响应。
- 逐个移除请求头,以找出服务器实际检查的最小集合。
- 如果响应分页,请查找 cursor 或 offset 参数并编写循环。
几个值得注意的陷阱:
- 签名令牌或一次性令牌。某些接口会将请求的 HMAC 嵌入到头部或查询参数中,该值由页面加载时的 JavaScript 计算得出。如果直接重放返回 401 错误,请在页面资源包中查找生成该头部的函数;通常你需要复制签名逻辑,或者通过真实的浏览器环境代理该请求。
- 移动应用。移动客户端的请求通常比 Web 应用更难解码,且流量往往使用设备专属密钥进行签名。请使用 mitmproxy 或 Charles 等中间人代理,并在设备上安装自定义 CA 证书以捕获调用。与 Web 目标相比,此类场景通常需要进行更多逆向工程。
- CSRF 和会话 Cookie。许多内部 API 要求使用与真实浏览会话相同的 Cookie 集合。请先访问主页,存储 Cookie,然后在 API 调用中重复使用它们。
隐藏的 API 还能大幅降低你遭遇 CAPTCHA 的风险,因为它们通常是从已经通过验证的会话中调用的,且面临的验证挑战比周围的营销页面要少得多。
将爬取地理位置与目标受众匹配
地理位置是防御方最易验证的信号之一,也是爬虫最容易出错的环节。一家巴西外卖网站主要服务于巴西用户,因此来自得克萨斯州住宅IP的请求,在检查其余请求内容之前就已经属于异常情况。许多网站会对非目标区域的流量进行重定向、返回本地化的404错误,或显示虚假的地区定价。
解决方法是同时确保三点一致:
- 代理国家应与网站的主要用户群体一致。巴西网站,就应使用巴西的住宅IP。
Accept-Language与该地区设置相匹配,例如pt-BR,pt;q=0.9而非en-US.- 浏览器时区和区域设置也需匹配,可通过
Intl覆盖设置或隐身浏览器的启动选项进行设置。
若其中任何一项不符,一致性检查即告失败。防御方很少仅凭地理位置进行拦截,但当其他信号处于临界状态时,他们通常会将其作为决定性因素。在抓取特定地区的内容时,请将其视为基本要求。
将缓存和网络存档作为最后的备选方案
当实时抓取目标不经济时,变化缓慢的数据有时会保存在公共缓存中。经典的 Google 缓存技巧(在 URL 前缀 webcache.googleusercontent.com/search?q=cache: )据称已于2024年左右被弃用;在构建相关管道前,请务必验证其当前可用性。
三个值得了解的备用方案:
- Wayback Machine。来自
web.archive.org,可通过其 CDX API 进行批量时间戳查询。适用于历史快照,不适用于最新数据。 - Common Crawl。每月进行大规模网页抓取并以WARC格式存储,可通过其索引免费查询。最适合对数据时效性要求不高的一次性批量研究。
- Bing 缓存和 Brave Search 快照。规模较小且覆盖不均,但偶尔能捕获其他工具遗漏的页面。
缓存仅是备选方案,而非主要策略。务必向利益相关方明确说明数据时效性问题;六个月前的Wayback快照适用于SEO研究,但对实时定价分析毫无用处。
攻克主流反机器人服务商:Cloudflare、Akamai、DataDome、PerimeterX
若响应中出现 Cloudflare、Akamai、DataDome 或 PerimeterX 的拦截提示,说明您正在抓取高难度目标。各供应商对检测层的权重设置不同,因此突破它们的技术也各异。下表是面向 2026 年的初步指南;实施前请对照当前供应商文档及您自身的测试流量进行验证。
|
供应商 |
特征码挑战面 |
重点检测要素 |
典型的 2026 年起始技术栈 |
|---|---|---|---|
|
托管挑战、Turnstile、据称运行着经过混淆的客户端检查的 JS 插页广告 |
TLS/JA4指纹、IP信誉、JS挑战响应 |
|
|
|
由 JS 提交的 "sensor_data" 有效载荷,外加遥测信标 |
行为遥测数据,深度指纹一致性 |
具备真实鼠标/滚动行为的隐形浏览器;非常干净的住宅IP;持久的粘性会话 |
|
|
JavaScript 验证码挑战配合设备检测脚本;CAPTCHA 备用方案 |
浏览器指纹、无头模式检测、IP 类别 |
强化版 Playwright/Puppeteer 搭配隐身插件;住宅或移动 IP;时序抖动 |
|
|
|
行为信号、跨导航的 Cookie 状态 |
持久的浏览器上下文;在目标页面加载前进行完整的会话预热;住宅IP |
若干交叉规则。 对于仅支持 HTTP 的架构而言,受 Cloudflare 保护的目标通常是四者中最容易攻破的,因为仅凭 TLS 冒充就能绕过许多网站;只有最高敏感度级别才会强制要求使用真实浏览器。Akamai 和 PerimeterX 更重视行为特征,因此即使指纹完美,缺乏真实交互的隐形浏览器仍会失败。DataDome 在浏览器指纹识别方面最为严格,通常要求使用经过全面加固的 Chromium 浏览器并配合住宅 IP。
还有两点需知。首先,供应商的防护体系是动态变化的,本季度有效的补丁下季度可能失效;请预留返工预算。其次,不要以为单一工具就能通过所有四家。大多数生产环境管道最终会根据目标路由出两到三条不同的请求路径。若需更深入的 Cloudflare 特定策略,我们的 [Cloudflare 绕过指南] 记录了当前的方法和工具。
DIY 与 Web 爬虫 API:2026 年的决策框架
到了某个阶段,问题将不再是“如何抓取这些数据”,而是“是否应该运行这套技术栈”。真正的盈亏平衡点取决于四个因素:月请求量、目标系统的复杂程度、团队人数,以及工程师时间的价值。
请参考以下决策树:
- 月请求量低于数十万次,防御较弱的目标,一到两名工程师。自行开发即可。基础版
requests模式:小型数据中心或住宅IP池,配合基础的请求头优化即可应对。 - 月请求量达数百万,目标难度参差不齐,团队规模较小。这是危险地带。虽然技术上可以自建住宅代理、配合隐身浏览器和验证码破解,但维护负担(补丁失效、IP轮换、指纹漂移)往往会占用一名全职工程师的全部时间。一旦将薪资成本(而非仅基础设施成本)纳入考量,托管API通常会更划算。
- 数千万级流量,防御严密的目标,专职团队。混合方案通常是最佳选择:自行处理占80%的简单部分(您可掌控技术栈),将最难的20%(如Cloudflare、DataDome、PerimeterX等目标)交由托管API处理,这样工程时间就能用于数据产品开发,而非指纹识别的基础架构维护。
- 涉及任何受监管、需审计或对合规性敏感的场景。采用具备文档化合规资质的托管服务,几乎总是比自行构建审计日志更经济。
粗略估算,当前定价作为变量由您填入:
- 每月 DIY 成本 ≈ 住宅代理流量(GB)× 代理单价 + 浏览器基础设施成本 + 验证码破解成本 + (工程师全职人数 × 薪资占比)。
- 每月 API 成本 ≈ 成功请求数 × 每次请求的 API 价格。
代入您的实际数据。临界点通常低于工程师的预期,因为全职员工(FTE)这一项是最大开销,且容易被低估。我们自家的 WebScrapingAPI 爬虫 API 是此类方案的一个选项;适合您数据流的正确选择取决于哪些目标占用了您的大部分流量。
遵守合规要求:robots.txt、服务条款及数据保护
网络爬取在许多司法管辖区是合法的,但“合法”不等于“被允许”,仅关注技术层面的工程师往往低估了风险面。公共数据通常仍受版权、网站服务条款或数据保护法规的保护,且商业用途通常需要书面授权,无论数据是否无需登录即可访问。
最重要的四个方面:
robots.txt以及服务条款(ToS)。遵守Disallow规则并Crawl-delay。在进行大规模抓取前,请仔细阅读网站的服务条款。反抓取条款虽不总是具有法律约束力,但若发生纠纷,无视这些条款将削弱您的抗辩能力。- GDPR与CCPA。若您的抓取行为收集了欧盟或加州居民的个人数据(姓名、邮箱、个人资料,甚至可被视为IP地址),您即承担数据控制者的义务,包括合法依据、保留期限及删除流程。除非确有必要,否则应避免抓取个人数据。
- 《计算机欺诈与滥用法案》(CFAA)与“超出授权访问”。在美国,绕过登录验证或针对已明确撤销访问权限的系统进行抓取,曾引发《计算机欺诈与滥用法案》的诉讼。2021年的范布伦(Van Buren)裁决缩小了适用范围,但绕过技术访问控制仍存在风险。如有疑问,请勿进行。
- 身份验证与个人身份信息(PII)。请勿从非自有账户抓取数据,请勿重新发布个人身份信息(PII),并对所收集的任何数据实施适当的访问控制和保留政策。
当数据具有商业级价值时,务必获取书面授权。这比打官司划算。
速查表:哪种技术可阻止哪种封锁
当抓取工具突然失效时,可将此表作为快速参考。每行将检测信号与其所在的安全层及相应的应对技术关联起来。
|
检测信号 |
层级 |
解决方法 |
|---|---|---|
|
IP声誉 / ASN封锁 |
1 |
轮换住宅或移动代理;基于地理位置的代理池 |
|
标头异常 |
2 |
浏览器级标头集;一致的客户端提示;保留顺序 |
|
TLS / JA3 / JA4 指纹 |
2 |
|
|
JavaScript 挑战 |
3 |
强化版 Playwright/Puppeteer、Nodriver、Camoufox、undetected-chromedriver |
|
行为分析 |
4 |
抖动延迟、指数退避、真实的滚动/悬停/点击 |
|
验证码 |
1 + 3 |
优先采用更优质的代理和指纹识别;解码服务或托管API作为备用方案 |
|
地理位置/区域设置不匹配 |
1 + 2 |
国家匹配的代理 + Accept-Language + 时区 |
|
蜜罐链接 |
3 |
针对隐藏、屏幕外及颜色匹配锚点的 DOM 过滤器 |
解除爬虫封禁的最终要点
2026年避免被封锁的网页抓取最短可行方案如下:第一层使用轮换的住宅代理,配合一个模拟TLS的客户端(curl-impersonate 或 tls-client)配合第二层复制的Chrome请求头,第三层仅在JavaScript确实需要时才使用强化隐身浏览器,第四层采用带指数退避的时序抖动。将这四层整合后,再叠加指纹一致性与地理位置匹配机制。在更换工具前先诊断封锁原因,尽可能优先使用隐藏API而非渲染页面,并遵守 robots.txt 以及适用于您抓取操作的数据保护规则。缓存和归档仅是备选方案,而非核心策略。其余工作在于确保各层之间保持协调一致,而这正是大多数管道出现偏差的症结所在。
关键要点
- 在动用工具前先诊断该层。利用状态码、验证页面和无声伪数据,将阻塞定位到网络、请求签名、浏览器或行为层面;随后仅修复该层。
- 轮换住宅IP地址,配合真实的Chrome标头集以及TLS伪装,可突破大多数非厂商目标的防护。将隐身浏览器留给真正受JavaScript限制的页面。
- 指纹识别失败通常源于一致性问题,而非单一异常信号。选定一个用户画像(操作系统、浏览器、语言环境、时区、GPU),并确保所有交互界面呈现一致的信息。
- 防范 CAPTCHA 的成本远低于破解它。更好的代理和指纹技术能降低触发率;其余部分应交由服务或托管 API 处理,而非事必躬亲。
- 自建方案与托管 API 的选择主要取决于全职工程师(FTE)的成本。一旦需要一名全职工程师专门维护指纹识别和代理,托管 API 通常更为经济,尤其在与 Cloudflare、Akamai、DataDome 和 PerimeterX 对比时。
常见问题
如何判断是哪种反机器人系统(Cloudflare、Akamai、DataDome、PerimeterX)在拦截我?
检查响应。Cloudflare会留下 cf-ray 和 server: cloudflare 头部信息,并常会显示一个 JS 插页广告。Akamai 会设置 akamai-* 头部,并发送一个 sensor_data 有效负载。DataDome会注入 x-datadome 头部字段以及一个透明的品牌验证页面。PerimeterX(现为 HUMAN)设置一个 _px3 Cookie 并引用 px-captcha。通常只需几秒钟,通过 HTML 主体和 Cookie 即可识别出供应商。
用于数据抓取时,住宅代理是否总是优于数据中心代理?
不一定。住宅IP虽更难被封锁,但速度较慢,每千兆字节成本更高,且对于防御较弱的目标而言是过度配置。对于内部工具、公共API以及未部署知名反机器人解决方案的小型网站,数据中心代理速度更快、成本更低,且完全足够。仅当数据中心IP开始失效,或目标网站部署了大型反机器人防护体系时,才需升级使用住宅IP或移动IP。
哪些 HTTP 状态码通常表示被反机器人系统拦截,而非真正的服务器错误?
在TCP握手后立即返回的纯403状态码几乎总是意味着反机器人拦截,尤其是当响应体为空或仅包含微小的JSON错误时。带有 Retry-After 标头则属于真正的速率限制,应予以遵守。带有HTML插页(提及Cloudflare、DataDome或验证码)的503状态码是验证页面,而非服务中断。真正的服务器错误通常包含详细的内容主体,且不包含供应商特有的标头或Cookie。
如果目标服务器提供静态 HTML,我还需要无头浏览器吗?
通常不需要。如果所需数据包含在初始 HTML 响应中,使用像 curl-impersonate 或 tls-client ,配合真实的浏览器头部设置,其速度和成本都远优于启动 Chrome。当 JavaScript 构建 DOM、网站需要解决 JS 验证码,或必须生成行为遥测数据时,才应使用无头浏览器。
在什么情况下,从自建爬虫切换到托管式网页抓取 API 才是明智之举?
当您自建系统的维护工作量持续消耗的工程时间超过数据本身的价值时;当一个或多个目标网站迫使您使用代理、隐身浏览器及验证码层,而您无法保持其稳定性时;或者当合规与审计要求使得与有文档记录的供应商建立合作关系比构建自己的审计轨迹更经济时,就该进行切换。盈亏平衡点通常取决于全职员工(FTE)成本的计算,而非基础设施成本。
结论
要在 2026 年实现不被封禁的网页抓取,关键不在于花哨的技巧,而在于四个层面的严谨一致性。轮换的住宅代理负责网络层;复制的 Chrome 头部信息配合 TLS 和 HTTP/2 伪装处理请求签名层;仅在真正必要时使用的强化隐身浏览器负责应对 JavaScript 挑战;而抖动时序、真实的交互以及对 robots.txt 则负责行为层。在爬取领域胜出的团队会选择一个可信的角色,将所有信号与之对齐,并在更换工具前先在正确的层级诊断封禁原因。
如果您已厌倦了修补指纹、轮换 IP,以及每隔几周就追踪 Cloudflare 或 DataDome 的规则变更,那么现在可能是时候将请求层完全卸载了。 WebScrapingAPI 为您提供一个统一的接口,在后台自动处理代理轮换、TLS 伪装、JavaScript 渲染以及 CAPTCHA 绕过,让您的工程师能够专注于数据解析和分析,而非隐蔽技术的底层实现。建议您首先针对最难攻克的目标启用该服务,将 80% 的简单任务保留给自主开发,并让数据分析来决定何时该划清界限。




