Skip to content

Commit fa3b2e2

Browse files
committed
Gemini cleaned up the Stealthy Playwright ReadMe
1 parent e2bc0b6 commit fa3b2e2

File tree

1 file changed

+33
-28
lines changed

1 file changed

+33
-28
lines changed

examples/cdp_mode/playwright/ReadMe.md

Lines changed: 33 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -11,21 +11,23 @@
1111

1212
--------
1313

14-
### 🎭 Getting started with <b translate="no">Stealthy Playwright Mode</b>:
14+
## 🛠️ Installation
1515

16-
If **`playwright`** isn't already installed, then install it first:
16+
To use **Stealthy Playwright Mode**, simply install the necessary Python packages:
1717

1818
```zsh
19-
pip install playwright
19+
pip install seleniumbase playwright
2020
```
2121

22-
**Stealthy Playwright Mode** comes in 3 formats:
23-
1. `sb_cdp` sync format
24-
2. `SB()` nested sync format
25-
3. `cdp_driver` async format
22+
> **Note:** Just as standard Playwright can use `channel="chrome"` to bypass internal binary downloads, Stealthy Playwright Mode attaches to the system Chrome already managed and patched by SeleniumBase. This lets you skip the large `playwright install` step entirely.
2623
24+
## 💻 Usage
2725

28-
### 🎭 `sb_cdp` sync format (minimal boilerplate):
26+
There are three primary ways to implement **Stealthy Playwright Mode**, depending on your project’s architecture and needs: `sb_cdp` sync, `SB()` nested sync, and `cdp_driver` async.
27+
28+
### 1. The lightweight "sync" format (`sb_cdp`)
29+
30+
Ideal for standalone scripts that primarily use Playwright but need SeleniumBase's stealth and CAPTCHA-solving power without the overhead of WebDriver.
2931

3032
```python
3133
from playwright.sync_api import sync_playwright
@@ -36,12 +38,13 @@ endpoint_url = sb.get_endpoint_url()
3638

3739
with sync_playwright() as p:
3840
browser = p.chromium.connect_over_cdp(endpoint_url)
39-
context = browser.contexts[0]
40-
page = context.pages[0]
41+
page = browser.contexts[0].pages[0]
4142
page.goto("https://example.com")
4243
```
4344

44-
### 🎭 `SB()` nested sync format (minimal boilerplate):
45+
### 2. The full-suite "nested sync" format (`SB()`)
46+
47+
Best for hybrid projects where you need to switch between Selenium WebDriver and Playwright APIs in the same session. This is for power users!
4548

4649
```python
4750
from playwright.sync_api import sync_playwright
@@ -53,12 +56,13 @@ with SB(uc=True) as sb:
5356

5457
with sync_playwright() as p:
5558
browser = p.chromium.connect_over_cdp(endpoint_url)
56-
context = browser.contexts[0]
57-
page = context.pages[0]
59+
page = browser.contexts[0].pages[0]
5860
page.goto("https://example.com")
5961
```
6062

61-
### 🎭 `cdp_driver` async format (minimal boilerplate):
63+
### 3. The async format (`cdp_driver`)
64+
65+
Designed for modern asynchronous Python. This allows you to run multiple concurrent stealth sessions using `async/await` and Playwright's `async_api`.
6266

6367
```python
6468
import asyncio
@@ -71,15 +75,22 @@ async def main():
7175

7276
async with async_playwright() as p:
7377
browser = await p.chromium.connect_over_cdp(endpoint_url)
74-
context = browser.contexts[0]
75-
page = context.pages[0]
78+
page = browser.contexts[0].pages[0]
7679
await page.goto("https://example.com")
7780

7881
if __name__ == "__main__":
7982
loop = asyncio.new_event_loop()
8083
loop.run_until_complete(main())
8184
```
8285

86+
### 💡 Key differences of the 3 stealthy formats:
87+
88+
- **`sb_cdp`**: Simplest setup. CDP launches a stealthy browser. (No WebDriver)
89+
90+
- **`SB()`**: Maximum utility. Gives you the full range of APIs: WebDriver, CDP, and Playwright. (WebDriver launches a stealthy browser.)
91+
92+
- **`cdp_driver`**: Best for performance. `asyncio` handles non-blocking tasks. CDP launches a stealthy browser. (No WebDriver)
93+
8394
--------
8495

8596
### 🎭 <b translate="no">Stealthy Playwright Mode</b> details:
@@ -109,8 +120,7 @@ endpoint_url = sb.get_endpoint_url()
109120

110121
with sync_playwright() as p:
111122
browser = p.chromium.connect_over_cdp(endpoint_url)
112-
context = browser.contexts[0]
113-
page = context.pages[0]
123+
page = browser.contexts[0].pages[0]
114124
page.goto("https://copilot.microsoft.com")
115125
page.wait_for_selector("textarea#userInput")
116126
page.wait_for_timeout(1000)
@@ -141,8 +151,7 @@ endpoint_url = sb.get_endpoint_url()
141151

142152
with sync_playwright() as p:
143153
browser = p.chromium.connect_over_cdp(endpoint_url)
144-
context = browser.contexts[0]
145-
page = context.pages[0]
154+
page = browser.contexts[0].pages[0]
146155
page.goto("https://www.bing.com/turing/captcha/challenge")
147156
page.wait_for_timeout(2000)
148157
sb.solve_captcha()
@@ -164,8 +173,7 @@ from playwright.sync_api import sync_playwright
164173

165174
with sync_playwright() as p:
166175
browser = p.chromium.launch(channel="chrome", headless=False)
167-
context = browser.new_context()
168-
page = context.new_page()
176+
page = browser.new_context().new_page()
169177
page.goto("https://example.com")
170178
```
171179

@@ -180,8 +188,7 @@ endpoint_url = sb.get_endpoint_url()
180188

181189
with sync_playwright() as p:
182190
browser = p.chromium.connect_over_cdp(endpoint_url)
183-
context = browser.contexts[0]
184-
page = context.pages[0]
191+
page = browser.contexts[0].pages[0]
185192
page.goto("https://example.com")
186193
```
187194

@@ -231,8 +238,7 @@ endpoint_url = sb.get_endpoint_url()
231238

232239
with sync_playwright() as p:
233240
browser = p.chromium.connect_over_cdp(endpoint_url)
234-
context = browser.contexts[0]
235-
page = context.pages[0]
241+
page = browser.contexts[0].pages[0]
236242
# ...
237243
```
238244
(Fill in the `url` and the `proxy` details to complete the script.)
@@ -250,8 +256,7 @@ async def main():
250256

251257
async with async_playwright() as p:
252258
browser = await p.chromium.connect_over_cdp(endpoint_url)
253-
context = browser.contexts[0]
254-
page = context.pages[0]
259+
page = browser.contexts[0].pages[0]
255260
# ...
256261

257262
if __name__ == "__main__":

0 commit comments

Comments
 (0)