
자동화 감지 및 누출을 피하기 위한 puppeteer와 playwright용 패치 모음입니다. Cloudflare 및 DataDome CAPTCHA 페이지를 우회하는 데 도움이 됩니다. 패치 적용/해제가 쉽고, 필요에 따라 활성화/비활성화할 수 있습니다.
이 저장소는 널리 사용되는 웹 자동화 라이브러리를 개선하기 위한 패치를 포함하고 있습니다. 구체적으로 puppeteer 및 playwright 패키지를 대상으로 합니다.
자동화 라이브러리나 브라우저 동작의 일부 측면은 설정이나 명령줄 스위치로 조정할 수 없습니다. 따라서 우리는 라이브러리의 소스 코드를 패치하여 이러한 문제를 해결합니다. 이 접근 방식은 깨지기 쉬워 라이브러리의 소스 코드가 변경됨에 따라 문제가 발생할 수 있지만, 커뮤니티의 도움을 받아 패치를 최신 상태로 유지하는 것이 이 저장소의 목표입니다.
기본 상태의 Puppeteer와 Playwright에는 쉽게 탐지되는 심각한 누출(leak)이 있습니다. 프록시, 지문(fingerprint), 행동 스크립트가 아무리 훌륭해도 패치가 되어 있지 않다면, 주요 웹사이트에는 커다란 위험 신호로 보일 뿐입니다.
🕵️ rebrowser-bot-detector를 사용하여 자동화 설정이 주요 최신 탐지 기법에 얼마나 취약한지 쉽게 테스트할 수 있습니다 (소스 및 자세한 정보)
| 패치 전 👎 | 패치 후 👍 |
|---|---|
![]() | ![]() |
패치와 발생 가능한 모든 오류를 직접 처리하고 싶지 않다면, 바로 사용할 수 있는(drop-in) 솔루션이 있습니다. 이 패키지들은 원본 코드에 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 누출(leak) 수정널리 사용되는 자동화 라이브러리는 Runtime. 도메인의 이벤트를 수신할 수 있게 해주는 CDP 명령 Runtime.Enable에 의존합니다. 이는 모든 자동화 프로세스의 핵심 기능인 페이지에서 JavaScript를 평가하는 데 사용되는 실행 컨텍스트를 관리하는 데 중요합니다.
그러나 이 명령의 사용을 탐지하여 브라우저가 Puppeteer나 Playwright 같은 자동화 소프트웨어에 의해 제어되고 있음을 드러내는 기술이 있습니다. 이 기술은 Cloudflare, DataDome 등을 포함한 모든 주요 안티봇 소프트웨어에서 사용됩니다.
이 누출에 대한 조사 내용을 담은 전체 기사를 준비했으며, 블로그에서 읽을 수 있습니다.
이 기술에 대한 자세한 내용은 DataDome의 블로그 게시물을 읽어보세요: How New Headless Chrome & the CDP Signal Are Impacting Bot Detection.
간단히 말하면, Runtime.Enable이 사용된 경우 페이지에서 자동으로 호출되는 몇 줄의 JavaScript입니다.
우리의 수정은 모든 프레임에서 자동 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/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 명령을 구현하려는 경우입니다. 현재 페이지 인스턴스에 대한 CDP 세션을 반환하는 page._client() 메서드는 있지만, 브라우저 인스턴스에는 그런 메서드가 없습니다.
이 패치는 Browser 클래스에 새 메서드 _connection()을 추가하므로 다음과 같이 사용할 수 있습니다:
browser._connection().on('Rebrowser.addRunEvent', (params) => { ... })
참고: 외부 웹사이트 스크립트로는 탐지할 수 없으며, 단지 편의를 위한 것입니다.
기본 유틸리티 월드 이름은 '__puppeteer_utility_world__' + packageVersion입니다. 때로는 다른 이름으로 변경하고 싶을 수 있습니다. 이 패치는 이를 util로 변경하고 환경 변수를 통해 사용자 지정할 수 있게 해줍니다:
REBROWSER_PATCHES_UTILITY_WORLD_NAME=customUtilityWorld
# use 0 to completely disable this patch
REBROWSER_PATCHES_UTILITY_WORLD_NAME=0
이 환경 변수는 즉석에서 변경할 수 없습니다. 모듈이 임포트되는 시점에 사용되므로 스크립트를 실행하기 전에 설정해야 합니다.
| 패치 전 👎 | 패치 후 👍 |
|---|---|
![]() | ![]() |