
Коллекция патчей для puppeteer и playwright, позволяющая избежать обнаружения автоматизации и утечек. Помогает обходить CAPTCHA-страницы Cloudflare и DataDome. Патчи легко применять и отменять; их можно включать и отключать по требованию.
Этот репозиторий содержит патчи для улучшения популярных библиотек веб-автоматизации. В частности, он нацелен на пакеты 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 и протестируйте свой пропатченный браузер.
Наша цель — поддерживать эти готовые пакеты-замены с актуальными версиями, но в основном мы сосредоточены на свежих версиях, так что если вы всё ещё используете puppeteer 13.3.7 из начала 90-х, возможно, пора обновиться. С большой вероятностью ничего не сломается, так как API довольно стабилен со временем.
Runtime.EnableПопулярные библиотеки автоматизации полагаются на CDP-команду Runtime.Enable, которая позволяет получать события из домена Runtime.. Это критически важно для управления контекстами выполнения, используемыми для выполнения JavaScript на страницах, — ключевая функция любого процесса автоматизации.
Однако существует техника, которая обнаруживает использование этой команды и показывает, что браузер управляется ПО для автоматизации, таким как Puppeteer или Playwright. Эта техника используется всем крупным антибот-ПО, таким как Cloudflare, DataDome и другие.
Мы подготовили полную статью о нашем исследовании этой утечки, которую можно прочитать в нашем блоге.
Более подробно об этой технике читайте в блоге DataDome: Как новый Headless Chrome и сигнал CDP влияют на обнаружение ботов.
Если кратко, это несколько строк JavaScript на странице, которые вызываются автоматически, если была использована команда Runtime.Enable.
Наше исправление отключает автоматическую команду Runtime.Enable на каждом фрейме. Вместо этого мы вручную создаём контексты с неизвестными ID при создании фрейма. Затем, когда нужно выполнить код, есть несколько способов получить ID контекста.
🟢 Плюсы: наилучший подход — сохраняет доступ к основному миру и работает с веб-воркерами и iframe. Вам не нужно менять ни строчки существующего кода.
🔴 Минусы: на данный момент не обнаружены.
Page.createIsolatedWorld и сохраните его ID.🟢 Плюсы: весь ваш код будет выполняться в отдельном изолированном мире, что не позволит скриптам страницы обнаружить ваши изменения через MutationObserver и другие техники.
🔴 Минусы: вы не сможете получить доступ к переменным и коду основного контекста. Хотя это необходимо для некоторых сценариев использования, изолированный контекст в целом отлично работает в большинстве случаев. Кроме того, веб-воркеры не позволяют создавать новые миры, поэтому вы не сможете выполнять свой код внутри воркера. Это нишевый сценарий использования, но в некоторых ситуациях может иметь значение. Для этой проблемы есть обходное решение — прочитайте Как получить доступ к объектам основного контекста из изолированного контекста в 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/DisableREBROWSER_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 добавляет //# sourceURL=pptr:... к каждому скрипту в page.evaluate(). Удалённый сайт может обнаружить такое поведение и поднять красные флаги.
Этот патч меняет его на //# sourceURL=app.js. Вы также можете настроить его через переменную окружения:
# используйте любое общее имя файла
REBROWSER_PATCHES_SOURCE_URL=jquery.min.js
# используйте 0, чтобы полностью отключить этот патч
REBROWSER_PATCHES_SOURCE_URL=0
Иногда очень полезно иметь доступ к CDP-сессии на уровне браузера. Например, когда вы хотите реализовать какую-либо собственную CDP-команду. Существует метод page._client(), который возвращает CDP-сессию для текущего экземпляра страницы, но такого метода для экземпляра браузера нет.
Этот патч добавляет новый метод _connection() в класс Browser, так что вы можете использовать его так:
browser._connection().on('Rebrowser.addRunEvent', (params) => { ... })
Примечание: это не обнаруживается внешними скриптами сайта, это просто для вашего удобства.
Имя служебного мира по умолчанию — '__puppeteer_utility_world__' + packageVersion. Иногда вы можете захотеть изменить его на что-то другое. Этот патч меняет его на util и позволяет настроить его через переменную окружения:
REBROWSER_PATCHES_UTILITY_WORLD_NAME=customUtilityWorld
# используйте 0, чтобы полностью отключить этот патч
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. Вам нужно найти папку driver внутри вашего пакета Playwright и запустить этот патч с --packagePath=$yourDriverFolder/$yourPlatform/package.
✅ Последняя полностью протестированная версия: 24.8.1 (выпущена 2025-05-06)
Патчи Playwright включают:
Runtime.enable: режимы addBinding и alwaysIsolated.REBROWSER_PATCHES_UTILITY_WORLD_NAME.Важно: метод page.pause() не работает с включённым исправлением; это требует дальнейшего исследования. При отладке вы можете просто полностью отключить исправление, используя переменную окружения REBROWSER_PATCHES_RUNTIME_FIX_MODE=0.
Пока эти патчи работают только с Chrome. Если вы действительно хотите использовать их с WebKit или Firefox, пожалуйста, откройте новый issue.
✅ Последняя полностью протестированная версия: 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)
Мы сейчас разрабатываем дополнительные патчи, чтобы улучшить прозрачность веб-автоматизации; они скоро будут выпущены в этом репозитории. Пожалуйста, поддержите проект, нажав кнопку ⭐️ star или watch.
💭 Если у вас есть идеи, мысли или вопросы, не стесняйтесь обращаться к нашей команде по электронной почте или через раздел issues.
⚠️ Важно понимать: одно это исправление не сделает ваш браузер пуленепробиваемым и необнаруживаемым. Вам нужно учесть много других аспектов — прокси, правильный user-agent, отпечатки (canvas, WebGL) и многое другое.
Всегда помните: чем меньше вы вмешиваетесь во внутренности браузера через JS-инъекции, тем лучше. Существуют способы обнаружить, что внутренние объекты, такие как console, navigator и другие, были затронуты Proxy-объектами или Object.defineProperty. Это непросто, но это всегда игра в кошки-мышки.
Если вы перепробовали всё и всё ещё сталкиваетесь с проблемами, попробуйте задать вопрос в разделе issues или рассмотрите облачные решения от Rebrowser.
Этот пакет спонсируется и поддерживается компанией Rebrowser. Мы позволяем масштабировать автоматизацию браузера и веб-скрапинг в облаке, используя сотни уникальных отпечатков.
Наши облачные браузеры показывают отличные результаты и обладают приятными функциями, такими как уведомления, если ваша библиотека использует Runtime.Enable во время выполнения или имеет другие красные флаги, которые можно улучшить. Создайте аккаунт сегодня, чтобы получить приглашение протестировать нашу передовую платформу и вывести ваш бизнес автоматизации на новый уровень.
При попытке запустить этот патчер на машине с Windows вы, скорее всего, столкнётесь с ошибкой, поскольку команда patch не найдена. Чтобы исправить это, установите Git, который включает patch.exe. После установки добавьте его в ваш 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 и компания — легенды