mcpField
S
scraperapi-java-sdk

scraperapi-java-sdk

github.com/scraperapi開発1098 回インストール12 週間前に更新
リポジトリ

scraperapi-java-sdk について

ScraperAPI を使う開発者向けの Java SDK 利用ガイドです。同期スクレイピングやバッチ処理におけるリクエスト設定、段階的なオプション選択、構造化レスポンス、エラー処理を説明します。

主な機能

  1. 01GET リクエスト用の Fluent Builder
  2. 02JavaScript レンダリングとプロキシ設定
  3. 03スティッキーセッションとリトライ
  4. 04対応サイト向けの構造化 JSON
  5. 05バッチ処理の非同期化

活用シーン

  1. 01単一 URL の HTML 取得
  2. 02JavaScript レンダリングページのスクレイピング
  3. 03ページ送り間でのプロキシセッション維持
  4. 04大量 URL の非同期処理

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/scraperapi/scraperapi-skills --skill scraperapi-java-sdk

インストール後、Claude Code で/scraperapi-java-sdkを入力して読み込まれたか確認します。

詳細

ScraperAPI — Java SDK のベストプラクティス

必要要件: Java 8 以降、Maven または Gradle、SCRAPERAPI_API_KEY 環境変数。

セットアップ

Maven
<dependency>
  <groupId>com.scraperapi</groupId>
  <artifactId>sdk</artifactId>
  <version>1.2</version>
</dependency>
Gradle
implementation 'com.scraperapi:sdk:1.2'
クライアントのインスタンス化
import com.scraperapi.ScraperApiClient;

ScraperApiClient client = new ScraperApiClient(System.getenv("SCRAPERAPI_API_KEY"));

API キーをハードコードしないでください。毎回、環境変数から読み込んでください。

基本的な使い方

Java SDK はフルーエントビルダーパターンを使用します。.get() の戻り値にパラメータメソッドをチェーンし、.result() を呼び出して処理をブロックし、HTML を取得します。

// Simple GET — returns HTML as a String
String html = client.get("https://example.com/").result();

// With parameters — chain before .result()
String html = client.get("https://example.com/")
    .render(true)
    .result();

// Multiple parameters
String html = client.get("https://example.com/")
    .render(true)
    .countryCode("us")
    .result();

選択ガイド

状況方法
単一 URL、同期処理.get(url).<params>.result()
ページが JavaScript でコンテンツを読み込む.render(true) をチェーンする
サイトがデータセンタープロキシをブロックする.premium(true) をチェーンする
最も強力なボット対策がある.ultraPremium(true) をチェーンする
同じドメインで複数ステップ/ページネーションを行う.sessionNumber(n) をチェーンする
一時的な失敗が予想される.retry(n) をチェーンする
20 件以上の URL またはバッチジョブHttpClient を使った非同期エンドポイント
対応プラットフォーム(Amazon、Google など)構造化データエンドポイント

パラメータリファレンス

レンダリング
// Render JavaScript before returning HTML
// Use when: page is a React/Vue/Angular SPA, or initial scrape returns empty content
// Cost: +10 credits
String html = client.get("https://spa-site.com/").render(true).result();

// Wait for a DOM element before capturing (requires render)
String html = client.get("https://spa-site.com/")
    .render(true)
    .waitForSelector(".product-list")
    .result();

最初から .render(true) を呼び出さないでください。まずは使わずに試してください。コストとレイテンシが増加します。

プロキシと地域ターゲティング
// Route through a country-specific proxy — no extra credit cost
String html = client.get("https://example.com/").countryCode("gb").result();

// Premium residential/mobile IPs — for sites that block datacenter proxies
// Cost: 10 credits (25 with render)
String html = client.get("https://hard-site.com/").premium(true).result();

// Ultra-premium — for the toughest anti-bot protections
// Cost: 30 credits (75 with render)
// Note: incompatible with custom headers
String html = client.get("https://hardest-site.com/").ultraPremium(true).result();

