Metadata-Version: 2.4
Name: playwright-proxy-authentication
Version: 0.1.0
Summary: Authenticated and rotating proxies for Playwright — turn user:pass proxy URLs into Playwright's proxy dict and rotate per context.
Author-email: JiBao Proxy <support@jibaoproxy.com>
License: MIT
Project-URL: Homepage, https://jibaoproxy.com
Project-URL: Source, https://github.com/jibaoproxyofficial-pixel/playwright-proxy-authentication
Keywords: playwright,proxy,proxy-authentication,rotating-proxy,web-scraping,browser-automation,residential-proxy
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Internet :: WWW/HTTP
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Dynamic: license-file

# playwright-proxy-authentication

[![PyPI version](https://img.shields.io/pypi/v/playwright-proxy-authentication.svg)](https://pypi.org/project/playwright-proxy-authentication/)
[![Python versions](https://img.shields.io/pypi/pyversions/playwright-proxy-authentication.svg)](https://pypi.org/project/playwright-proxy-authentication/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

Use **authenticated and rotating proxies with [Playwright](https://playwright.dev)** without fighting its proxy API. Turn an ordinary `scheme://user:pass@host:port` URL into the dict Playwright expects, and hand out a fresh exit IP per browser context.

```bash
pip install playwright-proxy-authentication
```

## The problem

Unlike `requests` or Scrapy, Playwright **ignores credentials in a proxy URL**. This silently fails to authenticate:

```python
# ❌ username/password are dropped — you get 407 Proxy Authentication Required
browser.new_context(proxy={"server": "http://user:pass@gw.example.com:913"})
```

Playwright wants the parts split out:

```python
# ✅ correct
browser.new_context(proxy={
    "server": "http://gw.example.com:913",
    "username": "user",
    "password": "pass",
})
```

This package does that conversion for you, and adds per-context rotation.

## Usage

```python
from playwright.sync_api import sync_playwright
from playwright_proxy_auth import ProxyPool

# A rotating residential gateway gives a new exit IP on every connection.
pool = ProxyPool(gateway="http://USERNAME:PASSWORD@us.jibaoproxy.com:913")

with sync_playwright() as p:
    browser = p.chromium.launch(headless=True)
    for _ in range(3):
        context = browser.new_context(proxy=pool.get())   # fresh IP per context
        page = context.new_page()
        page.goto("https://httpbin.org/ip")
        print(page.inner_text("body"))
        context.close()
    browser.close()
```

Static list instead of a gateway:

```python
pool = ProxyPool(proxies=[
    "http://USERNAME:PASSWORD@proxy-a.example.com:8000",
    "http://USERNAME:PASSWORD@proxy-b.example.com:8000",
])
```

One-off conversion without the pool:

```python
from playwright_proxy_auth import to_playwright_proxy
proxy = to_playwright_proxy("http://user:pass@gw.example.com:913")
browser.new_context(proxy=proxy)
```

See [`examples/`](examples/) for the async version.

## Gotchas this saves you from

- **Credentials in the URL are ignored** — they must be a separate `username`/`password`. (Main reason for it.)
- **Authenticated SOCKS5 is not supported by Playwright.** A `socks5://user:pass@…` URL raises a clear error instead of failing silently — use an HTTP/HTTPS gateway for authenticated rotation.
- **Proxy is per *context*, not per page.** Rotate by creating a new `browser.new_context(proxy=...)`; pages inside a context share its exit IP.

## A note on getting blocked anyway

A correctly authenticated proxy still gets blocked if the **exit IP is a datacenter range** — anti-bot systems score the ASN and [TLS/JA3 fingerprint](https://jibaoproxy.com/blog/ja3-tls-fingerprint-detection-explained.html) before your page loads. Residential exits with clean ASN reputation are what pass. We build [JiBao Proxy](https://jibaoproxy.com) for this: 72M+ residential IPs across 200+ countries with sticky sessions. This package works with any HTTP proxy provider, though.

## Related

- [Selenium & Playwright proxy authentication, explained](https://jibaoproxy.com/blog/selenium-playwright-proxy-authentication.html)
- [Why your JA3/TLS fingerprint gets you blocked](https://jibaoproxy.com/blog/ja3-tls-fingerprint-detection-explained.html)
- [browser-use & AI agent proxies](https://jibaoproxy.com/blog/browser-use-ai-agent-proxies.html)

## License

MIT
