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.
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.