Use a Shifter com Apify
Integre os proxies residenciais e de ISP do Shifter a qualquer Apify Actor, o Crawlee cuida das filas e novas tentativas, e o Shifter cuida dos IPs residenciais. O ProxyConfiguration aceita URLs do Shifter nativamente.
Início 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(); Recursos
Exemplos
Crawlee + Rotação por Sessão
O Crawlee lida com banimentos e expiração de sessão automaticamente. Use newUrlFunction para gerar uma nova URL do Shifter por sessão — quando o Crawlee encerra uma sessão devido a um banimento, a próxima recebe um IP residencial limpo.
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 (Alvos com Muito JS)
Quando o alvo precisa de um navegador real, troque o CheerioCrawler pelo PuppeteerCrawler. A mesma ProxyConfiguration se conecta — o Crawlee passa a URL do Shifter para os launch args do 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 com Input Schema
Exponha o país como uma entrada de Apify Actor. O Actor lê isso na inicialização e configura a Shifter para o pool residencial correspondente. O mesmo código do Actor funciona para qualquer região.
// .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 Fora do Crawlee (Lógica Personalizada)
Se o Crawlee não se encaixar no seu formato, você ainda pode extrair uma URL de proxy do Shifter a partir do ProxyConfiguration e usá-la com qualquer cliente HTTP. Sessões, tentativas e persistência continuam 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(); Perguntas frequentes
Perguntas comuns sobre usar o Shifter com Apify.
Use a classe ProxyConfiguration do Crawlee com um array `proxyUrls` (um ou mais URLs da Shifter) ou uma `newUrlFunction` que retorna uma nova URL da Shifter por sessão. Passe a configuração para o seu crawler, cada requisição é roteada automaticamente pela Shifter.
Apify Proxy e Shifter são produtos independentes. Para usar o Shifter, ignore a opção `useApifyProxy` e forneça sua própria ProxyConfiguration com URLs do Shifter. Você ainda pode combiná-los: alguns Actors usam o Apify Proxy para aquecimento e o Shifter para scrapes de produção.
Ative `useSessionPool: true` no seu crawler. O Crawlee marcará cada requisição com uma sessão e reutilizará a mesma URL de proxy (e, portanto, o mesmo sid do Shifter) entre as requisições dessa sessão. Quando uma sessão sofre um banimento, o Crawlee a descarta e inicia uma nova com um novo IP.
Sim. Defina um campo `country` no input_schema.json do seu Actor e leia-o na inicialização com `Actor.getInput()`. Incorpore-o ao nome de usuário do Shifter (por exemplo, `country-${input.country}`) dentro do seu newUrlFunction. O mesmo código do Actor funciona para todas as regiões.
Sim. O ProxyConfiguration se conecta aos quatro crawlers do Crawlee — Cheerio, JsdomCrawler, Puppeteer e Playwright. O Crawlee lida com a negociação do proxy de forma transparente, incluindo a autenticação no Chromium headless.
Sim. O Apify Console executa o código-fonte do seu Actor na nuvem deles. Armazene as credenciais do Shifter como segredos do Actor (Settings > Environment variables), referencie-as no seu código via `process.env.SHIFTER_USER` etc., e o Actor roteia através do Shifter em cada execução agendada.
Comece a Usar o Shifter com Apify
Execute Apify Actors através dos proxies residenciais e de ISP do Shifter com mais de 205 milhões de endereços. ProxyConfiguration nativo do Crawlee, IPs fixos por sessão e suporte completo a crawlers Cheerio / Puppeteer / Playwright.