DataImpulse Logo and Java Logo

Javaは、充実したライブラリ、マルチスレッド機能、堅実なエラー処理を備えたプラットフォーム非依存の言語であり、Webスクレイピングにも適しています。このチュートリアルでは、必要なツールと、Javaでのスクレイピングを効率化する手順を解説します。

JavaでWebスクレイピングを行う際のポイント

Pythonのように扱いやすい言語はWebスクレイピングで人気ですが、Javaにも次のような強みがあります。

  • JSoupやHtmlUnitなどのライブラリにより、HTMLの解析を容易にできます。
  • 高い性能と処理速度、効率的なメモリ管理により、大規模なプロジェクトに適しています。
  • 強い型付けを採用しているため、コンパイル時にエラーを検出できます。

既存のインフラがJavaに依存している場合や、長期的なプロジェクトを進める場合にも、Javaは有力な選択肢です。一方、Webスクレイピングでは、IPブロック、地域による制限、セキュリティ上の懸念といった課題に直面することがあります。Javaプロジェクトでプロキシを利用すれば、こうした障害を回避し、必要なデータを取得できます。

コーディングを始める前に、必要なツールを確認しましょう。

  • Visual Studio Code (Visual Studio 2022や、Javaをサポートする他のIDEでも構いません)
  • Coding Pack for Java
  • Extension Pack for Java
  • Apache Maven 

Visual Studio CodeまたはJavaを初めて使用する場合は、こちらに、Coding PackとExtension Packのインストール方法を詳しく解説したドキュメントがあります。また、このチュートリアルではApache Mavenのインストール手順を確認できます。

注: 対応している形式は”hostname:port”のみです。コードを実行する前に、IPアドレスをホワイトリストに登録してください。この設定はDataImpulseアカウントで行えます。利用するプロキシプランを開き、右上のメニューから”Manage Whitelist IPs”を選択して、ご自身のアドレスをホワイトリストに追加します。サポートが必要な場合や問題が発生した場合は、DataImpulseアカウント管理に関する詳細ガイドをご覧ください。

HttpClientAppを始める

プロキシサーバー経由でトラフィックをルーティングするには、HTTPクライアントを作成します。このアプリは指定したURLにリクエストを送信し、レスポンスを受け取ります。次のコードを使用できます。


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.*;


public class HttpClientApp {


    public static final String proxyHost = "gw.dataimpulse.com";
    public static final int proxyPort = 823;


    public static void main(String[] args) {
        System.out.println("Performing request through proxy...");


        try {
            String response = request("https://api.ipify.org");
            System.out.println("Your IP address: " + response);
        } catch (IOException e) {
            System.err.println("Request error: " + e.getMessage());
        }
    }


    public static String request(String url) throws IOException {
        // Configure the proxy without authentication
        Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyHost, proxyPort));


        // Create and configure the connection
        HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection(proxy);
        connection.setRequestMethod("GET");
        connection.setRequestProperty("User-Agent", "JavaHttpURLConnection");


        // Handle the response
        int responseCode = connection.getResponseCode();
        String responseMessage = connection.getResponseMessage();


        if (responseCode == 200) {
            // Successful response
            try (BufferedReader reader = new BufferedReader(
                    new InputStreamReader(connection.getInputStream()))) {
                StringBuilder response = new StringBuilder();
                String line;
                while ((line = reader.readLine()) != null) {
                    response.append(line);
                }
                return response.toString();
            }
        } else {
            // Error response with detailed output
            StringBuilder errorResponse = new StringBuilder();
            if (connection.getErrorStream() != null) {
                try (BufferedReader reader = new BufferedReader(
                        new InputStreamReader(connection.getErrorStream()))) {
                    String line;
                    while ((line = reader.readLine()) != null) {
                        errorResponse.append(line);
                    }
                }
            }
            throw new IOException("HTTP error: " + responseCode + " " + responseMessage +
                    (errorResponse.length() > 0 ? "\nError details: " + errorResponse : ""));
        }
    }
}

      
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
      

出力は次のようになります。

プロキシローテーターを作成する

プロキシサーバー経由でトラフィックをルーティングするだけでは不十分です。プライバシーを高めるには、リクエストごとに異なるIPを使用する必要があります。そのために、プロキシローテーターを使用します。次のコード例を参考にしてください。


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.*;
import java.util.Arrays;
import java.util.List;


public class ProxyRotator {


