Chrome
The Unblocking Browser Chrome provides high-performance remote browsers running on dedicated servers and using residential proxies for connection. These browsers are fast, stable, and highly configurable. They can act as a drop-in replacement for your local browser infrastructure.
Key Features
- Fast and stable performance 
- Any proxy country selection 
- Compatible with Chrome DevTools Protocol (CDP) 
Connection Details
Connect to UBC using the following WebSocket endpoint:
wss://ubc.oxylabs.ioBasic Usage
from playwright.sync_api import sync_playwright
username = "your-username"
password = "your-password"
endpoint = "ubc.oxylabs.io"
browser_url = f"wss://{username}:{password}@{endpoint}"
with sync_playwright() as p:
    browser = p.chromium.connect_over_cdp(browser_url)
    page = browser.new_page()
    page.goto('https://example.com')
    browser.close()import { chromium } from 'playwright';
(async () => {
    const username = 'your-username';
    const password = 'your-password';
    const endpoint = 'ubc.oxylabs.io';
    const browserUrl = `wss://${username}:${password}@${endpoint}`;
    const browser = await chromium.connectOverCDP(browserUrl);
    const page = await browser.newPage();
    await page.goto('https://example.com');
    await browser.close();
})();import puppeteer from 'puppeteer';
(async () => {
  const username = 'your-username';
  const password = 'your-password';
  const endpoint = 'ubc.oxylabs.io';
  const browserUrl = `wss://${username}:${password}@${endpoint}`;
  const browser = await puppeteer.connect({
    browserWSEndpoint: browserUrl
  });
  const page = await browser.newPage();
  await page.goto('https://example.com');
  await browser.close();
})();United States Proxy Infrastructure
Users, who mainly operate in the US, can connect directly to US-based infrastructure via the special entry point. This ensures faster loading time and better browsing efficiency. To establish connection, enter the following:
wss://ubc-us.oxylabs.ioCode examples:
from playwright.sync_api import sync_playwright
username = "your-username"
password = "your-password"
endpoint = "ubc-us.oxylabs.io"
browser_url = f"wss://{username}:{password}@{endpoint}"
with sync_playwright() as p:
    browser = p.chromium.connect_over_cdp(browser_url)
    page = browser.new_page()
    page.goto('https://example.com')
    browser.close()import { chromium } from 'playwright';
(async () => {
    const username = 'your-username';
    const password = 'your-password';
    const endpoint = 'ubc-us.oxylabs.io';
    const browserUrl = `wss://${username}:${password}@${endpoint}`;
    const browser = await chromium.connectOverCDP(browserUrl);
    const page = await browser.newPage();
    await page.goto('https://example.com');
    await browser.close();
})();import puppeteer from 'puppeteer';
(async () => {
  const username = 'your-username';
  const password = 'your-password';
  const endpoint = 'ubc-us.oxylabs.io';
  const browserUrl = `wss://${username}:${password}@${endpoint}`;
  const browser = await puppeteer.connect({
    browserWSEndpoint: browserUrl
  });
  const page = await browser.newPage();
  await page.goto('https://example.com');
  await browser.close();
})();Country Selection
You can specify a country for your browser session by adding the ?p_cc parameter to your connection URL. Here are examples:
from playwright.sync_api import sync_playwright
username = "your-username"
password = "your-password"
endpoint = "ubc.oxylabs.io"
country = "US"  # Replace with desired country code
browser_url = f"wss://{username}:{password}@{endpoint}?p_cc={country}"
with sync_playwright() as p:
    browser = p.chromium.connect_over_cdp(browser_url)
    page = browser.new_page()
    page.goto('https://example.com')
    browser.close()import { chromium } from 'playwright';
