Perché i browser senza testa hanno bisogno di proxy
I browser senza testa — le istanze del browser in esecuzione senza una GUI visibile — sono essenziali per la demolizione di siti web JavaScript-heavy. Tuttavia, eseguire più sessioni di browser senza testa da un unico indirizzo IP è un segnale di automazione evidente. Combinando i browser senza testa con la rotazione del proxy risolve questo distribuendo richieste in migliaia di IP residenziali.
Questa guida copre la configurazione di Puppeteer e Playwright proxy, plugin di stealth e strategie di rotazione. Per lo sfondo su come funziona il rilevamento, vedere il nostro guida ai sistemi di rilevamento anti-bot.
Set del proxy del puppeteer
Configurazione di base
// Puppeteer: Basic proxy configuration
const puppeteer = require('puppeteer');
const browser = await puppeteer.launch({
headless: 'new',
args: [
'--proxy-server=http://gate.proxyhat.com:8080',
'--no-sandbox',
'--disable-setuid-sandbox'
]
});
const page = await browser.newPage();
// Authenticate with the proxy
await page.authenticate({
username: 'USERNAME',
password: 'PASSWORD'
});
await page.goto('https://example.com', {
waitUntil: 'networkidle2',
timeout: 30000
});
const content = await page.content();
console.log(content.substring(0, 200));
await browser.close();
SOCKS5 con Puppeteer
// Puppeteer: SOCKS5 proxy configuration
const browser = await puppeteer.launch({
headless: 'new',
args: [
'--proxy-server=socks5://gate.proxyhat.com:1080'
]
});
const page = await browser.newPage();
await page.authenticate({
username: 'USERNAME',
password: 'PASSWORD'
});
Puppeteer Stealth Plugin
La configurazione di default Puppeteer espone decine di marcatori di automazione che i sistemi anti-bot rilevano. The puppeteer-extra-plugin-stealth plugin patch questi marcatori automaticamente.
// Install: npm install puppeteer-extra puppeteer-extra-plugin-stealth
const puppeteer = require('puppeteer-extra');
const StealthPlugin = require('puppeteer-extra-plugin-stealth');
// Apply stealth plugin
puppeteer.use(StealthPlugin());
const browser = await puppeteer.launch({
headless: 'new',
args: [
'--proxy-server=http://gate.proxyhat.com:8080',
'--disable-blink-features=AutomationControlled',
'--window-size=1920,1080',
'--disable-dev-shm-usage'
]
});
const page = await browser.newPage();
await page.authenticate({
username: 'USERNAME',
password: 'PASSWORD'
});
// Set realistic viewport
await page.setViewport({ width: 1920, height: 1080 });
// Set extra headers for consistency
await page.setExtraHTTPHeaders({
'Accept-Language': 'en-US,en;q=0.9'
});
await page.goto('https://example.com');
Le patch del plugin stealth:
navigator.webdriver— impostata in modo non definito anziché verochrome.runtime— aggiunge oggetti mancanti Chrome-specifici- WebGL vendor/renderer — stringhe GPU realistiche
- Plugin e autorizzazioni array — abbinare reale Chrome
- Consistenza linguistica e piattaforma
Per una comprensione più approfondita di ciò che questi patch affrontano, vedere il nostro articolo su browser impronta digitale.
Set di proxy Playwright
Playwright fornisce una configurazione proxy più elegante di Puppeteer, supportando i proxy per-context e l'emulazione di dispositivi incorporati.
Configurazione di base
// Playwright: Basic proxy setup
const { chromium } = require('playwright');
const browser = await chromium.launch({
proxy: {
server: 'http://gate.proxyhat.com:8080',
username: 'USERNAME',
password: 'PASSWORD'
}
});
const context = await browser.newContext();
const page = await context.newPage();
await page.goto('https://example.com');
const title = await page.title();
console.log(`Page title: ${title}`);
await browser.close();
Per-Context Proxy (IP diversi per scheda)
// Playwright: Different proxy per context
const { chromium } = require('playwright');
const browser = await chromium.launch();
// Context 1: US proxy session
const ctx1 = await browser.newContext({
proxy: {
server: 'http://gate.proxyhat.com:8080',
username: 'USERNAME-country-us-session-abc1',
password: 'PASSWORD'
},
locale: 'en-US',
timezoneId: 'America/New_York'
});
// Context 2: UK proxy session
const ctx2 = await browser.newContext({
proxy: {
server: 'http://gate.proxyhat.com:8080',
username: 'USERNAME-country-gb-session-abc2',
password: 'PASSWORD'
},
locale: 'en-GB',
timezoneId: 'Europe/London'
});
const page1 = await ctx1.newPage();
const page2 = await ctx2.newPage();
// Each page uses a different IP and locale
await page1.goto('https://example.com');
await page2.goto('https://example.com');
Emulazione del dispositivo con Proxy
// Playwright: Realistic device emulation + proxy
const { chromium, devices } = require('playwright');
const browser = await chromium.launch({
proxy: {
server: 'http://gate.proxyhat.com:8080',
username: 'USERNAME',
password: 'PASSWORD'
}
});
// Emulate a specific device with matching settings
const context = await browser.newContext({
...devices['Desktop Chrome'],
locale: 'en-US',
timezoneId: 'America/Chicago',
geolocation: { latitude: 41.8781, longitude: -87.6298 },
permissions: ['geolocation'],
colorScheme: 'light'
});
const page = await context.newPage();
await page.goto('https://example.com');
Rotazione proxy con browser senza testa
Strategia 1: Nuovo contesto per richiesta
Creare un nuovo contesto browser per ogni URL. Questo dà un IP fresco e biscotti puliti per richiesta.
// Playwright: Rotate proxy per request via new contexts
async function scrapeWithRotation(urls) {
const browser = await chromium.launch();
const results = [];
for (const url of urls) {
const sessionId = `sess-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
const context = await browser.newContext({
proxy: {
server: 'http://gate.proxyhat.com:8080',
username: `USERNAME-session-${sessionId}`,
password: 'PASSWORD'
}
});
const page = await context.newPage();
try {
await page.goto(url, { waitUntil: 'domcontentloaded', timeout: 30000 });
const data = await page.evaluate(() => document.title);
results.push({ url, data });
} catch (error) {
console.error(`Failed: ${url} — ${error.message}`);
} finally {
await context.close();
}
// Natural delay between requests
await new Promise(r => setTimeout(r, 1000 + Math.random() * 2000));
}
await browser.close();
return results;
}
Strategia 2: Sessioni appiccicose per flussi multi-pagine
Utilizzare sessioni appiccicose quando è necessario mantenere lo stesso IP su più pagine (paginazione, flussi di login).
// Playwright: Sticky session for multi-page scraping
async function scrapeWithStickySession(baseUrl, pageCount) {
const sessionId = `sticky-${Date.now()}`;
const browser = await chromium.launch({
proxy: {
server: 'http://gate.proxyhat.com:8080',
username: `USERNAME-session-${sessionId}`,
password: 'PASSWORD'
}
});
const context = await browser.newContext();
const page = await context.newPage();
const results = [];
for (let i = 1; i <= pageCount; i++) {
await page.goto(`${baseUrl}?page=${i}`, { waitUntil: 'networkidle' });
const items = await page.$$eval('.item', els =>
els.map(el => el.textContent.trim())
);
results.push(...items);
// Natural delay between pages
await new Promise(r => setTimeout(r, 1500 + Math.random() * 1500));
}
await browser.close();
return results;
}
Strategia 3: Scraping con corrente con piscina
// Playwright: Concurrent scraping with proxy pool
async function concurrentScrape(urls, concurrency = 5) {
const browser = await chromium.launch();
const results = [];
// Process URLs in batches
for (let i = 0; i < urls.length; i += concurrency) {
const batch = urls.slice(i, i + concurrency);
const promises = batch.map(async (url) => {
const sessionId = `conc-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
const context = await browser.newContext({
proxy: {
server: 'http://gate.proxyhat.com:8080',
username: `USERNAME-session-${sessionId}`,
password: 'PASSWORD'
}
});
const page = await context.newPage();
try {
await page.goto(url, { timeout: 30000, waitUntil: 'domcontentloaded' });
return { url, title: await page.title(), status: 'ok' };
} catch (e) {
return { url, error: e.message, status: 'error' };
} finally {
await context.close();
}
});
const batchResults = await Promise.all(promises);
results.push(...batchResults);
// Delay between batches
await new Promise(r => setTimeout(r, 2000));
}
await browser.close();
return results;
}
Puppeteer con Python (Pyppeteer Alternative)
Per sviluppatori Python, playwright per Python fornisce le stesse funzionalità con la sintassi più pulita.
# Python: Playwright with proxy and stealth settings
# pip install playwright
# playwright install chromium
from playwright.async_api import async_playwright
import asyncio
async def scrape_with_proxy():
async with async_playwright() as p:
browser = await p.chromium.launch(
proxy={
"server": "http://gate.proxyhat.com:8080",
"username": "USERNAME",
"password": "PASSWORD"
}
)
context = await browser.new_context(
viewport={"width": 1920, "height": 1080},
locale="en-US",
timezone_id="America/New_York",
user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
)
page = await context.new_page()
await page.goto("https://example.com")
title = await page.title()
print(f"Title: {title}")
await browser.close()
asyncio.run(scrape_with_proxy())
Ottimizzazione delle risorse
I browser senza testa consumano memoria e CPU significative. Ottimizzazione dei carichi di lavoro di produzione:
Blocca risorse non necessarie
// Playwright: Block images, fonts, and CSS to save bandwidth
const context = await browser.newContext({
proxy: {
server: 'http://gate.proxyhat.com:8080',
username: 'USERNAME',
password: 'PASSWORD'
}
});
const page = await context.newPage();
// Block non-essential resources
await page.route('**/*.{png,jpg,jpeg,gif,svg,webp,woff,woff2,ttf,css}', route =>
route.abort()
);
// Block tracking and analytics
await page.route('**/{google-analytics,gtag,facebook}**', route =>
route.abort()
);
await page.goto('https://example.com');
Gestione della memoria
- Chiudere i contesti dopo l'uso: Ogni contesto aperto consuma 50-150MB. Sempre contesti stretti quando fatto.
- Limitare i contesti concorrenti: Tenere 3-10 contesti per istanza del browser in base alla RAM disponibile.
- Riavviare il browser periodicamente: Dopo 100-200 cicli di contesto, riavviare il browser per evitare perdite di memoria.
- Utilizzare senza testa: 'new' (Puppeteer): La nuova modalità senza testa usa meno memoria di quella vecchia.
Gestione dei problemi comuni
Errori di autenticazione proxy
// Handle proxy auth errors gracefully
try {
const response = await page.goto(url, { timeout: 30000 });
if (response.status() === 407) {
console.error('Proxy authentication failed — check credentials');
}
} catch (error) {
if (error.message.includes('net::ERR_PROXY_CONNECTION_FAILED')) {
console.error('Proxy connection failed — check proxy server availability');
}
}
Gestione del timeout
// Retry with exponential backoff
async function gotoWithRetry(page, url, maxRetries = 3) {
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
return await page.goto(url, {
waitUntil: 'domcontentloaded',
timeout: 30000
});
} catch (error) {
if (attempt === maxRetries) throw error;
const delay = 1000 * Math.pow(2, attempt) + Math.random() * 1000;
console.log(`Retry ${attempt}/${maxRetries} after ${delay}ms`);
await new Promise(r => setTimeout(r, delay));
}
}
}
Migliori Pratiche Checklist
| Pratica | Puppete | Giocare a destra |
|---|---|---|
| proxy per Contesto | Via lancio args solo | Supporto proxy per contesto |
| Toppe di Stealth | pupazzo-extra-plugin-stealth | Emulazione del dispositivo incorporato |
| Blocco delle risorse | page.setRequestInterception | page.route |
| Multi-browser | Solo cromo | Cromo, Firefox, WebKit |
| isolamento sessione | Nuovo browser per sessione | Nuovo contesto per sessione |
Per la maggior parte delle attività di raschiamento, Playwright è la scelta consigliata su Puppeteer a causa del suo supporto proxy superiore (per-context), l'emulazione del dispositivo incorporato e il supporto multi-browser. Combinalo con I proxy residenziali di ProxyHat per i migliori risultati.
Per la configurazione proxy specifica di lingua senza browser senza testa, vedere le nostre guide per Python♪ Node.jse Vai.. Per strategie anti-detection complete, leggi il nostro Guida alla riduzione del rilevamento. Seguire sempre pratiche etiche di raschiamento e rispetto politiche di accesso al sito.






