Usa Shifter con Puppeteer
Ejecuta una instancia real de Chromium a través de los proxies residenciales de Shifter en minutos. Soporte nativo de --proxy-server, page.authenticate(), geolocalización por pestaña y escalado completo con cluster, sin plugins adicionales.
Inicio rápido
Instalar
npm install puppeteer Uso básico
import puppeteer from "puppeteer";
const browser = await puppeteer.launch({
args: ["--proxy-server=http://p.shifter.io:443"],
headless: "new",
});
const page = await browser.newPage();
await page.authenticate({
username: "customer-USERNAME-country-us-sid-123ABC",
password: "PASSWORD",
});
await page.goto("https://ipinfo.io/json");
console.log(await page.evaluate(() => document.body.textContent));
// {"ip": "154.16.xxx.xxx", "city": "New York", "country": "US", ...}
await browser.close(); Características
Ejemplos
Proxy autenticado con sesión persistente
Fija una IP residencial para toda la sesión del navegador añadiendo `sid-XXX` al nombre de usuario. Añade `country-uk-city-london` para geolocalización y `ttl-300` para mantener esa IP durante 300 segundos.
import puppeteer from "puppeteer";
import { randomBytes } from "node:crypto";
const sid = randomBytes(4).toString("hex");
const browser = await puppeteer.launch({
args: [
"--proxy-server=http://p.shifter.io:443",
"--no-sandbox",
"--disable-blink-features=AutomationControlled",
],
headless: "new",
});
const page = await browser.newPage();
await page.authenticate({
username: `customer-USERNAME-country-uk-city-london-sid-${sid}-ttl-300`,
password: "PASSWORD",
});
await page.setUserAgent(
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36",
);
// Multi-step flow — every page load reuses the same residential IP.
await page.goto("https://example.co.uk/login", { waitUntil: "networkidle0" });
await page.type("#email", "user@example.com");
await page.type("#password", "secret");
await page.click('button[type="submit"]');
await page.waitForNavigation({ waitUntil: "networkidle0" });
await page.goto("https://example.co.uk/dashboard");
const html = await page.content();
console.log(html.length, "bytes from dashboard");
await browser.close(); Geolocalización por pestaña
Cada nueva pestaña obtiene sus propias credenciales de proxy — permite que una pestaña haga scraping en un sitio de EE. UU. mientras otra lo hace en uno japonés, todo desde un mismo navegador.
import puppeteer from "puppeteer";
const browser = await puppeteer.launch({
args: ["--proxy-server=http://p.shifter.io:443"],
headless: "new",
});
async function scrape(country: string, url: string) {
const page = await browser.newPage();
await page.authenticate({
username: `customer-USERNAME-country-${country}-sid-${country}-001`,
password: "PASSWORD",
});
await page.goto(url, { waitUntil: "domcontentloaded" });
const data = await page.evaluate(() => ({
title: document.title,
text: document.body.innerText.slice(0, 200),
}));
await page.close();
return { country, ...data };
}
const results = await Promise.all([
scrape("us", "https://www.example.com"),
scrape("jp", "https://www.example.jp"),
scrape("de", "https://www.example.de"),
scrape("br", "https://www.example.com.br"),
]);
console.log(results);
await browser.close(); Puppeteer Cluster (scraping en paralelo)
Escala a decenas de páginas en paralelo sin agotar la memoria. Pasa el proxy a través de puppeteerOptions y autentícate por página en tu función de tarea.
import { Cluster } from "puppeteer-cluster";
const cluster = await Cluster.launch({
concurrency: Cluster.CONCURRENCY_PAGE,
maxConcurrency: 10,
puppeteerOptions: {
args: ["--proxy-server=http://p.shifter.io:443"],
headless: "new",
},
monitor: true,
});
await cluster.task(async ({ page, data: url }) => {
await page.authenticate({
username: `customer-USERNAME-country-us-sid-${url.replace(/\W+/g, "").slice(0, 8)}`,
password: "PASSWORD",
});
await page.goto(url, { waitUntil: "networkidle0" });
const title = await page.title();
const html = await page.content();
return { url, title, length: html.length };
});
const urls = [
"https://example.com/category/laptops",
"https://example.com/category/phones",
"https://example.com/category/tablets",
// ... hundreds more
];
const results = await Promise.all(urls.map((url) => cluster.execute(url)));
console.log(results);
await cluster.idle();
await cluster.close(); Modo sigiloso y bloqueo de recursos
Combina Shifter con el plugin stealth de puppeteer-extra y bloquea imágenes, fuentes y multimedia para hacer scraping entre 5 y 10 veces más rápido evitando las señales de automatización de Chrome.
import puppeteer from "puppeteer-extra";
import StealthPlugin from "puppeteer-extra-plugin-stealth";
puppeteer.use(StealthPlugin());
const browser = await puppeteer.launch({
args: [
"--proxy-server=http://p.shifter.io:443",
"--disable-blink-features=AutomationControlled",
],
headless: "new",
});
const page = await browser.newPage();
await page.authenticate({
username: "customer-USERNAME-country-us-city-newyork-sid-789GHI",
password: "PASSWORD",
});
// Block images, fonts, and media for faster page loads
await page.setRequestInterception(true);
page.on("request", (req) => {
const blocked = ["image", "font", "media", "stylesheet"];
blocked.includes(req.resourceType()) ? req.abort() : req.continue();
});
await page.goto("https://example.com", { waitUntil: "domcontentloaded" });
const products = await page.$$eval(".product", (els) =>
els.map((el) => ({
title: el.querySelector("h2")?.textContent?.trim(),
price: el.querySelector(".price")?.textContent?.trim(),
})),
);
console.log(products);
await browser.close(); Preguntas frecuentes
Preguntas frecuentes sobre el uso de Shifter con Puppeteer.
Pass --proxy-server=http://p.shifter.io:443 to the browser launch args, then call page.authenticate({ username, password }) on each page before navigating. The same proxy applies to every tab and the credentials handle the basic-auth challenge transparently.
Sí, en versiones modernas de Puppeteer (con headless: 'new'). El modo heredado `headless: true` también lo admite. Si usas versiones de Chromium anteriores a la 105, puede que necesites recurrir a una extensión de Chrome que inyecte las credenciales, pero en cualquier versión reciente de Puppeteer, page.authenticate funciona sin problemas.
Añade un ID de sesión al nombre de usuario del proxy, por ejemplo `customer-USERNAME-country-us-sid-123ABC`. Cada página que se autentique con ese nombre de usuario compartirá la misma IP residencial. Añade `ttl-N` para fijar la IP durante un máximo de N segundos.
Sí. Cada llamada a newPage() puede autenticarse con un nombre de usuario de Shifter diferente: `country-us` para una pestaña, `country-jp` para otra. El estado del navegador (cookies, caché) se comparte, pero la IP de salida cambia por pestaña, lo que es ideal para extraer contenido localizado en paralelo.
Sí. El plugin stealth parchea las huellas de automatización de Chrome; Shifter gestiona la IP residencial. Ambos se combinan sin problemas: instala puppeteer-extra y el plugin stealth, y luego configura el proxy en el lanzamiento como de costumbre.
Pasa el argumento --proxy-server en puppeteerOptions al llamar a Cluster.launch, y luego llama a page.authenticate dentro del callback de cluster.task. Combina esto con un sid único por tarea para hacer scraping en paralelo sin compartir IPs entre workers.
Empieza a usar Shifter con Puppeteer
Controla Chromium en modo headless a través de los más de 205M de proxies residenciales y de ISP de Shifter. --proxy-server nativo, geolocalización por pestaña, sesiones sticky y soporte completo para Puppeteer-cluster.