Puppeteer

Puppeteer code examples for using Residential Proxy with Headless Chrome, sticky sessions, page authentication, and geotargeting.

Practical Puppeteer code examples for routing browser automation traffic through Residential Proxies using page.authenticate().

Prerequisites

npm install puppeteer
  • puppeteer: Node.js library providing a high-level API to control Headless Chrome or Chromium over the DevTools Protocol.

Proxy Format

Puppeteer passes the proxy server address via Chromium launch flags (--proxy-server), then authenticates using page.authenticate().

username:password@proxy.mrscraper.com:10000

For sticky sessions or targeted countries, format the username with parameters:

user-country-us-sessid-session1:password@proxy.mrscraper.com:10000

1. Basic Proxy Setup

Demonstrates the standard setup for launching Headless Chrome with proxy flags and authenticating page traffic.

import puppeteer from 'puppeteer';

const proxyHost = 'proxy.mrscraper.com';
const proxyPort = '10000';
const proxyUsername = 'user-country-us';
const proxyPassword = 'pass123';

async function testProxy() {
  const browser = await puppeteer.launch({
    headless: true,
    args: [`--proxy-server=http://${proxyHost}:${proxyPort}`]
  });

  const page = await browser.newPage();

  // Authenticate page before navigating
  await page.authenticate({
    username: proxyUsername,
    password: proxyPassword
  });

  await page.goto('https://api.ipify.org?format=json', { waitUntil: 'networkidle2' });
  const content = await page.evaluate(() => document.body.innerText);
  console.log('Your Proxy IP:', content);

  await browser.close();
}

testProxy().catch(console.error);

Use Case: Quick proxy connectivity check and baseline authentication testing in Puppeteer.

2. Sticky Session Management

Maintains a stable residential IP address across multi-step browser workflows using a consistent session ID (sessid) and explicit session duration (sesstime-20).

import puppeteer from 'puppeteer';

async function runStickySession() {
  const browser = await puppeteer.launch({
    headless: true,
    args: ['--proxy-server=http://proxy.mrscraper.com:10000']
  });

  const page = await browser.newPage();
  
  // 20-minute static session in Canada
  await page.authenticate({
    username: 'user-country-ca-sessid-checkout1-sesstime-20',
    password: 'pass123'
  });

  const urls = [
    'https://example.com/step1',
    'https://example.com/step2',
    'https://example.com/step3'
  ];

  for (const url of urls) {
    await page.goto(url, { waitUntil: 'domcontentloaded' });
    console.log(`Visited ${url} - Title:`, await page.title());
  }

  await browser.close();
}

runStickySession().catch(console.error);

Use Case: Form submissions, login workflows, and multi-page checkouts where maintaining the same IP address is mandatory.

3. Rotating Proxy Scraping

Demonstrates rotating proxies with Puppeteer. Each request uses rotating proxy credentials to automatically fetch content with a different residential IP address.

import puppeteer from 'puppeteer';

async function scrapeWithRotation(urls) {
  const browser = await puppeteer.launch({
    headless: true,
    args: ['--proxy-server=http://proxy.mrscraper.com:10000']
  });

  for (const url of urls) {
    const page = await browser.newPage();
    
    // Rotating proxy - new IP per request
    await page.authenticate({
      username: 'user-country-uk',
      password: 'pass123'
    });

    try {
      await page.goto(url, { waitUntil: 'domcontentloaded', timeout: 30000 });
      const h1Text = await page.$eval('h1', el => el.textContent).catch(() => 'No H1');
      console.log(`Scraped [${url}]: ${h1Text}`);
    } catch (err) {
      console.error(`Failed to scrape ${url}:`, err.message);
    } finally {
      await page.close();
    }
  }

  await browser.close();
}

scrapeWithRotation([
  'https://example.com/page1',
  'https://example.com/page2',
  'https://example.com/page3'
]);

Use Case: High-volume scraping across multiple target pages without triggering IP rate limits or blocklists.

4. Geotargeting & Location Testing

Demonstrates routing Puppeteer traffic through specific countries (Japan) while customizing HTTP headers and viewport to match target geographic personas.

import puppeteer from 'puppeteer';

async function testLocalizedContent() {
  const browser = await puppeteer.launch({
    headless: true,
    args: [
      '--proxy-server=http://proxy.mrscraper.com:10000',
      '--lang=ja-JP'
    ]
  });

  const page = await browser.newPage();
  
  // Target Japanese residential proxy
  await page.authenticate({
    username: 'user-country-jp',
    password: 'pass123'
  });

  await page.setExtraHTTPHeaders({
    'Accept-Language': 'ja-JP,ja;q=0.9'
  });

  await page.goto('https://httpbin.org/headers');
  console.log(await page.evaluate(() => document.body.innerText));

  await browser.close();
}

testLocalizedContent().catch(console.error);

Use Case: Auditing localized e-commerce pricing, geo-specific ad placement, and regional content availability.

5. Parallel Isolated Contexts

Uses Incognito browser contexts (createBrowserContext()) to isolate multiple concurrent worker sessions, each authenticated with a unique proxy session ID.

import puppeteer from 'puppeteer';

async function parallelWorkers() {
  const browser = await puppeteer.launch({
    headless: true,
    args: ['--proxy-server=http://proxy.mrscraper.com:10000']
  });

  const workers = ['worker_a', 'worker_b', 'worker_c'];

  const tasks = workers.map(async (workerId) => {
    // Isolated incognito context
    const context = await browser.createBrowserContext();
    const page = await context.newPage();

    await page.authenticate({
      username: `user-country-us-sessid-${workerId}`,
      password: 'pass123'
    });

    await page.goto('https://api.ipify.org?format=json');
    const ip = await page.evaluate(() => document.body.innerText);
    console.log(`Worker ${workerId} IP:`, ip);

    await context.close();
  });

  await Promise.all(tasks);
  await browser.close();
}

parallelWorkers().catch(console.error);

Use Case: Scaling automated browser tasks in parallel with dedicated IP addresses per thread without launching multiple browser instances.

6. Production Error Handling & Cleanup

Provides robust exception handling, custom navigation timeouts, response validation, and safe browser shutdown routines.

import puppeteer from 'puppeteer';

async function safeScrape(url) {
  let browser = null;
  try {
    browser = await puppeteer.launch({
      headless: true,
      args: ['--proxy-server=http://proxy.mrscraper.com:10000']
    });

    const page = await browser.newPage();
    page.setDefaultNavigationTimeout(30000);

    await page.authenticate({
      username: 'user-country-us-sessid-prod1',
      password: 'pass123'
    });

    const response = await page.goto(url, { waitUntil: 'networkidle2' });
    
    if (!response || !response.ok()) {
      throw new Error(`HTTP Error ${response?.status()}`);
    }

    console.log('Successfully fetched:', await page.title());
  } catch (error) {
    console.error('Scraping error:', error.message);
  } finally {
    if (browser) {
      await browser.close();
    }
  }
}

safeScrape('https://example.com');

Use Case: Deploying production Puppeteer bots that handle network glitches, authentication errors, and timeouts gracefully.

Notes

  • Call page.authenticate() before invoking page.goto().
  • Use --proxy-server=http://... in launch.args to direct Puppeteer traffic.
  • Use createBrowserContext() for parallel isolated sessions with unique proxy usernames.

On this page