    // List of proxies to rotate through
    private static final List proxies = Arrays.asList(
            new Proxy(Proxy.Type.HTTP, new InetSocketAddress("gw.dataimpulse.com", 10000)),
            new Proxy(Proxy.Type.HTTP, new InetSocketAddress("gw.dataimpulse.com", 10001)),
            new Proxy(Proxy.Type.HTTP, new InetSocketAddress("gw.dataimpulse.com", 10002))
    );


    public static void main(String[] args) {
        // URL to request
        String url = "https://api.ipify.org";


        for (Proxy proxy : proxies) {
            System.out.println("Using proxy: " + proxy.address());
            try {
                String response = sendRequestWithProxy(url, proxy);
                System.out.println("Request succeeded with proxy " + proxy.address());
                System.out.println("IP address from API website: " + response);
            } catch (IOException e) {
                System.err.println("Request failed with proxy " + proxy.address() + ": " + e.getMessage());
            }
            System.out.println("------------------------------------------------");
        }
    }


    // Function to send request using a specific proxy
    private static String sendRequestWithProxy(String url, Proxy proxy) throws IOException {
        HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection(proxy);
        connection.setRequestMethod("GET");
        connection.setRequestProperty("User-Agent", "JavaHttpURLConnection");


        int responseCode = connection.getResponseCode();
        if (responseCode == 200) {
            try (BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()))) {
                StringBuilder response = new StringBuilder();
                String line;
                while ((line = reader.readLine()) != null) {
                    response.append(line);
                }
                return response.toString();
            }
        } else {
            throw new IOException("HTTP error code: " + responseCode + " " + connection.getResponseMessage());
        }
    }
}

      
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
      

実行すると、次のような結果が得られます。

プロキシチェッカーを作成する

ここでは、プロキシが指定したWebサイトで正しく動作するかを確認します。プロキシチェッカーアプリを作成し、確認するURLを指定します。

次のコードを試してください。


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.*;
import java.util.Arrays;
import java.util.List;


public class ProxyChecker {


    // List of proxies to rotate through
    private static final List proxies = Arrays.asList(
            new Proxy(Proxy.Type.HTTP, new InetSocketAddress("gw.dataimpulse.com", 10000)),
            new Proxy(Proxy.Type.HTTP, new InetSocketAddress("gw.dataimpulse.com", 10001)),
            new Proxy(Proxy.Type.HTTP, new InetSocketAddress("gw.dataimpulse.com", 10002))
    );


    // Website to check through proxies
    private static final String websiteUrl = "https://api.ipify.org";


    public static void main(String[] args) {
        System.out.println("Starting Proxy Checker...");


        for (Proxy proxy : proxies) {
            System.out.println("\nChecking proxy: " + proxy.address());
            try {
                boolean isWorking = checkProxy(proxy, websiteUrl);
                if (isWorking) {
                    System.out.println("✅ Proxy " + proxy.address() + " works with " + websiteUrl);
                } else {
                    System.out.println("❌ Proxy " + proxy.address() + " does not work with " + websiteUrl);
                }
            } catch (IOException e) {
                System.out.println("❌ Proxy " + proxy.address() + " failed: " + e.getMessage());
            }
            System.out.println("------------------------------------------------");
        }
    }


    // Function to check if proxy works with the given website
    private static boolean checkProxy(Proxy proxy, String url) throws IOException {
        HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection(proxy);
        connection.setRequestMethod("GET");
        connection.setRequestProperty("User-Agent", "JavaHttpURLConnection");
        connection.setConnectTimeout(5000); // 5 seconds timeout
        connection.setReadTimeout(5000);    // 5 seconds timeout


        int responseCode = connection.getResponseCode();
        String responseMessage = connection.getResponseMessage();


        System.out.println("Response: " + responseCode + " " + responseMessage);


        if (responseCode == 200) {
            try (BufferedReader reader = new BufferedReader(
                    new InputStreamReader(connection.getInputStream()))) {
                StringBuilder response = new StringBuilder();
                String line;
                while ((line = reader.readLine()) != null) {
                    response.append(line);
                }
                System.out.println("IP Returned: " + response);
            }
            return true;
        } else {
            try (BufferedReader reader = new BufferedReader(
                    new InputStreamReader(connection.getErrorStream()))) {
                StringBuilder errorResponse = new StringBuilder();
                String line;
                while ((line = reader.readLine()) != null) {
                    errorResponse.append(line);
                }
                System.out.println("Error details: " + errorResponse);
            }
            return false;
        }
    }
}

      
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
      

表示される結果は次のようになります。

Webスクレイピングを実行する