premium と ultraPremium は併用できません。両方をチェーンしないでください。 段階的な引き上げ順序:standard(1 cr)→ render(10 cr)→ premium(10 cr)→ ultraPremium(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 ID
String page1 = client.get("https://example.com/page1").sessionNumber(42).result();
String page2 = client.get("https://example.com/page2").sessionNumber(42).result();
デバイスタイプと自動解析
// Emulate a mobile browser user-agent
String html = client.get("https://example.com/").deviceType("mobile").result();

// Return structured JSON for supported sites (Amazon, Google, etc.)
String json = client.get("https://amazon.com/dp/B09V3KXJPB").autoparse(true).result();
リトライ
// Override the default retry count (default: 3)
// ScraperAPI retries failed requests for up to 70 seconds internally;
// .retry() controls how many times the SDK retries after a non-200 response
String html = client.get("https://flaky-site.com/").retry(5).result();

タイムアウトを極端に短く設定しないでください。SDK のデフォルト値は、ScraperAPI の内部リトライ期間(最大 70 秒)に対応するよう調整されています。クライアントのタイムアウトを 5 秒に設定すると、誤った失敗が発生します。

段階的な引き上げ

常に最も低コストの方法から始めてください。サイトが前の段階をブロックした場合にのみ引き上げてください。

public static String scrapeWithEscalation(ScraperApiClient client, String url) throws Exception {
    // Try each tier in order — stop at the first success
    String[][] tiers = {
        {},                                  // 1 credit — standard
        {"render:true"},                     // 10 credits
        {"premium:true"},                    // 10 credits
        {"premium:true", "render:true"},     // 25 credits
        {"ultraPremium:true"},               // 30 credits
    };

    // Practical implementation — explicit tier cascade
    String[] attempts = { "standard", "render", "premium", "premiumRender", "ultraPremium" };
    for (String tier : attempts) {
        try {
            var req = client.get(url);
            switch (tier) {
                case "render":       req = req.render(true); break;
                case "premium":      req = req.premium(true); break;
                case "premiumRender": req = req.premium(true).render(true); break;
                case "ultraPremium": req = req.ultraPremium(true); break;
            }
            String html = req.result();
            if (html != null && html.toLowerCase().contains("<html")) return html;
        } catch (Exception e) {
            // Log and try next tier
        }
    }
    return null;
}

非同期ジョブ(バッチ処理向け)

.result() は呼び出し元のスレッドをブロックします。20 件以上の URL を処理する場合は、REST エンドポイント経由で非同期ジョブを送信し、結果を並行して収集してください。

import java.net.http.*;
import java.net.URI;
import com.fasterxml.jackson.databind.ObjectMapper;

private static final String API_KEY = System.getenv("SCRAPERAPI_API_KEY");
private static final HttpClient HTTP = HttpClient.newHttpClient();
private static final ObjectMapper JSON = new ObjectMapper();

public static Map<String, Object> submitJob(String url) throws Exception {
    String body = JSON.writeValueAsString(Map.of("apiKey", API_KEY, "url", url));
    HttpRequest req = HttpRequest.newBuilder()
        .uri(URI.create("https://async.scraperapi.com/jobs"))
        .POST(HttpRequest.BodyPublishers.ofString(body))
        .header("Content-Type", "application/json")
        .build();
    HttpResponse<String> resp = HTTP.send(req, HttpResponse.BodyHandlers.ofString());
    return JSON.readValue(resp.body(), Map.class); // {id, statusUrl}
}

public static String pollJob(Map<String, Object> job, int maxWaitSec) throws Exception {
    long deadline = System.currentTimeMillis() + maxWaitSec * 1000L;
    while (System.currentTimeMillis() < deadline) {
        HttpRequest req = HttpRequest.newBuilder()
            .uri(URI.create((String) job.get("statusUrl")))
            .GET().build();
        Map<String, Object> data = JSON.readValue(
            HTTP.send(req, HttpResponse.BodyHandlers.ofString()).body(), Map.class);
        if ("finished".equals(data.get("status")))
            return ((Map<?, ?>) data.get("response")).get("body").toString();
        if ("failed".equals(data.get("status")))
            throw new RuntimeException("Job " + job.get("id") + " failed");
        Thread.sleep(5_000);
    }
    throw new RuntimeException("Job " + job.get("id") + " timed out");
}

構造化データエンドポイント

対応プラットフォームでは、生の HTML をスクレイピングする代わりに、構造化データエンドポイントを使用してください。

public static String structuredGet(String vertical, Map<String, String> params) throws Exception {
    StringBuilder query = new StringBuilder("api_key=" + API_KEY);
    params.forEach((k, v) -> query.append("&").append(k).append("=").append(v));
    URI uri = URI.create("https://api.scraperapi.com/structured/" + vertical + "?" + query);
    HttpRequest req = HttpRequest.newBuilder().uri(uri).GET().build();
    HttpResponse<String> resp = HTTP.send(req, HttpResponse.BodyHandlers.ofString());
    if (resp.statusCode() != 200)
        throw new RuntimeException("Error " + resp.statusCode());
    return resp.body();
}

// Google SERP
String serp = structuredGet("google/search", Map.of("query", "java web scraping"));

// Amazon product
String product = structuredGet("amazon/product", Map.of("asin", "B09V3KXJPB"));

// Walmart search
String items = structuredGet("walmart/search", Map.of("query", "standing desk", "tld", "com"));

エラー処理

public static String safeScrape(ScraperApiClient client, String url) {
    try {
        return client.get(url).retry(3).result();
    } catch (Exception e) {
        String msg = e.getMessage() != null ? e.getMessage() : "";
        if (msg.contains("401")) throw new RuntimeException("Invalid API key — check SCRAPERAPI_API_KEY", e);
        if (msg.contains("403")) throw new RuntimeException("Blocked or out of credits — try premium/ultraPremium", e);
        if (msg.contains("429")) throw new RuntimeException("Rate limit — reduce concurrency or use async", e);
        if (msg.contains("500") || msg.contains("503"))
            throw new RuntimeException("Transient error — retry with backoff", e);
        throw new RuntimeException("Scrape failed: " + url, e);
    }
}

ステータスコード:200 は成功、401 はキーが無効、403 はブロックまたはクレジット不足、404 は対象が見つからない、429 はレート制限、500/503 は一時的なエラー(課金されないため、バックオフして安全に再試行できます)。

クレジットコストのリファレンス

リクエストの種類クレジット
標準の .result()1
.render(true)10
.premium(true)10
.premium(true).render(true)25
.ultraPremium(true)30
.ultraPremium(true).render(true)75

ドキュメント

コメント