Usa Shifter con Apify
Integra los proxies residenciales y de ISP de Shifter en cualquier Actor de Apify: Crawlee gestiona las colas y los reintentos, Shifter gestiona las IPs residenciales. ProxyConfiguration acepta URLs de Shifter de forma nativa.
Inicio rápido
Instalar
npm install apify crawlee Uso básico
// main.js (an Apify Actor)
import { Actor } from "apify";
import { CheerioCrawler, ProxyConfiguration } from "crawlee";
await Actor.init();
const proxyConfiguration = new ProxyConfiguration({
proxyUrls: [
"customer-USERNAME-country-us-sid-123ABC:PASSWORD@p.shifter.io:443",
],
});
const crawler = new CheerioCrawler({
proxyConfiguration,
async requestHandler({ request, $, log }) {
log.info(`${request.url} -> ${$("h1").text().trim()}`);
},
});
await crawler.run(["https://example.com"]);
await Actor.exit(); Características
Ejemplos
Crawlee + Rotación por sesión
Crawlee gestiona los bloqueos y la expiración de sesiones automáticamente. Usa newUrlFunction para generar una nueva URL de Shifter por sesión: cuando Crawlee descarta una sesión por bloqueo, la siguiente obtiene una IP residencial nueva.
import { Actor } from "apify";
import { CheerioCrawler, ProxyConfiguration } from "crawlee";
await Actor.init();
const proxyConfiguration = new ProxyConfiguration({
// Each session asks for a fresh URL — and Crawlee bumps the session
// on bans, so stale IPs get cycled out automatically.
newUrlFunction: () => {
const sid = Math.random().toString(36).slice(2, 10);
return `customer-USERNAME-country-uk-sid-${sid}-ttl-300:PASSWORD@p.shifter.io:443`;
},
});
const crawler = new CheerioCrawler({
proxyConfiguration,
useSessionPool: true,
persistCookiesPerSession: true,
maxConcurrency: 8,
async requestHandler({ request, $, enqueueLinks, log, session }) {
log.info(`Session ${session.id} -> ${request.url}`);
$(".product-card").each((_, el) => {
// Push to dataset (auto-persisted by Apify)
Actor.pushData({
url: request.url,
title: $(el).find("h2").text().trim(),
price: $(el).find(".price").text().trim(),
});
});
await enqueueLinks({ selector: "a.next-page", strategy: "same-domain" });
},
failedRequestHandler({ request, log }) {
log.error(`Failed after retries: ${request.url}`);
},
});
await crawler.run(["https://example.co.uk/products"]);
await Actor.exit(); PuppeteerCrawler (objetivos con JavaScript intensivo)
Cuando el objetivo requiere un navegador real, sustituye CheerioCrawler por PuppeteerCrawler. La misma ProxyConfiguration se conecta directamente: Crawlee pasa la URL de Shifter a los argumentos de lanzamiento de Puppeteer.
import { Actor } from "apify";
import { PuppeteerCrawler, ProxyConfiguration } from "crawlee";
await Actor.init();
const proxyConfiguration = new ProxyConfiguration({
newUrlFunction: () => {
const sid = Math.random().toString(36).slice(2, 10);
return `customer-USERNAME-country-de-city-berlin-sid-${sid}:PASSWORD@p.shifter.io:443`;
},
});
const crawler = new PuppeteerCrawler({
proxyConfiguration,
useSessionPool: true,
launchContext: {
launchOptions: { headless: "new" },
},
maxConcurrency: 4,
async requestHandler({ request, page, log }) {
log.info(`Visiting ${request.url}`);
await page.waitForSelector(".product");
const products = await page.$$eval(".product", (els) =>
els.map((el) => ({
title: el.querySelector("h2")?.textContent?.trim(),
price: el.querySelector(".price")?.textContent?.trim(),
})),
);
await Actor.pushData(products);
},
});
await crawler.run(["https://example.de/categories/electronics"]);
await Actor.exit(); Actor por país con esquema de entrada
Expón el país como entrada del Actor de Apify. El Actor lo lee al inicio y configura Shifter para el grupo residencial correspondiente. El mismo código del Actor funciona para todas las regiones.
// .actor/input_schema.json
{
"title": "Localized Scraper Input",
"type": "object",
"schemaVersion": 1,
"properties": {
"startUrl": { "type": "string", "title": "Start URL", "default": "https://example.com" },
"country": { "type": "string", "title": "Country", "enum": ["us","uk","de","jp","fr","br"], "default": "us" },
"maxPages": { "type": "integer", "title": "Max Pages", "default": 100, "minimum": 1, "maximum": 5000 }
},
"required": ["startUrl", "country"]
}
// main.js
import { Actor } from "apify";
import { CheerioCrawler, ProxyConfiguration } from "crawlee";
await Actor.init();
const { startUrl, country, maxPages } = await Actor.getInput();
const proxyConfiguration = new ProxyConfiguration({
newUrlFunction: () => {
const sid = Math.random().toString(36).slice(2, 10);
return `customer-USERNAME-country-${country}-sid-${sid}-ttl-300:PASSWORD@p.shifter.io:443`;
},
});
const crawler = new CheerioCrawler({
proxyConfiguration,
maxRequestsPerCrawl: maxPages,
useSessionPool: true,
async requestHandler({ request, $, enqueueLinks }) {
await Actor.pushData({
country,
url: request.url,
title: $("title").text().trim(),
h1: $("h1").first().text().trim(),
});
await enqueueLinks({ strategy: "same-domain" });
},
});
await crawler.run([startUrl]);
await Actor.exit(); Apify SDK fuera de Crawlee (lógica personalizada)
Si Crawlee no se adapta a tu caso, puedes obtener una URL de proxy de Shifter desde ProxyConfiguration y usarla con cualquier cliente HTTP. Las sesiones, los reintentos y la persistencia siguen funcionando.
import { Actor } from "apify";
import { ProxyConfiguration } from "crawlee";
import { gotScraping } from "got-scraping";
await Actor.init();
const proxyConfiguration = new ProxyConfiguration({
newUrlFunction: () => {
const sid = Math.random().toString(36).slice(2, 10);
return `customer-USERNAME-country-fr-sid-${sid}:PASSWORD@p.shifter.io:443`;
},
});
// Pull a fresh proxy URL per logical task
async function fetchTarget(url) {
const proxyUrl = await proxyConfiguration.newUrl();
const html = await gotScraping({
url,
proxyUrl,
headerGeneratorOptions: {
browsers: [{ name: "chrome", minVersion: 120 }],
locales: ["en-US"],
},
}).text();
return html;
}
const urls = [
"https://example.fr/api/v1/products?page=1",
"https://example.fr/api/v1/products?page=2",
// ...
];
for (const url of urls) {
try {
const html = await fetchTarget(url);
await Actor.pushData({ url, length: html.length });
} catch (err) {
console.error(`Failed ${url}: ${err.message}`);
}
}
await Actor.exit(); Preguntas frecuentes
Preguntas frecuentes sobre el uso de Shifter con Apify.
Usa la clase ProxyConfiguration de Crawlee con un array `proxyUrls` (una o más URLs de Shifter) o una `newUrlFunction` que devuelva una URL de Shifter nueva por sesión. Pasa la configuración a tu crawler: todas las solicitudes se enrutarán automáticamente a través de Shifter.
Apify Proxy y Shifter son productos independientes. Para usar Shifter, omite la opción `useApifyProxy` y proporciona tu propia ProxyConfiguration con URLs de Shifter. Puedes combinarlos: algunos Actors usan Apify Proxy para el calentamiento y Shifter para los scrapes en producción.
Activa `useSessionPool: true` en tu crawler. Crawlee etiquetará cada solicitud con una sesión y reutilizará la misma URL de proxy (y por tanto el mismo sid de Shifter) en las solicitudes de esa sesión. Cuando una sesión provoca un bloqueo, Crawlee la descarta e inicia una nueva con una IP diferente.
Sí. Define un campo `country` en el archivo input_schema.json de tu Actor y léelo al inicio con `Actor.getInput()`. Incorpóralo al nombre de usuario de Shifter (p. ej. `country-${input.country}`) dentro de tu newUrlFunction. El mismo código del Actor funciona para todas las regiones.
Sí. ProxyConfiguration se integra con los cuatro crawlers de Crawlee: Cheerio, JsdomCrawler, Puppeteer y Playwright. Crawlee gestiona la negociación del proxy de forma transparente, incluida la autenticación en Chromium sin interfaz gráfica.
Sí. La consola de Apify ejecuta el código fuente de tu Actor en su nube. Guarda las credenciales de Shifter como secretos del Actor (Configuración > Variables de entorno), referencialas en tu código mediante `process.env.SHIFTER_USER`, etc., y el Actor enrutará a través de Shifter en cada ejecución programada.
Empieza a usar Shifter con Apify
Ejecuta Apify Actors a través de los proxies residenciales e ISP de más de 205M de Shifter. ProxyConfiguration nativa de Crawlee, IPs persistentes por sesión y soporte completo para crawlers con Cheerio, Puppeteer y Playwright.