最後に、Webスクレイピングアプリを作成します。必要なデータを抽出するには、スクレイピング対象のURLと、プログラムで取得するデータを指定します。ここでは、ホームページからリンクをスクレイピングします。次のコードを参考にしてください。


package com.dataimpulse;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.*;
import java.nio.charset.StandardCharsets;


public class ProxyWebScraper {


    // Proxy configuration
    private static final String PROXY_HOST = "gw.dataimpulse.com";
    private static final int PROXY_PORT = 823;


    // Target website to scrape
    private static final String TARGET_URL = "https://dataimpulse.com/";


    public static void main(String[] args) {
        System.out.println("Starting Proxy Web Scraper...");


        try {
            // Perform the web scraping through the proxy
            String htmlContent = getHtmlContent(TARGET_URL);
            if (htmlContent != null) {
                // Parse and extract links from the HTML content
                parseHtml(htmlContent);
            } else {
                System.out.println("Failed to retrieve HTML content.");
            }
        } catch (IOException e) {
            System.err.println("Error during scraping: " + e.getMessage());
        }
    }


    // Method to get HTML content through the proxy
    private static String getHtmlContent(String url) throws IOException {
        // Configure proxy
        Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(PROXY_HOST, PROXY_PORT));


        // Create and configure the connection
        HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection(proxy);
        connection.setRequestMethod("GET");
        connection.setRequestProperty("User-Agent", "JavaWebScraper/1.0");
        connection.setConnectTimeout(10000);
        connection.setReadTimeout(10000);


        int responseCode = connection.getResponseCode();
        if (responseCode == 200) {
            // Read and return the HTML content
            try (BufferedReader reader = new BufferedReader(
                    new InputStreamReader(connection.getInputStream(), StandardCharsets.UTF_8))) {
                StringBuilder content = new StringBuilder();
                String line;
                while ((line = reader.readLine()) != null) {
                    content.append(line);
                }
                return content.toString();
            }
        } else {
            System.err.println("Failed to fetch HTML. HTTP error code: " + responseCode);
            return null;
        }
    }


    // Method to parse HTML and extract links using jsoup
    private static void parseHtml(String htmlContent) {
        Document doc = Jsoup.parse(htmlContent);
        Elements links = doc.select("a[href]");


        if (links.isEmpty()) {
            System.out.println("No links found on the page.");
        } else {
            System.out.println("Links found:");
            for (Element link : links) {
                String href = link.attr("abs:href");
                String title = link.text();
                System.out.println("Title: " + title + ", Link: " + href);
            }
        }
    }
}

      
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
      

ただし、作業はまだ完了していません。スクレイピングアプリを正しく動作させるには、MavenでJSoupライブラリをインストールする必要があります。手順は次のとおりです。

  1. 該当するボタンからJavaプロジェクトを作成します。
  1. Maven をプロジェクトタイプとして選択します。
  1. 表示された一覧から”maven-archetype-quickstart”を選択します。
  1. maven-archetype-quickstartのバージョン”1.4″を選択します。
  1. group idに”com.dataimpulse”を入力します。
  1. “artifact Id”フィールドに”proxy-scraper”と入力します。
  1. ライブラリとProxyWebScraperアプリ本体を保存するフォルダーを選択します。すると、proxy-scraperフォルダーが作成されます。次に、コードをproxy-scraper/src/main/java/com/dataimpulse: に移動します。
  1. 以下のスクリーンショットのように、Apache Maven経由でJSoupライブラリを追加します。正しく追加できると、ライブラリが”pom.xml”ファイルに表示されます。
  1. “pom.xml”ファイルで、”maven.compiler.source”と”maven.compiler.target”の値を1.8に変更します。WindowsではCTRL+S、MacではCMD+Sでファイルを保存します。
  1. これでコードを実行できます。画面右上のボタンを使用してください。

スクレイピングプロジェクトの最終結果は次のとおりです。

ご覧のとおり、必要なデータをすべて取得できました。コードを変更すれば、任意のHTMLデータを取得することもできます。このような運用には適法に取得されたIPが不可欠なため、プロキシは慎重に選ぶ必要があります。DataImpulseでは、マルウェアの拡散などの違法行為に関与しない、倫理的に取得された1,500万件のアドレスをご利用いただけます。問題が発生した場合は、有人サポートチームが24/7で対応します。地域ごとのアクセス方針に合わせてターゲティングを調整することも可能です。さらに、当社のプロキシは従量課金制で、1GBあたり$1という手頃な価格のため、予算への負担を抑えられます。開始するには、[email protected] までご連絡いただくか、画面右上の”今すぐ試す“ボタンをご利用ください。

Share article: