Install
Minimal example
import puppeteer from 'puppeteer';
const auth = `${process.env.AVP_KEY}:${process.env.AVP_SECRET}`;
const browser = await puppeteer.launch({
args: ['--proxy-server=http://api.atlasvpn.live:7777'],
});
const page = await browser.newPage();
// Auth via page.authenticate — Chromium's proxy-server arg doesn't
// accept user:pass@host:port inline; you have to authenticate via the
// DevTools protocol.
await page.authenticate({
username: process.env.AVP_KEY, // avp_live_...
password: process.env.AVP_SECRET, // 64-char hex
});
await page.goto('https://ifconfig.me');
console.log(await page.content());
// → a residential IP
await browser.close();
Sticky session
Puppeteer inherits Chromium’s single-proxy-per-browser model. To use a sticky session, embed the tag in the username:
const sessionTag = `scrape-${Date.now()}`;
await page.authenticate({
username: `avp_live_<key>-country-us-session-${sessionTag}`,
password: '<secret>',
});
// All subsequent requests from this page use the same US residential
// exit for 10 minutes.
One Puppeteer browser instance = one sticky session. To rotate IPs, launch a fresh browser with a different username (-session-<newTag>). Browser launch is slow (~1s) so batch your scraping runs to minimise restarts.
Rotating IPs per-page
async function scrapeWithFreshIp(url) {
const tag = Math.random().toString(36).slice(2, 10);
const browser = await puppeteer.launch({
args: ['--proxy-server=http://api.atlasvpn.live:7777'],
});
const page = await browser.newPage();
await page.authenticate({
username: `avp_live_<key>-country-fr-session-${tag}`,
password: '<secret>',
});
try {
await page.goto(url, { waitUntil: 'networkidle2' });
return await page.content();
} finally {
await browser.close();
}
}
Handling anti-bot tech
Puppeteer through a residential IP defeats IP-based bot detection but NOT behavioural detection (mouse movement, timing, fingerprinting). For those, add:
- puppeteer-extra-plugin-stealth — patches common bot-detection tells
- human-like delays —
await page.waitForTimeout(randint(500, 2000))
- Real user-agent rotation — match Chrome versions currently in market
Residential IP + stealth plugin + realistic timing beats most commercial bot-detection products. The exceptions are the most advanced ones (PerimeterX, Datadome, Arkose Labs) — those require dedicated anti-bot SaaS.
Chromium + Docker
FROM node:20-slim
RUN apt-get update && apt-get install -y \
ca-certificates chromium fonts-liberation libappindicator1 \
libasound2 libatk-bridge2.0-0 libatk1.0-0 libcups2 libdbus-1-3 \
libgbm1 libgtk-3-0 libnspr4 libnss3 libx11-xcb1 libxcomposite1 \
libxdamage1 libxrandr2 xdg-utils --no-install-recommends
WORKDIR /app
COPY package*.json ./
RUN npm ci --production
COPY . .
CMD ["node", "scrape.js"]
Pass AVP_KEY and AVP_SECRET as env vars at run-time, NEVER bake them into the image.