Shifterと一緒に使用する Apify
ShifterのレジデンシャルおよびISP Proxyを任意のApify Actorに組み込めます。CrawleeがキューとリトライをShifterがレジデンシャル IPを担当します。ProxyConfigurationはShifter URLをネイティブに受け付けます。
クイックスタート
インストール
npm install apify crawlee 基本的な使い方
// 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(); 機能
例
Crawlee + セッションごとのローテーション
Crawleeはバンとセッション切れを自動的に処理します。newUrlFunctionを使用してセッションごとに新しいShifter URLを生成してください――Crawleeがバンによりセッションを終了すると、次のセッションにはクリーンなレジデンシャルIPが割り当てられます。
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(JS 重量ターゲット)
ターゲットが実際のブラウザを必要とする場合は、CheerioCrawlerをPuppeteerCrawlerに切り替えます。同じProxyConfigurationをそのまま接続できます。CrawleeがShifterのURLを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(); 入力スキーマ付きの国別アクター
国をApify Actorの入力として公開します。Actorは起動時にそれを読み取り、対応するレジデンシャルプールに合わせてShifterを設定します。同じActorコードがすべてのリージョンで機能します。
// .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(); Crawlee外でのApify SDK(カスタムロジック)
Crawlee が要件に合わない場合でも、ProxyConfiguration から Shifter プロキシ URL を取得して任意の HTTP クライアントで使用できます。セッション、リトライ、パーシステンスはすべて引き続き機能します。
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(); よくある質問
Shifter と Apify の併用に関するよくある質問。
`proxyUrls`配列(1つ以上のShifter URL)または各セッションごとに新しいShifter URLを返す`newUrlFunction`を使用して、CrawleeのProxyConfigurationクラスを設定してください。設定をクローラーに渡すと、すべてのリクエストが自動的にShifterを経由してルーティングされます。
Apify ProxyとShifterは独立した製品です。Shifterを使用するには、`useApifyProxy`オプションをスキップし、Shifter URLを使用した独自のProxyConfigurationを指定してください。両方を組み合わせることも可能です。一部のActorはウォームアップにApify Proxyを、本番スクレイピングにShifterを使用しています。
クローラーで `useSessionPool: true` を有効にしてください。CrawleeはセッションIDで各リクエストにタグを付け、そのセッション内のリクエスト全体で同じプロキシURL(したがって同じShifterのsid)を再利用します。セッションがBANを引き起こすと、Crawleeはそれを廃棄し、新しいIPで新しいセッションを開始します。
はい。Actorのinput_schema.jsonに`country`フィールドを定義し、`Actor.getInput()`で起動時に読み込んでください。newUrlFunction内でShifterのユーザー名にそれを組み込みます(例:`country-${input.country}`)。これにより、同じActorのコードがすべてのリージョンで動作します。
はい。ProxyConfiguration はCrawlee の4つのクローラー(Cheerio、JsdomCrawler、Puppeteer、Playwright)すべてに組み込まれます。Crawlee はヘッドレスChromium での認証を含め、プロキシのネゴシエーションを透過的に処理します。
はい。Apify ConsoleはActorのソースをクラウドで実行します。Shifterの認証情報をActorシークレット(設定 > 環境変数)として保存し、コード内で`process.env.SHIFTER_USER`などを通じて参照すると、Actorはスケジュールされた実行のたびにShifterを経由してルーティングされます。
でShifterを使い始める Apify
Shifterの2億500万件以上のレジデンシャルプロキシおよびISPプロキシを通じてApify Actorsを実行します。Crawlee ProxyConfigurationのネイティブ対応、セッションごとのスティッキーIP、Cheerio / Puppeteer / Playwrightクローラーの完全サポートを提供します。