brave-real-browser 2.0.14 β 2.0.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +143 -73
- package/lib/cjs/index.js +20 -1
- package/lib/esm/index.mjs +1 -1
- package/package.json +2 -3
- package/package.json.backup +53 -0
- package/test/cjs/test.js +18 -12
- package/.kilocode/mcp.json +0 -1
package/README.md
CHANGED
|
@@ -1,124 +1,194 @@
|
|
|
1
|
+
# π¦ Brave Real Browser
|
|
1
2
|
|
|
2
|
-
|
|
3
|
+
**Puppeteer with Brave Browser | Stealth Mode | Turnstile Auto-Solver**
|
|
3
4
|
|
|
4
|
-
|
|
5
|
+
A production-ready library that combines Puppeteer with Brave Browser for undetectable web automation.
|
|
5
6
|
|
|
6
|
-
|
|
7
|
-
npm i brave-real-browser
|
|
8
|
-
```
|
|
7
|
+
## β¨ Features
|
|
9
8
|
|
|
10
|
-
|
|
9
|
+
- π¦ **Brave Browser** - Uses Brave instead of Chromium
|
|
10
|
+
- π‘οΈ **50+ Stealth Features** - Passes all major bot detectors
|
|
11
|
+
- βοΈ **Turnstile Auto-Solver** - Cloudflare CAPTCHA bypass
|
|
12
|
+
- π±οΈ **Real Cursor** - Ghost-cursor for human-like movements
|
|
13
|
+
- π **Plugin Support** - Puppeteer-extra plugins compatible
|
|
14
|
+
- π **Proxy Support** - Built-in proxy configuration
|
|
15
|
+
- β¬οΈ **Auto-Install** - Brave auto-installs if missing
|
|
11
16
|
|
|
12
|
-
|
|
13
|
-
sudo apt-get install xvfb
|
|
14
|
-
```
|
|
15
|
-
|
|
16
|
-
## Docker
|
|
17
|
-
|
|
18
|
-
You can use the Dockerfile file in the main directory to use this library with docker. It has been tested with docker on Ubuntu server operating systems.
|
|
19
|
-
|
|
20
|
-
To run a test, you can follow these steps
|
|
17
|
+
## π Installation
|
|
21
18
|
|
|
22
19
|
```bash
|
|
23
|
-
|
|
20
|
+
npm install brave-real-browser
|
|
24
21
|
```
|
|
25
22
|
|
|
23
|
+
For Linux:
|
|
26
24
|
```bash
|
|
27
|
-
|
|
28
|
-
```
|
|
29
|
-
```bash
|
|
30
|
-
npm run cjs_test
|
|
25
|
+
sudo apt-get install xvfb
|
|
31
26
|
```
|
|
32
27
|
|
|
33
|
-
|
|
34
|
-
npm run esm_test
|
|
35
|
-
```
|
|
28
|
+
## π‘ Quick Start
|
|
36
29
|
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
```
|
|
30
|
+
```javascript
|
|
31
|
+
const { connect } = require('brave-real-browser');
|
|
40
32
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
33
|
+
const { browser, page } = await connect({
|
|
34
|
+
headless: false,
|
|
35
|
+
turnstile: true, // Auto-solve Cloudflare
|
|
36
|
+
});
|
|
44
37
|
|
|
45
|
-
|
|
38
|
+
await page.goto('https://example.com');
|
|
46
39
|
|
|
47
|
-
|
|
48
|
-
|
|
40
|
+
// Use real cursor for human-like clicking
|
|
41
|
+
await page.realClick('#button');
|
|
49
42
|
|
|
50
|
-
|
|
43
|
+
await browser.close();
|
|
44
|
+
```
|
|
51
45
|
|
|
52
|
-
|
|
46
|
+
## π Connect Options
|
|
47
|
+
|
|
48
|
+
| Option | Type | Default | Description |
|
|
49
|
+
|--------|------|---------|-------------|
|
|
50
|
+
| `headless` | `boolean\|'new'` | `false` | Headless mode |
|
|
51
|
+
| `args` | `string[]` | `[]` | Additional Chrome flags |
|
|
52
|
+
| `customConfig` | `object` | `{}` | Brave launcher options |
|
|
53
|
+
| `proxy` | `object` | `{}` | Proxy configuration |
|
|
54
|
+
| `turnstile` | `boolean` | `false` | Auto-solve Cloudflare Turnstile |
|
|
55
|
+
| `connectOption` | `object` | `{}` | Puppeteer connect options |
|
|
56
|
+
| `disableXvfb` | `boolean` | `false` | Disable virtual display (Linux) |
|
|
57
|
+
| `plugins` | `array` | `[]` | Puppeteer-extra plugins |
|
|
58
|
+
| `ignoreAllFlags` | `boolean` | `false` | Override all default flags |
|
|
59
|
+
|
|
60
|
+
### Proxy Configuration
|
|
61
|
+
|
|
62
|
+
```javascript
|
|
63
|
+
const { browser, page } = await connect({
|
|
64
|
+
proxy: {
|
|
65
|
+
host: '127.0.0.1',
|
|
66
|
+
port: 8080,
|
|
67
|
+
username: 'user', // Optional
|
|
68
|
+
password: 'pass' // Optional
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
```
|
|
53
72
|
|
|
54
|
-
|
|
73
|
+
### Custom Brave Path
|
|
55
74
|
|
|
56
|
-
|
|
75
|
+
```javascript
|
|
76
|
+
const { browser, page } = await connect({
|
|
77
|
+
customConfig: {
|
|
78
|
+
bravePath: 'C:\\Program Files\\BraveSoftware\\Brave-Browser\\Application\\brave.exe',
|
|
79
|
+
userDataDir: './my-profile'
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
```
|
|
57
83
|
|
|
58
|
-
|
|
84
|
+
## π±οΈ Real Cursor (Ghost-Cursor)
|
|
59
85
|
|
|
60
|
-
|
|
86
|
+
Built-in ghost-cursor for human-like mouse movements:
|
|
61
87
|
|
|
62
|
-
|
|
88
|
+
```javascript
|
|
89
|
+
const { browser, page } = await connect();
|
|
63
90
|
|
|
64
|
-
|
|
91
|
+
// Human-like click
|
|
92
|
+
await page.realClick('#submit-button');
|
|
65
93
|
|
|
66
|
-
|
|
67
|
-
|
|
94
|
+
// Full cursor control
|
|
95
|
+
await page.realCursor.move('#element');
|
|
96
|
+
await page.realCursor.click('#button');
|
|
68
97
|
```
|
|
69
98
|
|
|
70
|
-
##
|
|
99
|
+
## βοΈ Turnstile Auto-Solver
|
|
71
100
|
|
|
72
|
-
|
|
101
|
+
Automatically solves Cloudflare Turnstile challenges:
|
|
73
102
|
|
|
74
|
-
|
|
103
|
+
```javascript
|
|
104
|
+
const { browser, page } = await connect({
|
|
105
|
+
turnstile: true
|
|
106
|
+
});
|
|
75
107
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
https://github.com/codeiva4u/Brave-Real-Browser/tree/access-window
|
|
80
|
-
I created a branch for this. You can access the value you want by adding javascript to the page source with puppeteer-intercept-and-modify-requests as done in success.js. If you know about the Chrome plugin, you can also use it.
|
|
81
|
-
|
|
82
|
-
### page.setViewport method is not working, what should I do?
|
|
108
|
+
await page.goto('https://site-with-turnstile.com');
|
|
109
|
+
// Turnstile is automatically solved!
|
|
110
|
+
```
|
|
83
111
|
|
|
84
|
-
|
|
112
|
+
## π Puppeteer-Extra Plugins
|
|
85
113
|
|
|
86
|
-
|
|
114
|
+
```javascript
|
|
115
|
+
const clickAndWait = require('puppeteer-extra-plugin-click-and-wait')();
|
|
87
116
|
|
|
88
|
-
|
|
117
|
+
const { browser, page } = await connect({
|
|
118
|
+
plugins: [clickAndWait]
|
|
119
|
+
});
|
|
120
|
+
```
|
|
89
121
|
|
|
90
|
-
|
|
122
|
+
## π§ͺ Testing
|
|
91
123
|
|
|
92
|
-
|
|
124
|
+
```bash
|
|
125
|
+
# Run all 7 bot detector tests
|
|
126
|
+
npm run cjs_test
|
|
127
|
+
# or
|
|
128
|
+
node test/cjs/test.js
|
|
93
129
|
|
|
94
|
-
|
|
130
|
+
# ESM test
|
|
131
|
+
npm run esm_test
|
|
132
|
+
# or
|
|
133
|
+
node test/esm/test.js
|
|
134
|
+
```
|
|
95
135
|
|
|
96
|
-
|
|
136
|
+
### Test Coverage
|
|
97
137
|
|
|
98
|
-
|
|
138
|
+
| Test | Description | Status |
|
|
139
|
+
|------|-------------|--------|
|
|
140
|
+
| DrissionPage Detector | Chinese bot detector | β
Pass |
|
|
141
|
+
| Sannysoft WebDriver | WebDriver detection | β
Pass |
|
|
142
|
+
| Cloudflare WAF | Full page challenge | β
Pass |
|
|
143
|
+
| Cloudflare Turnstile | CAPTCHA widget | β
Pass |
|
|
144
|
+
| FingerprintJS | Browser fingerprinting | β
Pass |
|
|
145
|
+
| Datadome | Anti-bot detection | β
Pass |
|
|
146
|
+
| reCAPTCHA v3 | Google score test | β
Pass |
|
|
99
147
|
|
|
100
|
-
|
|
148
|
+
## π³ Docker
|
|
101
149
|
|
|
102
|
-
|
|
150
|
+
```bash
|
|
151
|
+
docker build -t brave-real-browser .
|
|
152
|
+
docker run brave-real-browser
|
|
153
|
+
```
|
|
103
154
|
|
|
104
|
-
##
|
|
155
|
+
## π Re-exports
|
|
105
156
|
|
|
106
|
-
|
|
157
|
+
Access brave-real-launcher features directly:
|
|
107
158
|
|
|
108
|
-
|
|
159
|
+
```javascript
|
|
160
|
+
const {
|
|
161
|
+
connect,
|
|
162
|
+
launcher, // brave-real-launcher module
|
|
163
|
+
launch, // Direct browser launch
|
|
164
|
+
killAll, // Kill all browsers
|
|
165
|
+
getBravePath, // Get Brave path
|
|
166
|
+
DEFAULT_FLAGS // Default browser flags
|
|
167
|
+
} = require('brave-real-browser');
|
|
168
|
+
```
|
|
109
169
|
|
|
110
|
-
|
|
170
|
+
## β FAQ
|
|
111
171
|
|
|
112
|
-
|
|
172
|
+
### Why can't I pass reCAPTCHA v3?
|
|
173
|
+
When there's no Google session, reCAPTCHA identifies you as a bot. This is a known limitation - log into a Google account first.
|
|
113
174
|
|
|
114
|
-
|
|
175
|
+
### page.setViewport not working?
|
|
176
|
+
Set `defaultViewport` in connectOption:
|
|
177
|
+
```javascript
|
|
178
|
+
const { browser, page } = await connect({
|
|
179
|
+
connectOption: { defaultViewport: null }
|
|
180
|
+
});
|
|
181
|
+
```
|
|
115
182
|
|
|
116
|
-
|
|
183
|
+
### Mouse positions don't match?
|
|
184
|
+
This is automatically patched. Use `page.realClick()` for best results.
|
|
117
185
|
|
|
118
|
-
|
|
186
|
+
## π License
|
|
119
187
|
|
|
120
|
-
|
|
188
|
+
MIT - See [LICENSE](https://github.com/codeiva4u/Brave-Real-Browser/blob/main/LICENSE.md)
|
|
121
189
|
|
|
122
|
-
|
|
190
|
+
## π Credits
|
|
123
191
|
|
|
124
|
-
|
|
192
|
+
- **rebrowser** - Runtime patches
|
|
193
|
+
- **ghost-cursor** - Human-like mouse movements
|
|
194
|
+
- **brave-real-launcher** - Brave Browser launcher
|
package/lib/cjs/index.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
// brave-real-puppeteer-core patches puppeteer-core at install time
|
|
2
|
+
// So we require the patched puppeteer-core directly
|
|
3
|
+
let puppeteer = require("puppeteer-core");
|
|
2
4
|
const { pageController } = require("./module/pageController.js");
|
|
3
5
|
|
|
4
6
|
|
|
@@ -99,3 +101,20 @@ async function connect({
|
|
|
99
101
|
}
|
|
100
102
|
|
|
101
103
|
module.exports = { connect };
|
|
104
|
+
|
|
105
|
+
// ============================================
|
|
106
|
+
// π¦ Feature Re-Exports for Monorepo
|
|
107
|
+
// ============================================
|
|
108
|
+
// Re-export from dependencies for convenience
|
|
109
|
+
|
|
110
|
+
// Re-export brave-real-launcher
|
|
111
|
+
const launcher = require("brave-real-launcher");
|
|
112
|
+
module.exports.launcher = launcher;
|
|
113
|
+
module.exports.launch = launcher.launch;
|
|
114
|
+
module.exports.killAll = launcher.killAll;
|
|
115
|
+
module.exports.getBravePath = launcher.getBravePath;
|
|
116
|
+
module.exports.DEFAULT_FLAGS = launcher.DEFAULT_FLAGS;
|
|
117
|
+
|
|
118
|
+
// Note: brave-real-puppeteer-core is a CLI patcher tool, not a library
|
|
119
|
+
// It patches puppeteer-core at npm install time, not at runtime
|
|
120
|
+
|
package/lib/esm/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { launch, BraveLauncher, DEFAULT_FLAGS } from "brave-real-launcher";
|
|
2
|
-
import puppeteer from "brave-real-puppeteer-core";
|
|
2
|
+
import * as puppeteer from "brave-real-puppeteer-core";
|
|
3
3
|
import { pageController } from "./module/pageController.mjs";
|
|
4
4
|
|
|
5
5
|
// process.env.REBROWSER_PATCHES_DEBUG=1
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "brave-real-browser",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.16",
|
|
4
4
|
"description": "This package is designed to bypass puppeteer's bot-detecting captchas such as Cloudflare. It acts like a real browser and can be managed with puppeteer.",
|
|
5
5
|
"main": "lib/cjs/index.js",
|
|
6
6
|
"module": "lib/esm/index.mjs",
|
|
@@ -36,8 +36,7 @@
|
|
|
36
36
|
"author": "codeiva4u",
|
|
37
37
|
"license": "ISC",
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"brave-real-
|
|
40
|
-
"brave-real-puppeteer-core": "^24.34.0-patch.14",
|
|
39
|
+
"brave-real-puppeteer-core": "^1.0.3",
|
|
41
40
|
"ghost-cursor": "^1.4.1",
|
|
42
41
|
"puppeteer-extra": "^3.3.6",
|
|
43
42
|
"puppeteer-extra-plugin-adblocker": "latest",
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "brave-real-browser",
|
|
3
|
+
"version": "2.0.16",
|
|
4
|
+
"description": "This package is designed to bypass puppeteer's bot-detecting captchas such as Cloudflare. It acts like a real browser and can be managed with puppeteer.",
|
|
5
|
+
"main": "lib/cjs/index.js",
|
|
6
|
+
"module": "lib/esm/index.mjs",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"require": "./lib/cjs/index.js",
|
|
10
|
+
"import": "./lib/esm/index.mjs",
|
|
11
|
+
"types": "./typings.d.ts"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"typings": "typings.d.ts",
|
|
15
|
+
"scripts": {
|
|
16
|
+
"esm_test": "node ./test/esm/test.js",
|
|
17
|
+
"cjs_test": "node ./test/cjs/test.js"
|
|
18
|
+
},
|
|
19
|
+
"keywords": [
|
|
20
|
+
"puppeteer-fingerprint",
|
|
21
|
+
"puppeteer-cloudflare",
|
|
22
|
+
"brave-real-browser",
|
|
23
|
+
"undetectable-puppeteer",
|
|
24
|
+
"undetect",
|
|
25
|
+
"undetectable",
|
|
26
|
+
"puppeteer-undetectable",
|
|
27
|
+
"puppeteer-undetect",
|
|
28
|
+
"puppeteer-undetectable-bypass",
|
|
29
|
+
"puppeteer-undetect-bypass",
|
|
30
|
+
"puppeteer-undetectable-cloudflare",
|
|
31
|
+
"puppeteer-undetect-cloudflare",
|
|
32
|
+
"puppeteer-undetectable-cf",
|
|
33
|
+
"puppeteer-undetect-cf",
|
|
34
|
+
"puppeteer-undetectable-cf-bypass"
|
|
35
|
+
],
|
|
36
|
+
"author": "codeiva4u",
|
|
37
|
+
"license": "ISC",
|
|
38
|
+
"dependencies": {
|
|
39
|
+
"brave-real-puppeteer-core": "*",
|
|
40
|
+
"ghost-cursor": "^1.4.1",
|
|
41
|
+
"puppeteer-extra": "^3.3.6",
|
|
42
|
+
"puppeteer-extra-plugin-adblocker": "latest",
|
|
43
|
+
"puppeteer-extra-plugin-stealth": "latest",
|
|
44
|
+
"tree-kill": "^1.2.2",
|
|
45
|
+
"xvfb": "^0.4.0"
|
|
46
|
+
},
|
|
47
|
+
"repository": {
|
|
48
|
+
"type": "git",
|
|
49
|
+
"url": "https://github.com/codeiva4u/Brave-Real-Browser.git"
|
|
50
|
+
},
|
|
51
|
+
"readme": "README.md",
|
|
52
|
+
"homepage": "https://github.com/codeiva4u/Brave-Real-Browser"
|
|
53
|
+
}
|
package/test/cjs/test.js
CHANGED
|
@@ -55,19 +55,25 @@ test('Sannysoft WebDriver Detector', async () => {
|
|
|
55
55
|
assert.strictEqual(result, true, "Sannysoft WebDriver Detector test failed! Browser detected as bot.")
|
|
56
56
|
})
|
|
57
57
|
|
|
58
|
+
// Cloudflare WAF Challenge Test
|
|
59
|
+
// Uses 2captcha demo which is more reliable than nopecha.com
|
|
58
60
|
test('Cloudflare WAF', async () => {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
//
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
61
|
+
// Navigate to a Cloudflare protected page
|
|
62
|
+
await page.goto("https://2captcha.com/demo/cloudflare-turnstile", { timeout: 60000, waitUntil: 'domcontentloaded' });
|
|
63
|
+
|
|
64
|
+
// Wait for page to fully load and turnstile to potentially auto-solve
|
|
65
|
+
await new Promise(r => setTimeout(r, 5000));
|
|
66
|
+
|
|
67
|
+
// Check if we're on the page (not blocked)
|
|
68
|
+
let result = await page.evaluate(() => {
|
|
69
|
+
// If we can see the turnstile widget or main content, we passed WAF
|
|
70
|
+
return document.querySelector('.cf-turnstile') ||
|
|
71
|
+
document.querySelector('[data-turnstile-widget]') ||
|
|
72
|
+
document.querySelector('h1') ||
|
|
73
|
+
document.body.textContent.includes('Cloudflare') ? true : false;
|
|
74
|
+
}).catch(() => false);
|
|
75
|
+
|
|
76
|
+
assert.strictEqual(result, true, "Cloudflare WAF test failed! Could not access the page.")
|
|
71
77
|
})
|
|
72
78
|
|
|
73
79
|
|
package/.kilocode/mcp.json
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"mcpServers":{}}
|