> For the complete documentation index, see [llms.txt](https://docs.helodata.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.helodata.com/integrations/scraping-tools/playwright.md).

# Playwright

Playwright has first-class proxy support — pass credentials directly to `launch()` or `new_context()`, no extension hacks required.

## Python

```python
from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch(proxy={
        "server":   "http://gate.helodata.io:7777",
        "username": "helo_s1a2b3c4d5e-type-res-region-us",
        "password": "PASSWORD",
    })
    page = browser.new_page()
    page.goto("https://ipv4.icanhazip.com")
    print(page.content())
    browser.close()
```

For SOCKS5 use `"server": "socks5://gate.helodata.io:7777"` (DNS is resolved by the proxy automatically).

## Node.js

```js
import { chromium } from "playwright";

const browser = await chromium.launch({
  proxy: {
    server:   "http://gate.helodata.io:7777",
    username: "helo_s1a2b3c4d5e-type-res-region-us",
    password: "PASSWORD",
  },
});
const page = await browser.newPage();
await page.goto("https://ipv4.icanhazip.com");
console.log(await page.content());
await browser.close();
```

## Per-context proxy

Use a different proxy per browser context — handy for parallel sessions:

```python
ctx_us = browser.new_context(proxy={"server": "http://gate.helodata.io:7777",
                                    "username": "helo_s1a2b3c4d5e-type-res-region-us",
                                    "password": "PASSWORD"})
ctx_de = browser.new_context(proxy={"server": "http://gate.helodata.io:7777",
                                    "username": "helo_s1a2b3c4d5e-type-res-region-de",
                                    "password": "PASSWORD"})
```

The browser process is shared; contexts are isolated like separate browser profiles.

## ISP

```python
browser = p.chromium.launch(proxy={
    "server":   "http://198.51.100.42:8000",
    "username": "helo_s1a2b3c4d5e",
    "password": "PASSWORD",
})
```

## Rotating sessions in Playwright

Mint a new sub-user string per context, with a unique `session-XXX`:

```python
import random, string
def session_user(country="us"):
    sid = "".join(random.choices(string.ascii_lowercase + string.digits, k=8))
    return f"helo_s1a2b3c4d5e-type-res-region-{country}-session-{sid}-sesstime-10"

ctx = browser.new_context(proxy={
    "server": "http://gate.helodata.io:7777",
    "username": session_user(),
    "password": "PASSWORD",
})
```

## Verify

```python
ip = page.evaluate("fetch('https://ipv4.icanhazip.com').then(r => r.text())")
print(ip)
```

## Common pitfalls

* **No headless flag needed** for proxy auth — Playwright handles it natively in both head and headless modes.
* **WebRTC leak** — by default Playwright doesn't expose the local IP via WebRTC, but verify with `browserleaks.com/webrtc` if your target sniffs for it.
* **Bypass list** — use `proxy.bypass = "localhost,127.0.0.1"` to avoid proxying internal targets.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.helodata.com/integrations/scraping-tools/playwright.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
