scraperapi-php-sdk について
ScraperAPI 経由でデータを取得する PHP 開発者向けの SDK 利用ガイドです。同期リクエスト、パラメーター設定、構造化出力、大量 URL の処理方法を扱います。
主な機能
- 01GET と POST のリクエスト
- 02JavaScript レンダリングとプロキシ設定
- 03スティッキーセッションとカスタムヘッダー
- 04HTML、Markdown、構造化 JSON の出力
- 05バッチ向け非同期エンドポイントの案内
活用シーン
- 01ScraperAPI 経由で対象ページを取得
- 02対象サイトへフォームや JSON を送信
- 03対応サイトから構造化データを取得
- 04多数の URL を対象にスクレイピングを実行
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ scraperapi/ scraperapi-skills --skill scraperapi-php-sdkインストール後、Claude Code で/scraperapi-php-sdkを入力して読み込まれたか確認します。
詳細
ScraperAPI — PHP SDK のベストプラクティス
必要条件: PHP 7.0 以降、Composer、composer require scraperapi/sdk、SCRAPERAPI_API_KEY 環境変数。
セットアップ
<?php
require __DIR__ . '/vendor/autoload.php';
use ScraperAPI\Client;
$client = new Client(getenv('SCRAPERAPI_API_KEY'));
API キーをハードコードしないでください。使用するたびに環境変数から読み込んでください。
基本的な使い方
// Simple GET — returns HTML string via ->raw_body
$html = $client->get("https://example.com/")->raw_body;
echo $html;
// With a single parameter
$html = $client->get("https://example.com/", ["render" => true])->raw_body;
// With multiple parameters
$html = $client->get(
"https://example.com/",
[
"render" => true,
"country_code" => "us",
]
)->raw_body;
パラメーターは連想配列として渡します。->raw_body を使うと、レスポンスオブジェクトから HTML 文字列を抽出できます。
選択ガイド
| 状況 | 方法 |
|---|---|
| 単一の URL、同期処理 | $client->get($url, $params)->raw_body |
| ページが JavaScript でコンテンツを読み込む | "render" => true を追加 |
| データセンタープロキシをサイトにブロックされる | "premium" => true を追加 |
| 最も強力なボット対策がある | "ultra_premium" => true を追加 |
| 同じドメインで複数ステップ/ページネーションがある処理 | "session_number" を使用 |
| 対象にフォームまたは JSON ボディを POST する | $client->post($url, $options)->raw_body |
| 20 件以上の URL またはバッチ処理 | cURL または Guzzle 経由で非同期エンドポイントを使用 |
| 対応プラットフォーム(Amazon、Google など) | 構造化データエンドポイントを直接使用 |
パラメーターリファレンス
レンダリング
// Render JavaScript before returning HTML
// Use when: page is a React/Vue/Angular SPA, or scrape returns empty/partial content
// Cost: +10 credits
$html = $client->get("https://spa-site.com/", ["render" => true])->raw_body;
// Wait for a specific DOM element (requires render: true)
$html = $client->get("https://spa-site.com/", [
"render" => true,
"wait_for_selector" => ".product-list",
])->raw_body;
// Screenshot (auto-enables rendering)
$html = $client->get("https://example.com/", ["screenshot" => true])->raw_body;
まずは render を指定せずに実行してください。期待するコンテンツがレスポンスに含まれていない場合にのみ追加します。コストとレイテンシーが増加します。
プロキシとジオターゲティング
// Route through a country-specific proxy — no extra credit cost
$html = $client->get("https://example.com/", ["country_code" => "de"])->raw_body;
// Premium residential/mobile IPs — for sites that block datacenter proxies
// Cost: 10 credits (25 with render)
$html = $client->get("https://hard-site.com/", ["premium" => true])->raw_body;
// Ultra-premium — for the toughest anti-bot protections
// Cost: 30 credits (75 with render)
// Note: incompatible with custom headers — keep_headers is ignored
$html = $client->get("https://hardest-site.com/", ["ultra_premium" => true])->raw_body;
premium と ultra_premium は相互排他です。両方を設定しないでください。
段階的な引き上げ順:標準(1 cr)→ render(10 cr)→ premium(10 cr)→ ultra_premium(30 cr)。
セッション(スティッキープロキシ)
// Reuse the same proxy IP across requests — useful for pagination and multi-step flows
// Sessions expire 15 minutes after last use; any integer is a valid session ID
$html1 = $client->get("https://example.com/page1", ["session_number" => 42])->raw_body;
$html2 = $client->get("https://example.com/page2", ["session_number" => 42])->raw_body;
ヘッダーとデバイスタイプ
// Forward custom headers to the target site
// Note: keep_headers is ignored when ultra_premium is true
$html = $client->get("https://example.com/", [
"keep_headers" => true,
])->raw_body;
// Pass headers in the request options array alongside ScraperAPI params
// Emulate a mobile or desktop browser user-agent
$html = $client->get("https://example.com/", ["device_type" => "mobile"])->raw_body;
自動解析とレスポンス形式
// Return structured JSON instead of HTML for supported sites (Amazon, Google, etc.)
$json = $client->get("https://amazon.com/dp/B09V3KXJPB", ["autoparse" => true])->raw_body;
$data = json_decode($json, true);
// Markdown output — useful for text pipelines
$md = $client->get("https://docs.example.com/", ["output_format" => "markdown"])->raw_body;
POST リクエスト
// POST a JSON body to the target site through ScraperAPI's proxy
$options = [
"body" => json_encode(["key" => "value"]),
"headers" => ["Content-Type" => "application/json"],
];
$result = $client->post("https://example.com/api", $options)->raw_body;
段階的な引き上げ
常に最も低コストの方法から開始し、ブロックされた場合にのみ段階的に引き上げてください。
function scrapeWithEscalation(Client $client, string $url): ?string
{
$tiers = [
[],
["render" => true],
["premium" => true],
["premium" => true, "render" => true],
["ultra_premium" => true],
];
foreach ($tiers as $params) {
$html = $client->get($url, $params)->raw_body;
if ($html && stripos($html, '<html') !== false) {
return $html;
}
}
return null;
}
非同期ジョブ(バッチ処理向け)
SDK は同期処理です。各 ->get() 呼び出しは、レスポンスが返るまで(最長 70 秒)ブロックします。URL が 20 件以上ある場合は、非同期 REST エンドポイントを使用してください。
$apiKey = getenv('SCRAPERAPI_API_KEY');
function submitJob(string $url, array $apiParams = []): array
{
global $apiKey;
$ch = curl_init('https://async.scraperapi.com/jobs');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode(['apiKey' => $apiKey, 'url' => $url, 'apiParams' => $apiParams]),
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_RETURNTRANSFER => true,
]);
$response = curl_exec($ch);
curl_close($ch);
return json_decode($response, true); // ["id" => "...", "statusUrl" => "..."]
}
function pollJob(array $job, int $maxWait = 120, int $interval = 5): string
{
$deadline = time() + $maxWait;
while (time() < $deadline) {
$data = json_decode(file_get_contents($job['statusUrl']), true);
if ($data['status'] === 'finished') return $data['response']['body'];
if ($data['status'] === 'failed') throw new \RuntimeException("Job {$job['id']} failed");
sleep($interval);
}
throw new \RuntimeException("Job {$job['id']} timed out");
}
// Submit and collect
$urls = ['https://example.com/p1', 'https://example.com/p2'];
$jobs = array_map('submitJob', $urls);
$results = array_map('pollJob', $jobs);
構造化データエンドポイント
対応プラットフォームでは、生の HTML の代わりに構造化データエンドポイントを使用してください。解析ロジックを使わずに、クリーンな JSON が返されます。
function structuredGet(string $vertical, array $params = []): array
{
global $apiKey;
$query = http_build_query(array_merge(['api_key' => $apiKey], $params));
$url = "https://api.scraperapi.com/structured/{$vertical}?{$query}";
$body = file_get_contents($url);
if ($body === false) throw new \RuntimeException("Request failed for {$vertical}");
return json_decode($body, true);
}
// Google SERP
$results = structuredGet('google/search', ['query' => 'PHP web scraping']);
// Amazon product details
$product = structuredGet('amazon/product', ['asin' => 'B09V3KXJPB']);
// Walmart search
$items = structuredGet('walmart/search', ['query' => 'standing desk', 'tld' => 'com']);
すべての分野と必須フィールドについては、構造化データのドキュメントを参照してください。
エラー処理
function safeScrape(Client $client, string $url, array $params = []): ?string
{
try {
return $client->get($url, $params)->raw_body;
} catch (\Exception $e) {
$status = method_exists($e, 'getCode') ? (int) $e->getCode() : 0;
switch ($status) {
case 401: throw new \RuntimeException('Invalid API key — check SCRAPERAPI_API_KEY');
case 403: throw new \RuntimeException('Blocked or out of credits — try premium or ultra_premium');
case 429: throw new \RuntimeException('Rate limit — reduce concurrency or switch to async');
case 500:
case 503: throw new \RuntimeException('Transient error — retry with exponential backoff');
default: throw $e;
}
}
}
ステータスコードのリファレンス:200 成功、401 無効なキー、403 ブロック/クレジット不足、404 対象が見つからない、 429 レート制限、500/503 一時的なエラー(課金されないため、安全に再試行できます)。
再試行のドキュメントも参照してください。
クレジットコストのリファレンス
| リクエストの種類 | クレジット |
|---|---|
| 標準 | 1 |
"render" => true | 10 |
"premium" => true | 10 |
"premium" => true, "render" => true | 25 |
"ultra_premium" => true | 30 |
"ultra_premium" => true, "render" => true | 75 |
任意のリクエストに "max_cost" => N を追加すると、クレジット消費を上限設定できます。リクエストのコストが N クレジットを超える場合は 403 が返されます。