在浏览器自动化(如 Playwright、Selenium)的世界里,去痕(Stealth)的意思很简单:脱掉浏览器的“机器人工作服”,换上普通人的“便服”。

当你用 Playwright 打开一个网页时,浏览器其实自带了很多“我是自动化工具”的底层标记。像 Akamai 这种高级风控,一眼就能看出你是个机器人。去痕,就是把这些暴露身份的蛛丝马迹全部抹掉或伪装起来。

咱们以 Playwright 为例,通俗地聊聊它是怎么被发现的,以及怎么做去痕。

一、 浏览器自动化有哪些“原罪”?(为什么会被发现)

如果不做任何处理,用代码启动的浏览器在风控系统眼里就像“裸奔”,主要漏洞有:

  1. navigator.webdriver 标志
    这是最致命的一点。自动化浏览器的这个属性默认是 true,而正常人类浏览器的这个属性是 undefined 或 false。

  2. 自动化特征参数(CDP 痕迹)
    Chrome 浏览器暴露给开发者的 DevTools Protocol(调试协议)会在内存中留下一些全局变量或特征(例如某些特殊的属性注入)。

  3. 环境残缺
    比如正常的 Chrome 浏览器有完整的插件列表、PDF 预览插件、语言、硬件加速指纹(WebGL/Canvas),而纯净的自动化环境往往“干净得过头”,插件为空、硬件信息异常。

  4. 运行行为死板
    直接用 headless: true(无头模式)运行,连显卡渲染都没有,或者视窗大小固定得像个模具。

二、 Playwright 怎么做去痕?

在 Playwright 中实现去痕,通常有两种主流方式:用现成的插件(最快)和手动注入脚本(最灵活)

方案 1:使用现成的开源库(推荐新手)

社区里有大佬专门做了一套针对 Playwright 的去痕库,叫 playwright-stealth。它能自动帮你把大部分基础指纹改掉。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from playwright.sync_api import sync_playwright
from playwright_stealth import stealth_sync

with sync_playwright() as p:
browser = p.chromium.launch(headless=False) # 建议配合有头模式
context = browser.new_context()
page = context.new_page()

# 核心:一键应用去痕
stealth_sync(page)

page.goto("https://bot.sannysoft.com/") # 这是一个专门测试浏览器指纹的网站
page.screenshot(path="stealth_test.png")
browser.close()

方案 2:手动修改与底子加固(更深层的“化妆”)

如果风控(如 Akamai)很严格,通用的 playwright-stealth 可能会被识别。你需要在启动浏览器时加上一些参数,并自己注入代码:

  1. 启动参数调整(Launch Arguments)
    在启动浏览器时,屏蔽掉自动化特征开关。
1
2
3
4
5
6
7
8
browser = p.chromium.launch(
headless=False,
args=[
"--disable-blink-features=AutomationControlled", # 禁用自动化控制特征
"--disable-infobars", # 隐藏“Chrome正在受到自动测试软件的控制”提示
"--start-maximized", # 最大化窗口
]
)
  1. 通过 addInitScript 篡改底层 JavaScript
    在页面加载前,提前把 navigator.webdriver 改写掉,并伪造一些正常浏览器的对象。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
context = browser.new_context()

# 在每个页面加载前执行这段 JS
context.add_init_script("""
// 1. 幹掉 webdriver 标志
Object.defineProperty(navigator, 'webdriver', {
get: () => undefined
});

// 2. 伪造 window.chrome 对象(无头模式下常缺失)
window.chrome = {
runtime: {},
app: {},
webstore: {},
};

// 3. 修复插件列表(让它看起来有插件)
Object.defineProperty(navigator, 'plugins', {
get: () => [1, 2, 3, 4, 5]
});
""")

三、 去痕里都有啥?(全方位的伪装项)

一个完整的去痕方案,通常会处理以下几个维度:

  1. JS 运行环境伪装
    修改 navigator、screen、window 对象的各种属性,使其与主流真实电脑(如 Windows 上的 Chrome)保持一致。

  2. WebGL / Canvas 指纹
    有些风控会通过在画布上画个图,然后对比像素点来识别显卡型号。去痕时可以对 WebGL 渲染做微小的扰动(Noise),防止被固定指纹追踪。

  3. 语言与时区匹配
    如果你的服务器在国外(IP 是美区),但浏览器的语言设置是中文、时区是东八区,这种矛盾的特征也会被 Akamai 标记。去痕时要保证 IP 地理位置、浏览器时区、语言、Accept-Language 请求头 四者高度一致。

  4. 关闭 Headless(无头模式)
    尽量不要用标准的 headless=true。如果必须在服务器上后台跑,建议使用 XVFB(虚拟显示服务),让浏览器以为自己在真正的屏幕上渲染,或者使用升级版的 Headless(Chrome 的 –headless=new 模式,并做好补环境)。

四、 避坑指南:去痕不是万能的

虽然做了 Stealth,但面对像 Akamai 这种顶级风控,单纯靠 playwright-stealth 往往还是不够的。

  1. Akamai 的盲区: Akamai 不仅看你的浏览器环境(JS 指纹),它还极度看重你的 网络层指纹(TLS/JA3/HTTP2) 和 行为轨迹。

  2. 如果你的 Playwright 连上网站的一瞬间,鼠标在屏幕上瞬移、或者压根没有鼠标轨迹,直接暴力狂点,哪怕你把 JS 环境伪装得再完美,Akamai 也会通过行为学把你判定为机器人。

现阶段的建议: 先用 Playwright 配合 playwright-stealth 去访问一些指纹测试网站(比如 bot.sannysoft.com),看看自己还挂了哪些红灯,逐项去补齐,然后再去挑战像 Akamai 这样的大 Boss