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.
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.