此仓库包含用于增强热门 Web 自动化库的补丁。具体来说,它针对 puppeteer 和 playwright 包。
自动化库或浏览器行为的某些方面无法通过设置或命令行开关进行调整。因此,我们通过修补库的源代码来解决这些问题。虽然这种方法很脆弱,并且可能随着库源代码的更改而失效,但我们的目标是在社区帮助下维护此仓库,使补丁保持最新。
开箱即用的 Puppeteer 和 Playwright 带有一些明显且易于检测的重大泄漏。无论你的代理、指纹和行为脚本有多好,如果没有打补丁,对任何主流网站来说,你都只是一面巨大的红旗。
🕵️ 你可以使用 rebrowser-bot-detector(源码和详情)轻松测试你的自动化设置是否会被主流的现代检测手段识别。
| 补丁前 👎 | 补丁后 👍 |
|---|---|
![]() | ![]() |
如果你不想处理补丁和所有可能的错误,这里有一个现成的解决方案。这些包只是在原始代码之上应用了 rebrowser-patches,仅此而已。
Puppeteer:rebrowser-puppeteer(源码)和 rebrowser-puppeteer-core(源码)
Playwright (Node.js):rebrowser-playwright(源码)和 rebrowser-playwright-core(源码)
Playwright (Python):rebrowser-playwright(源码)
开始使用的最简单方法是修改你的 package.json,使用新包但保留旧名称作为别名。这样,你无需更改自动化的任何源代码。操作方法如下:
package.json,将 "puppeteer": "^23.3.1" 和 "puppeteer-core": "^23.3.1" 替换为 "puppeteer": "npm:rebrowser-puppeteer@^23.3.1" 和 "puppeteer-core": "npm:rebrowser-puppeteer-core@^23.3.1"。注意:23.3.1 只是一个示例,请在 npm 上查看最新版本。npm install(或 yarn install)另一种方法是直接使用新包而不是原始包。以下是需要遵循的步骤:
package.json,将 puppeteer 和 puppeteer-core 包替换为 rebrowser-puppeteer 和 rebrowser-puppeteer-core。不要更改包的版本,只替换名称。npm install(或 yarn install)puppeteer 和 puppeteer-core,改为 rebrowser-puppeteer 和 rebrowser-puppeteer-core🚀 就这样!只需访问 rebrowser-bot-detector 页面并测试你打过补丁的浏览器。
我们的目标是维护并支持这些直接替代包的最新版本,但我们主要关注新版本,所以如果你还在使用 90 年代初的 puppeteer 13.3.7,也许是时候升级了。由于 API 相当稳定,升级很可能不会破坏任何东西。
Runtime.Enable 泄漏流行的自动化库依赖 CDP 命令 Runtime.Enable,该命令允许接收来自 Runtime. 域的事件。这对于管理用于在页面上执行 JavaScript 的执行上下文至关重要,是任何自动化过程的关键功能。
然而,有一种技术可以检测到此命令的使用,从而揭示浏览器正被 Puppeteer 或 Playwright 等自动化软件控制。这种技术被所有主流反机器人软件使用,例如 Cloudflare、DataDome 等。
我们准备了一篇关于此泄漏调查的完整文章,你可以在我们的博客中阅读。
有关此技术的更多详情,请阅读 DataDome 的博客文章:新版无头 Chrome 与 CDP 信号如何影响机器人检测。
简而言之,如果使用了 Runtime.Enable,页面上的几行 JavaScript 会被自动调用。
我们的修复会在每个框架上禁用自动的 Runtime.Enable 命令。相反,我们在创建框架时手动创建具有未知 ID 的上下文。然后,当需要执行代码时,有多种方法可以获取上下文 ID。
🟢 优点:这是终极方法,可保持对主世界的访问,并适用于 Web Worker 和 iframe。你无需更改任何现有代码库。
🔴 缺点:目前尚未发现任何缺点。
Page.createIsolatedWorld 创建新的隔离上下文并保存其 ID。🟢 优点:你所有的代码都将在单独的隔离世界中执行,防止页面脚本通过 MutationObserver 和其他技术检测到你的更改。
🔴 缺点:你将无法访问主上下文的变量和代码。虽然某些用例需要这样做,但在大多数场景下隔离上下文通常都能正常工作。此外,Web Worker 不允许创建新世界,因此你无法在 Worker 内执行代码。这是一个小众用例,但在某些情况下可能很重要。此问题有一个解决方法,请阅读如何从 Puppeteer 和 Playwright 的隔离上下文访问主上下文对象。
Runtime.Enable,然后立即调用 Runtime.Disable。这会触发 Runtime.executionContextCreated 事件,使我们能够捕获正确的上下文 ID。
🟢 优点:你将拥有对主上下文的完全访问权限。
🔴 缺点:在这短暂的时间窗口内,页面有可能调用导致泄漏的代码。风险很低,因为检测代码通常会在特定操作期间被调用,例如 CAPTCHA 页面或登录/注册表单,通常就在页面加载之后。你的业务逻辑通常会在稍晚一些时才被调用。
🎉 我们的测试表明,目前所有这些方法都无法被 Cloudflare 或 DataDome 检测到。
注意:你可以使用环境变量动态更改此补丁的设置。这使你能够根据业务逻辑在已修补和未修补版本之间轻松切换。
REBROWSER_PATCHES_RUNTIME_FIX_MODE=addBinding — addBinding 技术(默认)REBROWSER_PATCHES_RUNTIME_FIX_MODE=alwaysIsolated — 始终在隔离上下文中运行所有脚本REBROWSER_PATCHES_RUNTIME_FIX_MODE=enableDisable — 使用 Enable/Disable 技术REBROWSER_PATCHES_RUNTIME_FIX_MODE=0 — 完全禁用对此泄漏的修复REBROWSER_PATCHES_DEBUG=1 — 启用一些调试消息请记住,你可以通过不同方式设置这些变量,例如在代码中:
process.env.REBROWSER_PATCHES_RUNTIME_FIX_MODE = "alwaysIsolated"
或在命令行中:
REBROWSER_PATCHES_RUNTIME_FIX_MODE=alwaysIsolated node app.js
默认情况下,Puppeteer 会在 page.evaluate() 的每个脚本中添加 //# sourceURL=pptr:...。远程网站可以检测到此行为并发出警告。
此补丁将其更改为 //# sourceURL=app.js。你也可以通过环境变量进行调整:
# use any generic filename
REBROWSER_PATCHES_SOURCE_URL=jquery.min.js
# use 0 to completely disable this patch
REBROWSER_PATCHES_SOURCE_URL=0
有时,访问浏览器级别的 CDP 会话会非常有用。例如,当你想实现一些自定义的 CDP 命令时。有一个 page._client() 方法可以为当前页面实例返回 CDP 会话,但没有针对浏览器实例的此类方法。
此补丁为 Browser 类添加了一个新方法 _connection(),因此你可以这样使用:
browser._connection().on('Rebrowser.addRunEvent', (params) => { ... })
注意:外部网站脚本无法检测到它,它只是为了方便你使用。
默认的 utility world 名称是 '__puppeteer_utility_world__' + packageVersion。有时你可能想将其更改为其他名称。此补丁将其更改为 util,并允许你通过环境变量进行自定义:
REBROWSER_PATCHES_UTILITY_WORLD_NAME=customUtilityWorld
# use 0 to completely disable this patch
REBROWSER_PATCHES_UTILITY_WORLD_NAME=0
此环境变量无法动态更改,你必须在运行脚本之前设置它,因为它在模块被导入时就会使用。
| 补丁前 👎 | 补丁后 👍 |
|---|---|
![]() | ![]() |
注意:外部网站脚本无法检测到它,但 Google 可能会在他们专有的 Chrome 中使用此信息;我们无从得知。
此包设计为针对已安装的库运行。先安装库,然后调用修补程序,就可以使用了。
在项目的根文件夹中,运行:
npx rebrowser-patches@latest patch --packageName puppeteer-core
你可以使用以下命令轻松还原所有更改:
npx rebrowser-patches@latest unpatch --packageName puppeteer-core
你也可以通过提供其文件夹的完整路径来修补包,例如:
npx rebrowser-patches@latest patch --packagePath /web/app/node_modules/puppeteer-core-custom
你可以通过运行 npx rebrowser-patches@latest --help 查看所有命令行选项,但目前每个库只有一个补丁,因此你无需配置任何内容。
⚠️ 请注意,在项目文件夹中运行 npm install 或 yarn install 后,它可能会覆盖补丁带来的所有更改。你需要再次运行修补程序以保持补丁生效。
如果你的包已经打过补丁,并且想要更新到最新版本的 rebrowser-patches,最简单的方法是删除 node_modules/puppeteer-core,然后运行 npm install 或 yarn install --check-files,接着运行 npx rebrowser-patches@latest patch。
所有这些版本都只是围绕 Node.js 版 Playwright 的包装器。你需要在 Playwright 包中找到 driver 文件夹,并使用 --packagePath=$yourDriverFolder/$yourPlatform/package 运行此补丁。
✅ 最新完整测试版本:24.8.1(发布于 2025-05-06)
Playwright 补丁包括:
Runtime.enable 泄漏:addBinding 和 alwaysIsolated 模式。REBROWSER_PATCHES_UTILITY_WORLD_NAME 环境变量更改 utility world 名称。重要提示:page.pause() 方法在启用修复后无法正常工作,这需要更多调查。你可以在调试时使用 REBROWSER_PATCHES_RUNTIME_FIX_MODE=0 环境变量完全禁用修复。
目前这些补丁仅适用于 Chrome。如果你确实想将其用于 WebKit 或 Firefox,请新建一个问题。
✅ 最新完整测试版本:1.52.0(发布于 2025-04-17)
rebrowser-puppeteer 与 puppeteer-extra 一起使用?使用 addExtra 方法,示例如下:
// before
import puppeteer from 'puppeteer-extra'
// after
import { addExtra } from 'puppeteer-extra'
import rebrowserPuppeteer from 'rebrowser-puppeteer-core'
const puppeteer = addExtra(rebrowserPuppeteer)
我们目前正在开发更多补丁,以提高 Web 自动化的透明度,这些补丁将很快在此仓库中发布。请点击 ⭐️ 星标或关注按钮来支持该项目。
💭 如果你有任何想法、意见或问题,请随时通过电子邮件联系我们的团队,或使用问题专区。
⚠️ 重要的是要知道,仅靠此修复并不能让你的浏览器无懈可击、无法被检测。你还需要解决许多其他方面的问题,例如代理、合适的 user-agent 和指纹(canvas、WebGL)等。
始终牢记:你通过 JS 注入操纵浏览器内部细节越少越好。有一些方法可以检测到 console、navigator 等内部对象受到了 Proxy 对象或 Object.defineProperty 的影响。这很棘手,但这场猫鼠游戏永远不会结束。
如果你尝试了所有方法仍然遇到问题,请尝试在问题专区提问,或考虑使用 Rebrowser 的云解决方案。
此包由 Rebrowser 赞助和维护。我们允许你在云端使用数百个独特的指纹扩展你的浏览器自动化和网页抓取业务。
我们的云浏览器成功率很高,并附带一些不错的功能,例如当你的库在执行期间使用 Runtime.Enable 或存在其他可以改进的危险信号时向你发送通知。立即创建账户,获得邀请来测试我们前沿的平台,将你的自动化业务提升到新的水平。
当你在 Windows 机器上尝试运行此修补程序时,很可能会遇到错误,因为找不到 patch 命令。要解决此问题,你需要安装包含 patch.exe 的 Git。安装完成后,你需要将其添加到 PATH 中:
set PATH=%PATH%;C:\Program Files\Git\usr\bin\
你可以使用以下命令检查 patch.exe 是否安装正确:
patch -v
zfcsoftware/puppeteer-real-browser - 总体思路和对自动化社区的贡献
Kaliiiiiiiiii-Vinyzu/patchright - 修复 Playwright 泄漏的一组补丁
kaliiiiiiiiii/brotector - 一些现代测试,用于区分 CDP 与 devtools 的算法
prescience-data/harden-puppeteer - 隔离世界执行的先驱之一
puppeteer-extra-plugin-stealth - 一切都从这里开始,向所有贡献者和社区致以崇高敬意 🙏 berstend 和他的伙伴们是最棒的