Skip to content
Advanced / 9 min read

How to Rotate IPRoyal Residential Proxies with Playwright on Linux for Web Scraping

Use IPRoyal residential proxies with Playwright on Linux for browser-based scraping. This advanced tutorial covers HTTP and SOCKS5 endpoints, sticky sessions, country targeting, rotation, and verification.

Linux SOCKS5 HTTP(S) Web Scraping

How to Rotate IPRoyal Residential Proxies with Playwright on Linux for Web Scraping

Overview

Playwright is a browser automation framework that can drive Chromium, Firefox, and WebKit. For web scraping, browser automation is useful when a target site depends on JavaScript, cookies, or dynamic rendering. IPRoyal residential proxies give you rotating IPs from a large pool, and IPRoyal also offers datacenter and ISP proxies for different trade-offs. This tutorial shows how to connect Playwright on Linux to IPRoyal residential proxies over HTTP or SOCKS5, rotate sessions, use sticky sessions, apply geo-targeting, and verify the exit IP. It is written for advanced browser automation work where you already understand Python, async code, and basic proxy authentication.

Prerequisites

  • A Linux machine or Linux server with a desktop or headless environment.
  • Python 3.10 or newer.
  • An IPRoyal account with residential proxy credentials from the IPRoyal dashboard.
  • The host, port, username, and password for your IPRoyal proxy endpoint.
  • Basic familiarity with Python, async/await, and Playwright.
  • Permission to scrape the target site, and a review of its terms and robots.txt.

How Playwright Uses IPRoyal Proxies

Playwright can send traffic through a proxy at the browser launch level or at the browser context level. IPRoyal residential proxies use username/password authentication. The exact host, port, and username parameters come from your IPRoyal dashboard.

Use the following table to choose the server value in Playwright:

IPRoyal proxy type Playwright server value Notes
Residential HTTP/HTTPS http://HOST:PORT Common choice for browser automation; works with HTTPS targets.
Residential SOCKS5 socks5://HOST:PORT Use if your IPRoyal plan exposes a SOCKS5 endpoint or you have SOCKS5 enabled.
Datacenter http://HOST:PORT or socks5://HOST:PORT Faster and cheaper, but more likely to be blocked on sensitive targets.
ISP http://HOST:PORT or socks5://HOST:PORT Static or sticky IP options can help with logged-in workflows.
Shadowsocks Local SOCKS5 listener Playwright does not speak Shadowsocks directly. Run a local Shadowsocks client and point Playwright to its SOCKS5 port.

IPRoyal lists HTTP, SOCKS5, and Shadowsocks among its supported protocols, so you can mix browser automation with other tools later.

Steps

1. Install Playwright and Chromium on Linux

Create an isolated Python environment and install Playwright with Chromium.

python3 -m venv .venv
source .venv/bin/activate
pip install --upgrade pip
pip install playwright python-dotenv
python -m playwright install --with-deps chromium

The --with-deps flag installs the system libraries Chromium needs on Debian and Ubuntu. On other distributions, install the equivalent Chromium dependencies or use the Playwright Docker image.

2. Store IPRoyal Proxy Credentials Safely

Create a .env file in your project directory. Do not commit it to version control.

IPROYAL_PROXY_HOST=your-iproyal-host
IPROYAL_PROXY_PORT=your-iproyal-port
IPROYAL_PROXY_USER=your-iproyal-username
IPROYAL_PROXY_PASS=your-iproyal-password
IPROYAL_PROXY_SCHEME=http

Use the exact values from your IPRoyal dashboard. Set IPROYAL_PROXY_SCHEME to http for HTTP/HTTPS endpoints or socks5 for SOCKS5 endpoints.

3. Build a Reusable Proxy Helper

Create proxy_config.py. This helper reads your credentials and builds the dictionary Playwright expects.

import os
from dataclasses import dataclass
from dotenv import load_dotenv

load_dotenv()

@dataclass(frozen=True)
class ProxyConfig:
    server: str
    username: str
    password: str

def iproyal_proxy(
    session_id: str | None = None,
    country: str | None = None,
) -> ProxyConfig:
    '''
    Build a Playwright proxy dict for IPRoyal.

    The session and country syntax must match your IPRoyal dashboard.
    The examples below show common patterns only. Replace the f-strings
    with the exact format IPRoyal gives you.
    '''
    host = os.environ['IPROYAL_PROXY_HOST']
    port = os.environ['IPROYAL_PROXY_PORT']
    scheme = os.environ.get('IPROYAL_PROXY_SCHEME', 'http')
    username = os.environ['IPROYAL_PROXY_USER']
    password = os.environ['IPROYAL_PROXY_PASS']

    if country:
        # Example pattern only. Check your IPRoyal dashboard for the exact syntax.
        username = f'{username}-country-{country}'
    if session_id:
        # Example pattern only. Sticky sessions usually attach a session token.
        username = f'{username}-session-{session_id}'

    return ProxyConfig(
        server=f'{scheme}://{host}:{port}',
        username=username,
        password=password,
    )

If your IPRoyal username already contains targeting parameters, do not duplicate them. Use the format shown in the dashboard and adapt the helper.

4. Launch Playwright with a Rotating IPRoyal Proxy

Create browser_check.py. Launch Chromium with the proxy and verify the exit IP.

import asyncio
from playwright.async_api import async_playwright
from proxy_config import iproyal_proxy

