Why Use Remote Cloud Browsers with Puppeteer?
Traditional Puppeteer scripts rely on puppeteer.launch(), which spins up a Chromium subprocess on your local machine or server. While convenient for simple tasks, local browser automation hits severe roadblocks at scale:
- Memory Exhaustion: Each Chrome instance uses 150MB–400MB of RAM. A single server running 20 parallel threads will crash.
- Anti-Bot Fingerprint Leaks: Standard Puppeteer exposes `navigator.webdriver = true` and incomplete WebGL vendor information.
- CAPTCHA Blockades: Complex Cloudflare Turnstile, reCAPTCHA v2/v3, and DataDome challenges cannot be clicked or solved natively by standard Puppeteer scripts without complex plugins.
Step 1: Install Puppeteer Core
Because you will be connecting to a remote Chrome instance rather than launching a local Chromium binary, you should install puppeteer-core instead of full puppeteer. This saves ~300MB of disk space and eliminates Linux system library dependencies:
npm install puppeteer-coreStep 2: Connect via browserWSEndpoint
Connecting to 2Captcha Browser API requires only passing the WebSocket endpoint URL containing your API key to puppeteer.connect():
import puppeteer from 'puppeteer-core';
const API_KEY = process.env.TWOCAPTCHA_API_KEY || 'YOUR_2CAPTCHA_KEY';
// CDP WebSocket URL with built-in CAPTCHA solver enabled
const wsEndpoint = `wss://browser.2captcha.com/connect?apiKey=${API_KEY}&autoSolve=true&country=us`;
async function scrapeProtectedSite() {
console.log('Connecting to 2Captcha Cloud Browser...');
const browser = await puppeteer.connect({
browserWSEndpoint: wsEndpoint,
defaultViewport: { width: 1920, height: 1080 }
});
try {
const page = await browser.newPage();
console.log('Navigating to target protected website...');
await page.goto('https://nowsecure.nl', { waitUntil: 'networkidle2' });
// The remote browser handles Cloudflare Turnstile verification automatically!
console.log('Page Title:', await page.title());
// Take a screenshot of the bypassed page
await page.screenshot({ path: 'scraped_page.png', fullPage: true });
console.log('Screenshot saved successfully.');
} finally {
// Always close the browser to stop the billing session
await browser.close();
}
}
scrapeProtectedSite().catch(console.error);Step 3: Handling Auto CAPTCHA Solving
When you connect to 2Captcha Browser API with autoSolve=true, the cloud infrastructure listens to DOM mutations and network requests for CAPTCHA widgets (Cloudflare Turnstile, reCAPTCHA, hCaptcha, GeeTest).
When a challenge appears, the background solver completes the challenge and injects the authorization token directly into the browser DOM—without requiring custom Puppeteer code or manual frame manipulation.
Key Best Practices
- Always call `await browser.close()`: Cloud browsers bill based on session duration or computing minutes. Ensure your code wraps execution in a
try / finallyblock. - Specify Geolocation: If scraping localized ecommerce or travel pricing, specify the residential country code in the WebSocket URL (e.g.,
&country=deor&country=us). - Handle Network Disconnects Gracefully: Add reconnection logic with exponential backoff if running 24/7 web scraping pipelines.