The costly mistake is rewriting a working scraper to fix blocks that are really a proxy problem. Neither tool changes your IP or solves CAPTCHAs. In Playwright vs Selenium for web scraping, Playwright wins on proxy logins, waiting and traffic control, while Selenium wins on languages and existing code. Here’s what changes if you switch.
Pick Playwright for new scrapers: its docs show a proxy per browser context with an HTTP(S) login, it auto-waits on five checks before each action, and it can block images to save proxy traffic. Keep Selenium if you have working code or need Ruby or Kotlin: it covers six languages in its docs, but shows no proxy login field.
Playwright’s GitHub page shows 98.8k stars, almost three times Selenium’s 34.5k, but stars aren’t the reason it wins here.
| Playwright | Selenium | |
|---|---|---|
| Price | Free, Apache-2.0 | Free, Apache-2.0 |
| Proxy setup | Per browser or per context | Manual proxy capability |
| Proxy login | Username and password for HTTP(S) | Not shown on the options page |
| Waiting | Auto-waits on 5 checks | Implicit wait defaults to 0; explicit waits in your code |
| Network control | Route, abort, modify responses | Not on the pages read |
| Languages | JavaScript, Python, .NET, Java | Java, Python, C#, Ruby, JavaScript, Kotlin |
| Browsers | Chromium, Firefox, WebKit | Chrome, Edge, Firefox |
| Driver setup | Browsers installed with the library | Selenium Manager downloads drivers |
| Sessions | Isolated contexts, parallel by default | Remote WebDriver and Grid |
| AI agents | Official MCP server and CLI | Third-party MCP servers, llms.txt |
| Support and refunds | Open source, nothing to refund | Open source, nothing to refund |
Every cell comes from playwright.dev, selenium.dev and each project’s GitHub page, read on October 29, 2026. Neither project publishes benchmarked speed figures.
Playwright takes the rows that cost money in scraping: proxy logins, fewer failed runs from timing, and blocking heavy files so you pay for less proxy traffic. Selenium takes the rows that cost time to change: six languages in its docs, real installed browsers, and years of code you may already have.
New scraper? Playwright. Working Selenium code and no proxy pain? Stay put.
Both licences cost $0, so the bill you’ll actually see comes from somewhere else.
Playwright and Selenium are both Apache-2.0, per their GitHub pages. What you pay for is the machine that runs the browsers, the proxy traffic each page load uses, and the developer hours spent on runs that fail. That last cost is where the two differ most.
If you currently use Selenium, switching costs developer time, not money. Expect the migration to take about as many edits as you have waits and locators: each explicit wait can usually go, and each find_element call becomes a Playwright locator. Your parsing code and proxy list carry over as they are.
Servers matter too. If you run browsers on rented machines, see our ranking of VPS for proxy servers before you size them.
The licence is free. Failed runs and wasted proxy gigabytes are not.
Selenium’s options page shows proxy code in four languages, and none of it has a username or password.
Playwright’s network page says a proxy can be set globally for the whole browser or for each browser context. The examples pass server, username and password, and the page says traffic can go through an HTTP(S) proxy or SOCKSv5. The login note covers HTTP(S) only.
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch()
context = browser.new_context(proxy={
"server": "http://PROXY_HOST:PROXY_PORT",
"username": "PROXY_USER",
"password": "PROXY_PASS",
})
page = context.new_page()
page.goto("https://httpbin.org/ip")
print(page.text_content("body"))
browser.close()
Selenium’s options page sets the proxy capability with a manual proxy type. In Python, that’s a Proxy object with httpProxy and sslProxy values. Because no login field appears on the page, the simplest route is to allowlist your server’s IP address in your proxy provider’s dashboard.
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy, ProxyType
options = webdriver.ChromeOptions()
options.proxy = Proxy({
"proxyType": ProxyType.MANUAL,
"httpProxy": "PROXY_HOST:PROXY_PORT",
"sslProxy": "PROXY_HOST:PROXY_PORT",
})
driver = webdriver.Chrome(options=options)
driver.get("https://httpbin.org/ip")
print(driver.find_element("tag name", "body").text)
driver.quit()
Switching from Selenium means one change here: the proxy moves from the driver’s options into a dictionary on the browser or the context. If you rotate many proxies, give each context its own and keep one browser process running. For the IPs themselves, start from our best residential proxies ranking.
Selenium’s default implicit wait is 0, so an element that appears half a second late fails straight away.
Its waits page offers two fixes. An implicit wait is a global setting for every element lookup in the session. An explicit wait is a loop in your code that polls until a condition is true or a timeout raises an error. The page warns not to mix them: a 10-second implicit wait plus a 15-second explicit wait could time out after 20 seconds.
Playwright moves that work into the library. Its auto-waiting page lists five checks: visible, stable, enabled, receives events and editable. A click runs every check except editable, and a fill runs visible, enabled and editable. If the checks don’t pass within the timeout, the action fails with a TimeoutError.
Selenium waits when you tell it to. Playwright waits unless you tell it not to.
Proxy providers bill by the gigabyte, and images, fonts and video are usually the heaviest part of a page.
Playwright’s network page lets you route every request, abort it by resource type, change headers or the method, and fetch then rewrite a response. For a scraper behind a paid proxy, aborting images, media and fonts means those bytes never cross the proxy. The pages read on selenium.dev don’t cover request interception.
from playwright.sync_api import sync_playwright
BLOCK = ("image", "media", "font")
with sync_playwright() as p:
browser = p.chromium.launch(proxy={"server": "http://PROXY_HOST:PROXY_PORT"})
page = browser.new_page()
page.route("**/*", lambda route: route.abort() if route.request.resource_type in BLOCK else route.continue_())
page.goto("https://example.com")
print(page.title())
browser.close()
Isolation matters for bandwidth too. Playwright’s README says each test gets its own browser context with near-zero overhead, and tests run in parallel by default. Selenium scales out with Remote WebDriver and Grid, which run whole browser sessions on other machines.
Blocked by CAPTCHAs instead? Neither tool solves them. Pair either one with one of the best CAPTCHA solvers, or move hard targets to one of the cloud browsers for AI scraping.
The cheapest gigabyte is the one you never download.
Very little of your scraping logic breaks; the plumbing around it does.
If you currently use Selenium Grid, plan the scaling part separately: Playwright’s parallel runs happen in worker processes and contexts rather than on a Grid hub. If you write Ruby, there’s no Playwright binding on the pages read, so stay with Selenium.
Only one of the two ships its own MCP server, a standard way for AI agents to call tools.
Playwright’s repository includes an MCP server that gives agents browser control through structured accessibility snapshots, plus a CLI it calls more token-efficient than MCP. Selenium’s AI agents page points agents to an llms.txt index, its docs and examples, and says the MCP servers that exist are community projects, not part of Selenium.
Selenium’s page has one useful warning for migrations driven by an agent: find_element_by methods were removed in 4.3, and executable_path and desired_capabilities were removed in 4.10 for Python. Old tutorials still use them, so tell your agent which version you run.
Playwright is the better scraping tool on the pages read. It sets a proxy for the whole browser or for each browser context, with a username and password for HTTP(S) proxies, and it auto-waits on five actionability checks before every action. The weak spot: its docs don’t confirm a login for SOCKS5 proxies, and it has no Ruby binding.
Its network page lets you route, abort and rewrite requests. For scraping, that means you can drop images, media and fonts before they download, which cuts the gigabytes you pay a proxy provider for. The GitHub page lists Chromium, Firefox and WebKit on Linux, macOS and Windows, headless or headed.
If you currently use Selenium, the biggest change is the browser context: a separate, cookie-isolated session inside one browser, which the README says has near-zero overhead. One context per proxy replaces one browser per proxy. The repository also ships an MCP server and a CLI for AI agents.
Check before you switch: Does your provider give HTTP(S) proxies with a login? Do you write in JavaScript, Python, .NET or Java? Do your target pages build content with JavaScript? If all three are yes, Playwright fits.
| Plan | Price | What you get | Proxies |
|---|---|---|---|
| Library | Free, Apache-2.0 | JavaScript, Python, .NET, Java | Per browser or per context |
| Playwright Test | Free | Parallel by default, traces | Per browser or per context |
| MCP server and CLI | Free | AI agents drive the browser | Same proxy settings |
The GitHub page showed no release list when read, so the latest version isn’t stated here. The network page says proxies can be HTTP(S) or SOCKSv5 but mentions a login only for HTTP(S).
Verdict: The default pick for new scrapers that rotate proxies.
Selenium is the safer pick when you already have working code or need a language Playwright lacks. Its docs show examples in Java, Python, C#, Ruby, JavaScript and Kotlin, and Selenium Manager downloads drivers on its own. The weak spot: the options page shows proxy code with no username or password, and its default implicit wait is 0.
The project calls itself an umbrella of tools built on the W3C WebDriver specification, which drives real installed browsers. Selenium Manager has shipped with every release since 4.6, finds the browser version, downloads the matching driver and caches it. Since 4.11 it can download Chrome too, with Firefox from 4.12 and Edge from 4.14.
The waiting rules are where scrapers break. The waits page says the default implicit wait is 0, so a missing element fails at once. It also warns not to mix implicit and explicit waits, because a 10-second implicit wait with a 15-second explicit wait could time out after 20 seconds.
Check before you stay: Do you have hundreds of lines of working Selenium code? Do you need Ruby or Kotlin? Does your proxy provider support an IP allowlist instead of a login? If two are yes, keeping Selenium is reasonable.
| Plan | Price | What you get | Proxies |
|---|---|---|---|
| WebDriver bindings | Free, Apache-2.0 | Java, Python, C#, Ruby, JavaScript | Manual proxy capability |
| Selenium Manager | Free, built in | Drivers since 4.6, browsers since 4.11 | Uses the browser proxy or SE_PROXY |
| Grid | Free | Remote and parallel sessions | Set per session |
The options page’s proxy section showed code but no explanatory text when read, so the full list of proxy types isn’t confirmed. The GitHub page listed no releases; the AI agents page uses 4.49.0 as its example version.
Verdict: The pick for existing suites and extra languages, if you handle proxy logins yourself.
Still choosing proxies for either tool? See all proxy rankings, and test your proxies with GoToProxy before you wire them into code.
We read Playwright’s network and auto-waiting docs and its GitHub page, and Selenium’s options, waits, Selenium Manager and AI agent docs and its GitHub page, on October 29, 2026. Where a page is silent, the article says so. Nobody here ran a benchmark. Scores weight proxy handling highest. Compare tools with independent proxy ratings on ProxyRates for the proxies you pair them with. Scores are our editorial rating built from published prices, features and terms. They are not lab measurements.