如何解决Puppeteer中net::ERR_CONNECTION_RESET等系列连接错误
First, let's break down your problem: those ERR_CONNECTION_RESET/CLOSED/FAILED errors are likely a mix of unreliable free proxies and Google flagging your Puppeteer instance as a bot. Let's start with beefing up your bot detection evasion, then cover proxy best practices.
Step 1: Enhance Your preparePageForTests Function
Add these additional mocks and tweaks to make your browser instance look far more like a real human user:
const preparePageForTests = async (page) => { const userAgent = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36'; await page.setUserAgent(userAgent); // Critical: Block Chrome's AutomationControlled flag (newer detection method) await page.evaluateOnNewDocument(() => { delete window.navigator.__proto__.webdriver; Object.defineProperty(navigator, 'webdriver', { get: () => undefined, }); }); // Mock real desktop hardware specs await page.evaluateOnNewDocument(() => { Object.defineProperty(navigator, 'hardwareConcurrency', { get: () => 8, // Typical desktop core count }); Object.defineProperty(navigator, 'deviceMemory', { get: () => 16, // Typical desktop RAM }); }); // Set realistic viewport and screen properties await page.setViewport({ width: 1920, height: 1080, deviceScaleFactor: 1, }); await page.evaluateOnNewDocument(() => { Object.defineProperty(window.screen, 'colorDepth', { get: () => 24, }); }); // Mock network connection details await page.evaluateOnNewDocument(() => { Object.defineProperty(navigator, 'connection', { get: () => ({ type: 'wifi', effectiveType: '4g', downlink: 10, rtt: 50, }), }); }); // Pass the Chrome Test. await page.evaluateOnNewDocument(() => { window.navigator.chrome = { app: { isInstalled: false, }, webstore: { onInstallStageChanged: {}, onDownloadProgress: {}, }, runtime: { PlatformOs: { MAC: 'mac', WIN: 'win', ANDROID: 'android', CROS: 'cros', LINUX: 'linux', OPENBSD: 'openbsd', }, PlatformArch: { ARM: 'arm', X86_32: 'x86-32', X86_64: 'x86-64', }, PlatformNaclArch: { ARM: 'arm', X86_32: 'x86-32', X86_64: 'x86-64', }, RequestUpdateCheckStatus: { THROTTLED: 'throttled', NO_UPDATE: 'no_update', UPDATE_AVAILABLE: 'update_available', }, OnInstalledReason: { INSTALL: 'install', UPDATE: 'update', CHROME_UPDATE: 'chrome_update', SHARED_MODULE_UPDATE: 'shared_module_update', }, OnRestartRequiredReason: { APP_UPDATE: 'app_update', OS_UPDATE: 'os_update', PERIODIC: 'periodic', }, } }; }); await page.evaluateOnNewDocument(() => { const originalQuery = window.navigator.permissions.query; return window.navigator.permissions.query = (parameters) => ( parameters.name === 'notifications' ? Promise.resolve({ state: Notification.permission }) : originalQuery(parameters) ); }); await page.evaluateOnNewDocument(() => { Object.defineProperty(navigator, 'plugins', { get: () => [1, 2, 3, 4, 5], }); }); await page.evaluateOnNewDocument(() => { Object.defineProperty(navigator, 'languages', { get: () => ['en-US', 'en'], }); }); // Add random delay to mimic human hesitation before navigation await page.waitForTimeout(Math.floor(Math.random() * 2000) + 1000); }
Step 2: Update Your Launch Arguments
Add these critical flags to reduce detection and fix Heroku-specific resource issues:
const browser = await puppeteerExtra.launch({ headless: 'new', // Newer headless mode is far more undetectable args: [ '--no-sandbox', '--disable-setuid-sandbox', '--proxy-server=socks4://109.94.182.128:4145', '--disable-blink-features=AutomationControlled', // Blocks core automation detection '--disable-dev-shm-usage', // Fixes memory limits on Heroku '--disable-features=VizDisplayCompositor', // Reduces fingerprinting surface '--start-maximized', // Matches our realistic viewport ]});
Step 3: Fix Proxy Reliability
Free SOCKS4 proxies from public lists are extremely unreliable—they get blocked by Google within minutes, are often slow, or dead on arrival. Here's how to fix this:
- Use paid rotating residential proxies: Services like BrightData, Oxylabs, or Smartproxy offer proxies that mimic real user IPs, making them far less likely to get blocked.
- Test proxies before use: Add a quick check to verify the proxy works (e.g., navigate to
https://api.ipify.organd confirm the IP matches your proxy). - Handle failures gracefully: Wrap your navigation code in try/catch blocks, and retry with a different proxy if you hit a connection error.
Step 4: Use Puppeteer Extra Stealth Plugin (Optional but Recommended)
Since you're already using puppeteer-extra, install the stealth plugin to automate most evasion work:
npm install puppeteer-extra-plugin-stealth
Then update your code to use it:
const puppeteerExtra = require('puppeteer-extra'); const StealthPlugin = require('puppeteer-extra-plugin-stealth'); puppeteerExtra.use(StealthPlugin()); // Rest of your code can drop most manual mocks—this plugin handles them automatically
Final Tips
- Rotate user agents: Use a list of real Chrome user agents and pick one randomly each run.
- Add human-like actions: Insert random delays between clicks, scrolls, and navigation to avoid triggering rate limits.
- Upgrade Heroku dyno: Puppeteer is resource-heavy—use at least a standard dyno to avoid memory crashes.
Content of this question originates from Stack Exchange, asked by nickcoding2

