绕过 PerimeterX 和 Akamai 的保护:反检测的实用方法
PerimeterX 和 Akamai Bot Manager 是两个最先进的防止机器人攻击的解决方案,广泛应用于大型电子商务平台、金融服务和企业网站。这些系统分析数百个浏览器参数、用户行为和网络特征,创建多层保护,无法通过简单更换 IP 地址来绕过。
在本指南中,我们将详细分析这两种系统的架构,研究它们的检测方法,并基于实际案例和技术实验制定全面的绕过策略。
PerimeterX 和 Akamai 的架构:检测如何工作
PerimeterX(现为 HUMAN Security)和 Akamai Bot Manager 作为多层保护系统,在请求处理的不同阶段进行嵌入。理解它们的架构对于制定绕过策略至关重要。
PerimeterX 的架构
PerimeterX 的工作分为三个阶段。在第一阶段,JavaScript 传感器嵌入到 HTML 页面中,并在客户端浏览器中执行,收集运行环境的数据:WebGL 指纹、Canvas 指纹、音频上下文、可用字体、插件、屏幕分辨率以及许多其他参数。该传感器经过混淆并定期更新,增加了分析的难度。
在第二阶段,PerimeterX 的服务器组件分析 HTTP 头、TLS 指纹、IP 声誉和网络特征,甚至在请求到达主应用程序之前。系统使用自己的已知机器人和可疑 IP 地址数据库,并实时更新。
第三阶段是行为分析。PerimeterX 跟踪鼠标移动、滚动速度、点击模式、操作间隔时间,并建立行为档案。机器学习模型将该档案与真实用户和已知机器人的模式进行比较。
Akamai Bot Manager 的架构
Akamai Bot Manager 在 CDN 层面进行集成,这使其在分析速度上具有优势。该系统使用自己的技术 BMP(Bot Manager Premier),在将请求传递到源服务器之前分析 Akamai 的边界服务器上的请求。
Akamai 的一个关键区别是使用来自数百万个受其 CDN 保护的网站的遥测数据。这使得系统能够快速识别新类型的机器人,并全球更新检测规则。Akamai 还使用类似于 PerimeterX 传感器的 Web SDK 技术,但更侧重于客户端完整性的加密验证。
重要: 两个系统都使用带有加密数据的 cookie 来存储验证结果。这些 cookie 在不知道服务器密钥的情况下无法伪造,因此在会话之间简单地复制 cookie 是无效的。
检测方法:保护系统分析什么
现代反机器人系统通过数百个参数分析请求,这些参数被归类为几类。理解每个类别可以系统性地消除自动化标记。
HTTP 头和 TLS 的分析
HTTP 头的顺序是检测的最简单方法之一。浏览器以严格定义的顺序发送头部,这在不同的版本和制造商之间有所不同。Python 中的 requests 或 Node.js 中的 axios 等库使用自己的顺序,立即暴露出自动化行为。
TLS 指纹(JA3 指纹)由 TLS 握手的参数生成:TLS 版本、支持的加密套件列表、扩展及其顺序。每个浏览器和操作系统的组合都会生成唯一的指纹。例如,Windows 11 上的 Chrome 120 的指纹与 macOS 上的 Chrome 120 或同一系统上的 Firefox 的指纹不同。
// User-Agent 和 TLS 指纹不匹配的示例
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/120.0.0.0
TLS Fingerprint: JA3 哈希对应 Python requests
// 结果:立即被阻止
JavaScript 执行环境
无头浏览器在 JavaScript 环境中留下数十个痕迹。检查 navigator.webdriver 属性、window.chrome 对象的存在、navigator.plugins 中的不一致、WebGL 和 Canvas 渲染中的异常。
PerimeterX 和 Akamai 使用先进的验证技术:测量 JavaScript 函数的执行时间(在无头浏览器中有所不同),检查 DOM 中的自动化伪影,分析函数调用栈。系统还检查数据的一致性——例如,如果 User-Agent 指示移动设备,但 navigator.maxTouchPoints 为 0,这会触发检测。
网络特征和 IP 声誉
保护系统通过多个参数检查 IP 地址:是否属于已知的代理提供商、是否在黑名单上、该 IP 的活动历史、地理位置与请求的其他参数(浏览器语言、时区)的一致性。
特别关注 IP 的使用模式。如果来自同一地址的请求具有不同的 User-Agent 或浏览器指纹,这是一种强烈的自动化信号。同样,如果在一个会话中 IP 变化过于频繁(激进的代理轮换),这会触发阻止。
| 检测参数 | PerimeterX | Akamai |
|---|---|---|
| TLS 指纹 | 高优先级 | 关键优先级 |
| Canvas 指纹 | 中等优先级 | 高优先级 |
| 行为分析 | 关键优先级 | 高优先级 |
| IP 声誉 | 高优先级 | 高优先级 |
| HTTP/2 指纹 | 中等优先级 | 关键优先级 |
浏览器指纹和 TLS 指纹
浏览器指纹是一种基于浏览器特征创建唯一标识符的技术。即使没有 cookies,保护系统也可以跟踪用户并识别异常。
Canvas 和 WebGL 指纹
Canvas 指纹通过渲染带有文本和图形的不可见图像来工作。由于图形驱动程序、字体和抗锯齿设置的差异,每个系统生成的图像略有不同。该图像的哈希值成为指纹的一部分。
WebGL 指纹使用 3D 渲染创建更独特的指纹。系统请求有关 GPU、支持的扩展、最大纹理大小和其他参数的信息。这些数据的组合生成的指纹具有足够的熵以识别设备。
// 获取 WebGL 指纹的示例
const canvas = document.createElement('canvas');
const gl = canvas.getContext('webgl');
const debugInfo = gl.getExtension('WEBGL_debug_renderer_info');
const vendor = gl.getParameter(debugInfo.UNMASKED_VENDOR_WEBGL);
const renderer = gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL);
// 结果可能是:“Google Inc. (NVIDIA)” + “ANGLE (NVIDIA GeForce RTX 3080)”
// 每个设备的唯一组合
音频上下文和字体
Audio Context API 允许基于音频处理创建唯一的指纹。操作系统中音频堆栈的差异导致音频信号处理中的微小差异,这些差异可以被测量并用于识别。
已安装字体的列表对于每个系统也是独特的。保护系统使用测量不同字体的文本大小的技术——如果字体未安装,浏览器会使用后备字体,这会改变大小。检查数百种字体会生成唯一的签名。
TLS 和 HTTP/2 指纹
JA3 指纹由 TLS Client Hello 的参数生成:SSL/TLS 版本、加密套件列表、扩展列表、支持的椭圆曲线组列表、椭圆曲线点格式。这些参数被连接并哈希,生成唯一的字符串。
HTTP/2 指纹分析 SETTINGS 帧的参数、流的顺序和优先级、窗口更新值。每个浏览器使用独特的 HTTP/2 设置,这使得即使在正确的 TLS 指纹下也能识别客户端。
实用建议: 绕过指纹识别需要确保所有参数的一致性。使用 Chrome User-Agent 和 Firefox TLS 指纹会立即被识别。像 curl-impersonate 或 tls-client 这样的工具有助于创建完全一致的指纹。
行为分析和机器学习
行为分析是现代反机器人系统中最难以绕过的方面。即使有完美的技术指纹,非人类的行为也会暴露出自动化。
鼠标移动和交互分析
PerimeterX 和 Akamai 跟踪鼠标移动轨迹、加速和减速、微小移动,这些都是人手特有的。机器人通常以直线移动光标,或者根本不生成鼠标事件。系统还分析反应时间——在页面加载后立即点击而没有鼠标移动看起来可疑。
滚动模式也很独特。人类以不均匀的速度滚动页面:开始时快速,减速以便阅读,有时向后滚动。机器人通常以恒定速度滚动,或使用 window.scrollTo() 进行瞬间滚动。
时间模式和行动速度
行动之间的时间是一个关键参数。人类不可能在 0.5 秒内填写 10 个字段的表单,或者在一分钟内点击 50 个链接。保护系统为每种类型的操作建立速度档案,并将其与用户的行为进行比较。
特别关注延迟的一致性。如果每次点击之间恰好间隔 2 秒,这是代码中明显的 sleep(2000) 的迹象。人类的延迟具有自然的变异性,并遵循特定的统计分布。
机器学习模型
两个系统都使用在数百万个真实用户和已知机器人的会话上训练的机器学习模型。模型同时分析数百个特征:操作序列、网站浏览深度、导航模式、与元素的交互。
PerimeterX 使用具有不同权重的模型集成,针对不同类型的网站。电子商务模型专注于购买模式,媒体网站模型专注于内容阅读模式。这使得绕过变得更加复杂,因为需要适应每个网站的特性。
// 具有变异性的类人延迟示例
function humanDelay(baseMs) {
// 使用对数正态分布而不是均匀分布
const variance = baseMs * 0.3;
const delay = baseMs + (Math.random() - 0.5) * variance;
// 添加特征的微小延迟
const microDelay = Math.random() * 50;
return Math.max(100, delay + microDelay);
}
// 使用:await new Promise(r => setTimeout(r, humanDelay(2000)));
代理选择和轮换策略
选择代理类型和轮换策略在与 PerimeterX 和 Akamai 的交互中至关重要。错误的代理配置将使所有掩盖浏览器指纹的努力付诸东流。
住宅代理 vs 移动代理 vs 数据中心代理
数据中心代理 成本最低,但检测风险最高。PerimeterX 和 Akamai 支持数据中心 IP 地址数据库,并自动提高对这些请求的检查级别。仅在低优先级任务或与高质量浏览器指纹结合使用时,才能使用数据中心代理。
住宅代理 使用真实互联网服务提供商的 IP 地址,大大降低了检测的可能性。然而,住宅代理的质量差异很大。选择具有干净 IP 池的提供商非常重要,这些地址之前未被用于垃圾邮件或其他可疑活动。
移动代理 提供最高的信任级别,因为它们使用移动运营商的 IP 地址。这些地址通常在多个用户之间共享(运营商级 NAT),这使得阻止变得困难。移动代理在对抗 Akamai 时尤其有效,因为 Akamai 对移动流量的阻止更加谨慎。
轮换策略
激进轮换(每个请求更换 IP)是一个常见错误。这会产生可疑的模式:一个用户不可能每几秒就物理更换 IP。会话轮换更有效,其中一个 IP 用于完整的用户会话(10-30 分钟的活动)。
对于长期操作,建议使用持续会话,持续时间为 30-60 分钟。这模拟了真实用户在会话期间保持在一个 IP 上的行为。同时,重要的是不要使用一个 IP 太久——持续几个小时的会话也会显得可疑。
地理一致性
确保 IP 地址的地理位置与其他参数(浏览器语言、时区、区域设置)之间的一致性至关重要。如果 IP 地址来自德国,但 navigator.language 返回“en-US”,而时区为“America/New_York”,这将立即触发检测。
在处理多个地理区域时,为每个区域使用单独的浏览器配置文件。在一个会话中切换区域(IP 来自法国,然后来自日本)对真实用户来说是不可能的,并会立即被识别。
| 代理类型 | 对 PerimeterX 的有效性 | 对 Akamai 的有效性 | 建议 |
|---|---|---|---|
| 数据中心 | 低(30-40%) | 非常低(20-30%) | 仅用于测试 |
| 住宅 | 高(75-85%) | 中等(65-75%) | 大多数任务的主要选择 |
| 移动 | 非常高(85-95%) | 高(80-90%) | 用于关键任务和高保护网站 |
反检测浏览器和工具的设置
正确配置自动化工具是成功绕过 PerimeterX 和 Akamai 的关键因素。即使是最好的代理也无济于事,如果浏览器指纹包含明显的自动化标记。
Playwright 和 Puppeteer:高级配置
基本安装 Playwright 或 Puppeteer 会创建明显的无头浏览器。需要使用隐形插件和额外配置来掩盖自动化。库 puppeteer-extra-plugin-stealth 隐藏主要标记,但需要额外的设置。
// 带反检测的 Playwright 高级配置
const { chromium } = require('playwright-extra');
const stealth = require('puppeteer-extra-plugin-stealth')();
chromium.use(stealth);
const browser = await chromium.launch({
headless: false, // 无头模式容易被检测
args: [
'--disable-blink-features=AutomationControlled',
'--disable-features=IsolateOrigins,site-per-process',
'--disable-site-isolation-trials',
'--no-sandbox',
'--disable-setuid-sandbox',
'--disable-dev-shm-usage',
'--disable-accelerated-2d-canvas',
'--disable-gpu',
'--window-size=1920,1080',
'--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
]
});
const context = await browser.newContext({
viewport: { width: 1920, height: 1080 },
locale: 'en-US',
timezoneId: 'America/New_York',
permissions: ['geolocation', 'notifications'],
geolocation: { latitude: 40.7128, longitude: -74.0060 }
});
Selenium 与 undetected-chromedriver
标准 Selenium WebDriver 容易通过 navigator.webdriver 属性被检测。库 undetected-chromedriver 自动修补 ChromeDriver,删除主要的自动化标记,并定期更新以绕过新的检测方法。
import undetected_chromedriver as uc
from selenium.webdriver.chrome.options import Options
options = Options()
options.add_argument('--disable-blink-features=AutomationControlled')
options.add_argument('--disable-dev-shm-usage')
options.add_argument('--no-sandbox')
options.add_argument('--window-size=1920,1080')
# 使用特定版本的 Chrome 以保持一致性
driver = uc.Chrome(options=options, version_main=120)
# 通过 CDP 进行额外的掩盖
driver.execute_cdp_cmd('Network.setUserAgentOverride', {
"userAgent": 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
})
driver.execute_script("Object.defineProperty(navigator, 'webdriver', {get: () => undefined})")
反检测浏览器:AdsPower、Multilogin、GoLogin
商业反检测浏览器提供了管理指纹的现成解决方案。AdsPower 和 Multilogin 允许创建具有独特 Canvas、WebGL、音频指纹的配置文件,并通过 API 进行管理。这些工具在处理多个账户时尤其有用。
关键优势是能够在会话之间保持一致的指纹。每个配置文件具有固定的 Canvas、WebGL、字体参数,这对长期工作至关重要。同时,重要的是使用现实的配置——生成随机指纹可能会产生技术上不可能的组合,这些组合很容易被识别。
具有正确指纹的 HTTP 客户端
对于不需要 JavaScript 渲染的任务,具有正确 TLS 和 HTTP/2 指纹的 HTTP 客户端更有效。库 curl-impersonate(Python 中为 curl_cffi)和 tls-client 允许模拟真实浏览器的 TLS 指纹。
from curl_cffi import requests
# 模拟 Chrome 120 的正确 TLS 和 HTTP/2 指纹
response = requests.get(
'https://example.com',
impersonate="chrome120",
proxies={
"http": "http://user:pass@proxy:port",
"https": "http://user:pass@proxy:port"
},
headers={
'Accept-Language': 'en-US,en;q=0.9',
'Accept-Encoding': 'gzip, deflate, br',
'sec-ch-ua': '"Not_A Brand";v="8", "Chromium";v="120"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-platform': '"Windows"'
}
)
# TLS 指纹自动对应 Chrome 120
无触发检测的自动化技术
即使有完美的技术指纹,自动化模式也可能暴露出机器人。需要在与网站的交互层面模拟人类行为。
模拟鼠标移动
从点 A 到点 B 的直线鼠标移动是自动化的明显标志。人类的手会产生平滑的曲线和微小的修正。像 pyautogui 这样的库可以生成使用贝塞尔曲线的真实轨迹。
// 生成类人鼠标轨迹
async function humanMouseMove(page, targetX, targetY) {
const current = await page.evaluate(() => ({
x: window.mouseX || 0,
y: window.mouseY || 0
}));
const steps = 25 + Math.floor(Math.random() * 15);
const points = generateBezierCurve(current.x, current.y, targetX, targetY, steps);
for (let point of points) {
await page.mouse.move(point.x, point.y);
await new Promise(r => setTimeout(r, 10 + Math.random() * 20));
}
// 点击前的微调
await page.mouse.move(targetX + (Math.random() - 0.5) * 2,
targetY + (Math.random() - 0.5) * 2);
}
function generateBezierCurve(x1, y1, x2, y2, steps) {
const cp1x = x1 + (x2 - x1) * (0.3 + Math.random() * 0.2);
const cp1y = y1 + (y2 - y1) * (0.3 + Math.random() * 0.2);
const points = [];
for (let i = 0; i <= steps; i++) {
const t = i / steps;
const x = Math.pow(1-t, 2) * x1 + 2 * (1-t) * t * cp1x + Math.pow(t, 2) * x2;
const y = Math.pow(1-t, 2) * y1 + 2 * (1-t) * t * cp1y + Math.pow(t, 2) * y2;
points.push({x: Math.round(x), y: Math.round(y)});
}
return points;
}
真实的滚动和内容阅读
人类会滚动页面以阅读内容,并在有趣的部分停下来。机器人通常会快速滚动到页面底部或所需元素。模拟阅读需要分析内容并创建真实的暂停。
async function humanScroll(page, targetElement) {
const elementPosition = await page.evaluate(el => {
const rect = el.getBoundingClientRect();
return rect.top + window.pageYOffset;
}, targetElement);
const currentScroll = await page.evaluate(() => window.pageYOffset);
const distance = elementPosition - currentScroll;
const scrollSteps = Math.floor(Math.abs(distance) / 100);
for (let i = 0; i < scrollSteps; i++) {
const scrollAmount = (distance / scrollSteps) * (0.8 + Math.random() * 0.4);
await page.evaluate((amount) => {
window.scrollBy({top: amount, behavior: 'smooth'});
}, scrollAmount);
// 随机暂停以“阅读”
if (Math.random() > 0.7) {
await new Promise(r => setTimeout(r, 1000 + Math.random() * 2000));
} else {
await new Promise(r => setTimeout(r, 200 + Math.random() * 400));
}
}
}
自然的导航模式
用户不会直接跳转到目标页面——他们会自然地与网站互动。从主页开始,访问几个部分,使用搜索或导航菜单。这创造了一个互动历史,提高了保护系统的信任度。
还需要模拟错误和修正——人类可能会点击错误的链接并返回,或者在搜索框中输入错误并纠正拼写。理想的直接路径看起来可疑。
管理 cookies 和存储
PerimeterX 和 Akamai 使用 cookies 和 localStorage 来跟踪会话。在请求之间完全清除 cookies 看起来可疑——真实浏览器会保留一些 cookies(分析、设置)。在同一“用户”之间保留 cookies,但对不同配置文件使用不同的 cookies 集合。
重要: 保护系统分析 cookies 的年龄。如果保护 cookie (_px, _abck) 刚刚出现,但用户表现出常客的行为——这就是不一致。对于长期操作,"预热" 配置文件,创建访问历史。
实际案例和常见问题的解决方案
让我们考虑具体的绕过 PerimeterX 和 Akamai 的场景,以及在过程中出现的常见问题的解决方案。
案例 1:使用 PerimeterX 进行电子商务解析
任务:从大型电子商务网站提取产品数据,该网站受到 PerimeterX 的保护。该网站在 3-5 个请求后即使来自不同的 IP 也会阻止访问。
解决方案: 使用住宅代理与持续会话(30 分钟)和 Playwright 完全模拟行为的组合。关键点:从主页开始,使用搜索或类别进行导航,在请求之间添加 3-7 秒的随机延迟,模拟滚动和鼠标移动。至关重要的是在同一会话中保留 _px cookies。
// 预热会话的示例
async function scrapeWithWarmup(page, targetUrls) {
// 预热配置文件
await page.goto('https://example.com');
await humanScroll(page, await page.$('footer'));
await new Promise(r => setTimeout(r, 3000 + Math.random() * 2000));
// 通过菜单导航
await humanMouseMove(page, menuX, menuY);
await page.click('nav a.category');
await new Promise(r => setTimeout(r, 2000 + Math.random() * 1000));
// 仅在预热后转到目标页面
for (let url of targetUrls) {
await page.goto(url);
await humanScroll(page, await page.$('.product-info'));
// 提取数据
const data = await page.evaluate(() => extractProductData());
await new Promise(r => setTimeout(r, 5000 + Math.random() * 3000));
}
}
案例 2:绕过 Akamai 的 API 请求
任务:访问受 Akamai Bot Manager 保护的 API。API 需要特定的头部和由页面上的 JavaScript 生成的令牌。
解决方案: Akamai 通常使用 sensor_data——一个包含浏览器验证结果的加密字符串。该字符串由 JavaScript 生成,并应包含在请求中。使用浏览器自动化获取有效的 sensor_data,然后在具有正确 TLS 指纹的 HTTP 客户端中应用它。
// 通过浏览器提取 sensor_data
async function getSensorData(page) {
await page.goto('https://example.com');
// 等待 Akamai 传感器执行
await page.waitForTimeout(5000);
// 从 cookie 或 localStorage 中提取 sensor_data
const sensorData = await page.evaluate(() => {
const cookie = document.cookie.split(';')
.find(c => c.trim().startsWith('_abck='));
return cookie ? cookie.split('=')[1] : null;
});
return sensorData;
}
// 在 HTTP 客户端中使用
const sensorData = await getSensorData(page);
const response = await fetch('https://example.com/api/data', {
headers: {
'Cookie': `_abck=${sensorData}`,
'User-Agent': 'Mozilla/5.0...',
// 其他头部应与浏览器一致
}
});
案例 3:解决 CAPTCHA 和挑战页面
问题:即使配置正确,PerimeterX 或 Akamai 有时也会显示挑战页面或 CAPTCHA 以进行额外验证。
解决方案: PerimeterX 的挑战页面通常执行额外的验证...