(async () => {
    const username = 'your-username';
    const password = 'your-password';
    const endpoint = 'ubc.oxylabs.io';
    const country = 'US';  // Replace with desired country code
    const browserUrl = `wss://${username}:${password}@${endpoint}?p_cc=${country}`;
    const browser = await chromium.connectOverCDP(browserUrl);
    const page = await browser.newPage();
    await page.goto('https://example.com');
    await browser.close();
})();import puppeteer from 'puppeteer';
(async () => {
    const username = 'your-username';
    const password = 'your-password';
    const endpoint = 'ubc.oxylabs.io';
    const country = 'US';  // Replace with desired country code
    const browserUrl = `wss://${username}:${password}@${endpoint}?p_cc=${country}`;
    const browser = await puppeteer.connect({
        browserWSEndpoint: browserUrl
    });
    const page = await browser.newPage();
    await page.goto('https://example.com');
    await browser.close();
})();If no country is specified, the system will automatically assign one based on availability.
Browser Arguments
Unblocking Browser Chrome accepts additional browser arguments passed with connection URL in the format of ?bargs=. These GET parameters specify command-line arguments that browsers should be started with. 
- If the argument should have value, we use - bargs=argname:argvalue;
- If the argument is just a flag, we use - bargs=flagname.
Currently, Oxylabs Unblocking Browser Chrome supports the following arguments:
force-color-profile:<profile>
Force all monitors to be treated as though they have the specified color profile.
window-position:X,Y
Specifies the initial window position.
hide-scrollbars
Prevents creating scrollbars for web content – useful for taking consistent screenshots.
enable-features:<feature1>,<feature2>,<feature3>
Comma-separated list of feature names to enable.
disable-notifications
Disables the Web Notification and the Push APIs.
Usage example:
from playwright.sync_api import sync_playwright
username = "your-username"
password = "your-password"
endpoint = "ubc.oxylabs.io"
browser_url = f"wss://{username}:{password}@{endpoint}/?bargs=force-color-profile:srgb&bargs=window-position:100,100"
with sync_playwright() as p:
    browser = p.chromium.connect_over_cdp(browser_url)
    page = browser.new_page()
    page.goto('https://example.com')
    browser.close()Device Type
You can customize how the browser emulates different device types by using the ?p_device parameter. This allows you to emulate fingerprints of the selected device types (desktop, mobile, tablet), which is particularly useful for scraping responsive layouts, mobile-specific content, or device-dependent behavior such as CAPTCHAs or UI elements.
Available ?p_device parameter values:
- desktop(default) – Emulates a standard desktop browser with a full-size viewport and desktop user-agent string.
- mobile– Simulates a smartphone experience with a smaller screen resolution, touch capabilities, and a mobile user-agent.
- tablet– Emulates a tablet device, ideal for scraping medium-sized layouts and hybrid mobile/tablet interfaces.
For example:
wss://username:[email protected]?p_device=mobileCAPTCHA Solving Events
Oxylabs will log a message to the console when a CAPTCHA is detected and is in the process of being solved. Following messages can be printed into console log:
oxylabs-captcha-solve-start
Fired when our system has detected the CAPTCHA and started solving it.
oxylabs-captcha-solve-end
Fired when the auto-solver has successfully solved the CAPTCHA.
oxylabs-captcha-solve-error
Fired when the auto-solver has failed to solve the CAPTCHA.
You can subscribe to these events to pause your automation and resume only after the CAPTCHA has been successfully handled. Normally CAPTCHA solving takes up to 30 seconds depending on the type and complexity of the CAPTCHA, but in some cases could take longer so allow time for CAPTCHA solving to end.
Check out the below example of how these events can be handled.
import asyncio
import time
from typing import Any
from playwright.async_api import async_playwright
# Fill in the username and password
UB_USERNAME: str = ""
UB_PASSWORD: str = ""
UB_BROWSER_URL: str = f"wss://{UB_USERNAME}:{UB_PASSWORD}@ubc-us.oxylabs.io"
class UBScraper:
    def __init__(self) -> None:
        self.OXYLABS_CAPTCHA_START_MESSAGE: str = "oxylabs-captcha-solve-start"
        self.OXYLABS_CAPTCHA_DONE_MESSAGE: str = "oxylabs-captcha-solve-end"
        self.CAPTCHA_STARTED: bool = True
        self.CAPTCHA_SOLVED: bool = False
    async def handle_console(self, msg: Any) -> None:
        msg_args = msg.args
        for arg in msg_args:
            log_message = str(arg)
            print(log_message)
            if log_message.strip() == self.OXYLABS_CAPTCHA_START_MESSAGE:
                print("Captcha started to solve!")
                self.CAPTCHA_STARTED = True
            if log_message.strip() == self.OXYLABS_CAPTCHA_DONE_MESSAGE:
                print("Captcha finished solving!")
                self.CAPTCHA_SOLVED = True
    async def wait_for_captcha_completion(self, timeout_seconds: int = 20) -> bool:
        start_time = time.time()
        check_interval = 1
        print(f"Waiting for captcha to complete (timeout: {timeout_seconds}s)")
        while not self.CAPTCHA_SOLVED:
            elapsed = time.time() - start_time
            if elapsed > timeout_seconds:
                print(f"Timeout after {elapsed:.1f}s waiting for captcha")
                return False
            if int(elapsed) % 5 == 0:
                print(f"Still waiting for captcha... ({int(elapsed)}s)")
            await asyncio.sleep(check_interval)
        completion_time = time.time() - start_time
        print(f"Captcha completed after {completion_time:.1f}s")
        return True
    async def scrape(self, url: str) -> None:
        async with async_playwright() as playwright:
            start = time.time()
            browser = await playwright.chromium.connect_over_cdp(
                UB_BROWSER_URL,
            )
            print(f"Connecting to browser took {time.time() - start:.2f} seconds")
            context = browser.contexts[0]
            page = await context.new_page()
            page.on("console", self.handle_console)
            await page.goto(url)
            captcha_completed = await self.wait_for_captcha_completion(
                timeout_seconds=30
            )
            if not captcha_completed:
                raise Exception("Failed to solve")
            await page.screenshot(path="cf_captcha_check_.png")
            print("done")
            input("Enter to close")
