Skip to main content

Overview

This example shows how to use Playwright with Tzafon Computer, including how to dynamically change the proxy for your browser session.
Tzafon exposes a Chrome DevTools Protocol (CDP) endpoint that Playwright can connect to, giving you full Playwright capabilities on a Tzafon-managed browser.

Prerequisites

Install the required packages:
pip install playwright requests
playwright install chromium

Complete Example

import requests
import time
from playwright.sync_api import Playwright, sync_playwright

# Configuration
BASE_URL = "https://api.tzafon.ai"
TOKEN = "sk_your_api_key_here"  # Replace with your API key

# Proxy configuration (example using Oxylabs)
PROXY = "http://username:password@proxy-server:port"


def create_computer_with_proxy() -> str:
    """Create a Tzafon browser session and configure proxy."""
    headers = {
        "Authorization": f"Bearer {TOKEN}",
        "Content-Type": "application/json",
    }

    # Step 1: Create the browser session
    print("Creating browser session...")
    resp = requests.post(
        f"{BASE_URL}/computers",
        json={"kind": "browser"},
        headers=headers,
        timeout=180,
    )
    data = resp.json()
    computer_id = data["id"]
    print(f"Created computer: {computer_id}")

    # Step 2: Set the proxy
    print("Configuring proxy...")
    resp = requests.post(
        f"{BASE_URL}/computers/{computer_id}/execute",
        json={"action": {"type": "change_proxy", "proxy_url": PROXY}},
        headers=headers,
        timeout=180,
    )

    if resp.status_code == 200:
        print("Proxy configured successfully")
    else:
        print(f"Proxy configuration failed: {resp.content}")

    return computer_id


def run_playwright(playwright: Playwright, cdp_url: str, computer_id: str) -> None:
    """Connect Playwright and perform automation."""
    print(f"Connecting to CDP: {cdp_url}")

    # Connect to the Tzafon browser via CDP
    browser = playwright.chromium.connect_over_cdp(cdp_url)

    # Get the existing context and page
    context = browser.contexts[0]
    page = context.pages[0]

    try:
        # Navigate to a page
        print("Navigating to website...")
        page.goto("https://httpbin.org/ip", wait_until="networkidle", timeout=30000)

        # Wait for content to load
        time.sleep(2)

        # Take a screenshot
        page.screenshot(path="screenshot_with_proxy.png")
        print("Screenshot saved: screenshot_with_proxy.png")

        # Get the page content (shows IP from proxy)
        content = page.content()
        print(f"Page content: {content[:500]}")

    except Exception as e:
        print(f"Error during automation: {e}")

    finally:
        # Clean up
        context.close()
        browser.close()


def terminate_computer(computer_id: str) -> None:
    """Terminate the browser session."""
    headers = {"Authorization": f"Bearer {TOKEN}"}
    requests.delete(f"{BASE_URL}/computers/{computer_id}", headers=headers)
    print(f"Terminated computer: {computer_id}")


if __name__ == "__main__":
    computer_id = create_computer_with_proxy()

    try:
        cdp_url = f"{BASE_URL}/computers/{computer_id}/cdp?token={TOKEN}"

        with sync_playwright() as p:
            run_playwright(p, cdp_url, computer_id)
    finally:
        terminate_computer(computer_id)

Key Concepts

1. Creating a Session

First, create a Tzafon browser session:
resp = requests.post(
    f"{BASE_URL}/computers",
    json={"kind": "browser"},
    headers=headers,
)
computer_id = resp.json()["id"]

2. Setting the Proxy

Use the change_proxy action to configure the proxy before connecting Playwright:
resp = requests.post(
    f"{BASE_URL}/computers/{computer_id}/execute",
    json={
        "action": {
            "type": "change_proxy",
            "proxy_url": "http://user:pass@proxy:port"
        }
    },
    headers=headers,
)
Proxy URL Format:
  • HTTP proxy: http://username:password@host:port
  • SOCKS5 proxy: socks5://username:password@host:port

3. Connecting Playwright via CDP

Connect to the Tzafon browser using the CDP endpoint:
cdp_url = f"{BASE_URL}/computers/{computer_id}/cdp?token={TOKEN}"
browser = playwright.chromium.connect_over_cdp(cdp_url)

# Get the existing context and page (don't create new ones)
context = browser.contexts[0]
page = context.pages[0]
Use browser.contexts[0] and context.pages[0] to get the existing browser context. Don’t create new contexts or pages, as the proxy is configured on the existing session.

4. Switching Proxies Mid-Session

You can change the proxy at any time during the session:
def switch_proxy(computer_id: str, new_proxy: str) -> None:
    """Switch to a different proxy."""
    headers = {
        "Authorization": f"Bearer {TOKEN}",
        "Content-Type": "application/json",
    }

    resp = requests.post(
        f"{BASE_URL}/computers/{computer_id}/execute",
        json={"action": {"type": "change_proxy", "proxy_url": new_proxy}},
        headers=headers,
    )

    if resp.status_code == 200:
        print(f"Switched to proxy: {new_proxy}")

# Example: Rotate through proxies
proxies = [
    "http://user:pass@proxy1:port",
    "http://user:pass@proxy2:port",
    "http://user:pass@proxy3:port",
]

for proxy in proxies:
    switch_proxy(computer_id, proxy)
    page.goto("https://httpbin.org/ip")
    page.screenshot(path=f"screenshot_{proxy.split('@')[1].split(':')[0]}.png")

Use Cases

Test how your website appears from different geographic locations by switching between proxies in different regions.
Rotate through multiple proxies to distribute requests and avoid triggering rate limits.
Use residential or datacenter proxies to scrape websites that block automation.
Verify that ads display correctly in different regions by using geo-specific proxies.

Best Practices

Configure the proxy immediately after creating the session, before any page navigation.
Check the response status when setting a proxy. If the proxy is invalid or unreachable, navigation will fail.
Always terminate your computer session when done to avoid unnecessary charges.
Set appropriate timeouts for page navigation, as proxies may increase latency.