async def main() -> None:
    proxy = iproyal_proxy()
    async with async_playwright() as p:
        browser = await p.chromium.launch(
            headless=True,
            proxy={
                'server': proxy.server,
                'username': proxy.username,
                'password': proxy.password,
            },
        )
        context = await browser.new_context()
        page = await context.new_page()
        await page.goto('https://httpbin.org/ip', wait_until='domcontentloaded')
        print(await page.locator('body').inner_text())
        await browser.close()

if __name__ == '__main__':
    asyncio.run(main())

Run it with:

python browser_check.py

If the JSON response shows an IP that is not your own, the proxy is working. If you omit a session ID, a rotating residential endpoint should return different IPs across new requests or new sessions.

5. Add Sticky Sessions for Multi-Step Flows

Some workflows, such as filling a cart or completing a multi-step form, need the same exit IP for several requests. Use a sticky session token from your IPRoyal dashboard.

async def sticky_session_example() -> None:
    proxy = iproyal_proxy(session_id='checkout-001')
    async with async_playwright() as p:
        browser = await p.chromium.launch(
            headless=True,
            proxy={
                'server': proxy.server,
                'username': proxy.username,
                'password': proxy.password,
            },
        )
        context = await browser.new_context()
        page = await context.new_page()
        await page.goto('https://httpbin.org/ip', wait_until='domcontentloaded')
        print(await page.locator('body').inner_text())
        await browser.close()

Keep the same session_id for the whole workflow. Use a new session ID when you want a new exit IP. Sticky session lifetime and availability depend on your IPRoyal plan and dashboard settings.

6. Apply Country and City Targeting

Country targeting is usually passed through the proxy username. Use the exact country code and parameter format from your IPRoyal dashboard.

proxy = iproyal_proxy(country='us')

If IPRoyal provides city-level targeting for your plan, add it in the same place you add the country parameter. Do not guess the format; copy it from the dashboard. Verify the result by checking the exit IP with an IP geolocation service.

7. Rotate Across Concurrent Browser Contexts

For parallel scraping, reuse one browser instance and create a new context per proxy configuration. This is lighter than launching a new browser for every request.

import asyncio
from playwright.async_api import async_playwright
from proxy_config import iproyal_proxy

async def scrape_with_contexts(urls: list[str]) -> list[str]:
    async with async_playwright() as p:
        browser = await p.chromium.launch(headless=True)

        async def one(url: str, idx: int) -> str:
            proxy = iproyal_proxy(session_id=f'job-{idx}')
            context = await browser.new_context(
                proxy={
                    'server': proxy.server,
                    'username': proxy.username,
                    'password': proxy.password,
                }
            )
            page = await context.new_page()
            await page.goto(url, wait_until='domcontentloaded', timeout=60000)
            title = await page.title()
            await context.close()
            return title

        results = await asyncio.gather(*(one(url, i) for i, url in enumerate(urls)))
        await browser.close()
        return results

Start with low concurrency, monitor block rates, and increase gradually. Too many parallel sessions from the same target can trigger rate limiting even when you rotate IPs.

8. Verify the Exit IP Before Every Large Job

Add a small verification step to your scraper. Check the exit IP at the start of a job and compare it with the expected country or session behavior.

async def verify_exit_ip(page) -> str:
    await page.goto('https://httpbin.org/ip', wait_until='domcontentloaded')
    body = await page.locator('body').inner_text()
    print(body)
    return body

If the IP is wrong, fix the proxy username or session parameters before running the full crawl.

Troubleshooting

Symptom Likely cause Fix
407 Proxy Authentication Required Wrong username, wrong password, or credentials not passed correctly Confirm the IPRoyal username and password. Use Playwright's username and password fields instead of embedding credentials in the server URL.
net::ERR_PROXY_CONNECTION_FAILED Wrong host, port, or scheme; firewall blocking the proxy port Check the host and port in the IPRoyal dashboard. Try HTTP and SOCKS5 separately. Test with curl before using Playwright.
Same exit IP every request Sticky session is active, or the endpoint is not rotating Remove the session ID, create a new session, or check your IPRoyal rotation settings.
SOCKS5 fails but HTTP works Wrong scheme or port Use socks5://HOST:PORT and the SOCKS5 port from the dashboard.
Shadowsocks connection fails Playwright does not support Shadowsocks natively Run a local Shadowsocks client and point Playwright to its local SOCKS5 listener.
Site shows captchas or blocks Too many requests per IP, browser fingerprint mismatch, or datacenter IPs on a sensitive target Slow down, use residential proxies, rotate sessions, reuse realistic contexts, and respect the target site's rules.

A quick command-line check can isolate proxy issues from Playwright issues:

curl -x 'http://USERNAME:PASSWORD@HOST:PORT' https://httpbin.org/ip

If the password contains special characters, URL-encode it or use curl's --proxy-user option.

Summary

You can use IPRoyal residential proxies with Playwright on Linux by storing credentials in .env, building a reusable proxy helper, launching Chromium or a browser context with the proxy dictionary, and rotating sessions or using sticky sessions as needed. Use HTTP for simplicity, SOCKS5 when you need it, and a local Shadowsocks client only when your workflow requires Shadowsocks-style tunneling. Verify the exit IP before large jobs, start with low concurrency, and adjust rotation and geo-targeting using the exact syntax from your IPRoyal dashboard. IPRoyal is a suggested provider for residential, datacenter, and ISP proxies, but always compare pool size, pricing, and target compatibility before committing to a scraping stack.