if __name__ == "__main__":
    import asyncio
    # replace with URL of your choice
    URL = "https://www.indeed.com/cmp/Bank-of-the-West/reviews?lang=any&fcountry=ALL&sort=date"
    asyncio.run(UBScraper().scrape(URL))const {chromium} = require('playwright');
const sleep = require('util').promisify(setTimeout)
const
    CAPTCHA_SOLVE_START = 'oxylabs-captcha-solve-start',
    CAPTCHA_SOLVE_END = 'oxylabs-captcha-solve-end',
    CAPTCHA_SOLVE_ERROR = 'oxylabs-captcha-solve-error',
    UB_BROWSER_URL = 'wss://<username>:<password>@ubc.headlesify.io',
    CAPTCHA_CHECK_INTERVAL_SEC = 1,
    CAPTCHA_CHECK_TIMEOUT_SEC = 30,
    TARGET_URL = 'https://www.indeed.com/cmp/Bank-of-the-West/reviews?lang=any&fcountry=ALL&sort=date';
(async () => {
    console.log('Opening browser page...');
    const browser = await chromium.connectOverCDP(UB_BROWSER_URL);
    const ctx = browser.contexts()[0];
    const page = await ctx.newPage();
    // Handle console.log messages and look for Oxylabs CAPTCHA solving events
    let captchaState = null;
    page.on('console', message => {
        const msg = message.text().trim();
        if (msg.startsWith('oxylabs-captcha-')) {
            captchaState = msg;
        }
    });
    console.log('Opening target website with CAPTCHA...');
    await page.goto(TARGET_URL);
    // Wait for CAPTCHA to be solved
    for (let i = 0; i < CAPTCHA_CHECK_TIMEOUT_SEC; i++) {
        await sleep(CAPTCHA_CHECK_INTERVAL_SEC * 1000);
        // Note: for better control, you can also wait for CAPTCHA_SOLVE_START event only for certain amount of time.
        if (captchaState === CAPTCHA_SOLVE_END) {
            console.log('CAPTCHA solved successfully, continue scraping...');
            break;
        }
    }
    // Check if captcha was solved successfully
    if ([CAPTCHA_SOLVE_START, CAPTCHA_SOLVE_ERROR].includes(captchaState)) {
        console.error('Could not solve CAPTCHA. Try increasing CAPTCHA_CHECK_TIMEOUT_SEC.');
        process.exit(1);
    }
    await page.waitForSelector('h1[data-testid="PageHeader-title-reviews"]');
    console.log('Making a screenshot...');
    await page.screenshot({ path: 'page_screenshot.jpg' });
    await page.close();
    await browser.close();
    console.log('Done.');
    process.exit(0);
})();const puppeteer = require('puppeteer');
const sleep = require('util').promisify(setTimeout);
const
    CAPTCHA_SOLVE_START = 'oxylabs-captcha-solve-start',
    CAPTCHA_SOLVE_END = 'oxylabs-captcha-solve-end',
    CAPTCHA_SOLVE_ERROR = 'oxylabs-captcha-solve-error',
    UB_BROWSER_URL = 'wss://<username>:<password>@ubc.headlesify.io',
    CAPTCHA_CHECK_INTERVAL_SEC = 1,
    CAPTCHA_CHECK_TIMEOUT_SEC = 30,
    TARGET_URL = 'https://www.indeed.com/cmp/Bank-of-the-West/reviews?lang=any&fcountry=ALL&sort=date';
