Websites have gotten sharp. They spot bots a mile away. Cloudflare, anti-spam guards, and clever scripts easily flag a poorly configured Puppeteer. What happens next? Instant bans, endless captchas, and zero data collection.
But there’s a way through. Puppeteer Stealth mode turns your bot into a digital chameleon — it mimics real users so well, it slips past defenses like a ghost.
This guide shows you how to install Puppeteer Stealth, use plugins to bypass anti-bot defenses, and test your setup to avoid blocks. By the end, your scraper will run smoothly and stay under the radar.
Step 1: Download Puppeteer and Activate Stealth Mode
Setting up Stealth mode is straightforward. You need Puppeteer itself, the puppeteer-extra
framework for plugins, and the puppeteer-extra-plugin-stealth
to mask automation signs.
Run this in your terminal:
npm install puppeteer puppeteer-extra puppeteer-extra-plugin-stealth
Quick breakdown:
puppeteer
: The core Chrome automation library.puppeteer-extra
: Allows adding plugins easily.puppeteer-extra-plugin-stealth
: Makes your bot look human by hiding telltale automation markers.
By default, Puppeteer reveals itself — headers like HeadlessChrome
give it away. Stealth mode erases those fingerprints.
Step 2: Add the Stealth Plugin
Create index.js
and add this:
const puppeteer = require('puppeteer-extra');
const StealthPlugin = require('puppeteer-extra-plugin-stealth');
puppeteer.use(StealthPlugin());
(async () => {
const browser = await puppeteer.launch({ headless: true });
const page = await browser.newPage();
await page.goto('https://bot.sannysoft.com/');
await page.screenshot({ path: 'result.png' });
console.log('Test complete. Screenshot saved.');
await browser.close();
})();
Run this. The screenshot shows how stealthy your bot really is.
Step 3: Enhance Stealth with Browser Startup Flags
Make your bot even more convincing by tweaking launch options:
const browser = await puppeteer.launch({
headless: true,
args: [
'--no-sandbox',
'--disable-setuid-sandbox',
'--disable-dev-shm-usage',
'--disable-accelerated-2d-canvas',
'--disable-gpu'
]
});
Why? These flags reduce resource use and dodge some server checks.
--no-sandbox
: avoids certain Linux security restrictions.--disable-gpu
: prevents rendering artifacts that hint automation.
Step 4: Test on Real Sites
Verify your setup using these key sites:
bot.sannysoft.com
— Tests your browser’s human-like behavior.whatismybrowser.com
— Shows exactly what your bot “looks” like to servers.httpbin.org/headers
— Reveals HTTP headers your bot sends.
If these sites think you’re a real user — you’re winning.
Step 5: Hide Your IP Address with Proxies
One IP address? That’s a red flag. Too many requests from a single IP and you’re banned.
Enter proxies.
Pick the right proxy:
- Server proxies: speed + stability — great for heavy scraping.
- Mobile proxies: mimic real users — harder to detect.
Add a proxy to Puppeteer like this:
const browser = await puppeteer.launch({
headless: true,
args: ['--proxy-server=http://username:password@proxy_address:port']
});
Swap out username
, password
, proxy_address
, and port
accordingly.
Step 6: Rotate Proxies to Beat IP Limits
Static proxies? Not enough. Rotate proxies with each request to spread risk.
Here’s a sample proxy rotation setup:
const proxyList = [
'http://user1:pass1@proxy1:port',
'http://user2:pass2@proxy2:port',
'http://user3:pass3@proxy3:port'
];
const getRandomProxy = () => proxyList[Math.floor(Math.random() * proxyList.length)];
(async () => {
for (let i = 0; i < 5; i++) {
const proxy = getRandomProxy();
const browser = await puppeteer.launch({
headless: true,
args: [`--proxy-server=${proxy}`]
});
const page = await browser.newPage();
await page.goto('https://httpbin.org/ip');
console.log(`Request sent via proxy: ${proxy}`);
await browser.close();
}
})();
This randomly picks a proxy every time, keeping you off the radar.
Step 7: Validate Proxy Stability
Before full deployment, test proxies thoroughly:
- Load multiple pages through each proxy to ensure reliability.
- Measure connection speed — slow proxies waste time.
- Match proxy location with target site requirements (e.g. US content needs US IPs).
Step 8: Final Testing and Debugging
Bots fail silently. You may see errors like access denied or weird browser crashes.
Run tests against the same bot detection sites:
bot.sannysoft.com
for behavior analysiswhatismybrowser.com
for fingerprint checkshttpbin.org/headers
for header inspection
Here’s a quick test script:
const puppeteer = require('puppeteer-extra');
const StealthPlugin = require('puppeteer-extra-plugin-stealth');
puppeteer.use(StealthPlugin());
(async () => {
const browser = await puppeteer.launch({ headless: true });
const page = await browser.newPage();
await page.goto('https://bot.sannysoft.com/');
await page.screenshot({ path: 'stealth-test.png' });
console.log('Stealth test complete. Screenshot saved.');
await browser.close();
})();
Once your bot passes these, you’ve built a stealthy, resilient scraping tool ready for the wild.
Wrapping Up
Puppeteer Stealth, paired with smart proxy use and proper testing, transforms your scraper from a blatant bot into a stealthy data hunter. No more captchas. No more blocks. Just smooth, uninterrupted scraping.