統合

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 でのネイティブ ProxyConfiguration サポート -- Shifter の URL または newUrlFunction を渡す
CheerioCrawler、PuppeteerCrawler、PlaywrightCrawler、BasicCrawler と互換性あり
CrawleeのセッションプールによるセッションごとのスティッキーIP — 古いセッションは自動的に廃棄されます
195+ か国での Geo ターゲティング -- Actor 入力スキーマを通じて国をパラメータ化
Apify Consoleのスケジュール実行、Apify Cloudの自動スケーリング、セルフホストのCrawleeへのドロップイン対応
pushData、キーバリューストア、リクエストキュー、データセット永続化を含むApify SDK全体と互換性あり

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();
FAQ

よくある質問

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クローラーの完全サポートを提供します。

Shifterを無料で試す数分でセットアップ完了。いつでもキャンセル可能。