(async () => {
    console.log('Opening browser page...');
    const browser = await puppeteer.connect({
        browserWSEndpoint: UB_BROWSER_URL,
        defaultViewport: null
    });
    const pages = await browser.pages();
    const page = pages.length > 0 ? pages[0] : await browser.newPage();
    // Handle console.log messages and look for Oxylabs CAPTCHA solving events
    let captchaState = null;
    page.on('console', msg => {
        const text = msg.text().trim();
        if (text.startsWith('oxylabs-captcha-')) {
            captchaState = text;
        }
    });
    console.log('Opening target website with CAPTCHA...');
    await page.goto(TARGET_URL, { waitUntil: 'domcontentloaded' });
    for (let i = 0; i < CAPTCHA_CHECK_TIMEOUT_SEC; i++) {
        await sleep(CAPTCHA_CHECK_INTERVAL_SEC * 1000);
        if (captchaState === CAPTCHA_SOLVE_END) {
            console.log('CAPTCHA solved successfully, continue scraping...');
            break;
        }
    }
    if ([CAPTCHA_SOLVE_START, CAPTCHA_SOLVE_ERROR].includes(captchaState)) {
        console.error('Could not solve CAPTCHA. Try increasing CAPTCHA_CHECK_TIMEOUT_SEC.');
        process.exit(1);
    }
    await page.waitForSelector('h1[data-testid="PageHeader-title-reviews"]');
    console.log('Making a screenshot...');
    await page.screenshot({ path: 'page_screenshot.jpg' });
    await page.close();
    await browser.disconnect();  // use disconnect for remote sessions
    console.log('Done.');
    process.exit(0);
})();Dynamic CAPTCHA Solving
By default, Unblocking Browser automatically detects and solves CAPTCHAs immediately when a page loads. However, some websites display CAPTCHAs at later stages, such as popup windows when submitting forms or after specific user interactions.
Unblocking Browser allows you to trigger CAPTCHA detection and solving manually at any point during your session. To manually trigger CAPTCHA solving, execute the following code to send a message to the window object:
window.postMessage({action: 'solve_captcha', type: '<captcha type>'}, '*')Supported CAPTCHA types include:
- hcaptcha
- recaptcha
- turnstile(Cloudflare CAPTCHA)
Example of usage (Playwright / Puppeteer JavaScript):
// ...
await page.click('#form-submit');
// Now we know that CAPTCHA should be shown
await page.evaluate(() => {
  window.postMessage({action: 'solve_captcha', type: 'recaptcha'}, '*')
});
// Follow `oxylabs-captcha-start` and `oxylabs-captcha-end` events like a regular case
// ...Turnstile CAPTCHA requires a different approach since it must be intercepted before it appears on screen. To do so, initiate CAPTCHA detection first, then perform the action that triggers the CAPTCHA:
// We know that our next action may trigger Turnstile CAPTCHA
await page.evaluate(() => {
  window.postMessage({action: 'solve_captcha', type: 'turnstile'}, '*')
});
await page.click('#form-submit');
// Follow `oxylabs-captcha-start` and `oxylabs-captcha-end` events like a regular case
// ...Last updated
Was this helpful?

