In this Article
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ライブラリをインストールする必要があります。手順は次のとおりです。
- 該当するボタンからJavaプロジェクトを作成します。
- Maven をプロジェクトタイプとして選択します。
- 表示された一覧から”maven-archetype-quickstart”を選択します。
- group idに”com.dataimpulse”を入力します。
- “artifact Id”フィールドに”proxy-scraper”と入力します。
- ライブラリとProxyWebScraperアプリ本体を保存するフォルダーを選択します。すると、proxy-scraperフォルダーが作成されます。次に、コードをproxy-scraper/src/main/java/com/dataimpulse: に移動します。
- 以下のスクリーンショットのように、Apache Maven経由でJSoupライブラリを追加します。正しく追加できると、ライブラリが”pom.xml”ファイルに表示されます。
- “pom.xml”ファイルで、”maven.compiler.source”と”maven.compiler.target”の値を1.8に変更します。WindowsではCTRL+S、MacではCMD+Sでファイルを保存します。
- これでコードを実行できます。画面右上のボタンを使用してください。
スクレイピングプロジェクトの最終結果は次のとおりです。
ご覧のとおり、必要なデータをすべて取得できました。コードを変更すれば、任意のHTMLデータを取得することもできます。このような運用には適法に取得されたIPが不可欠なため、プロキシは慎重に選ぶ必要があります。DataImpulseでは、マルウェアの拡散などの違法行為に関与しない、倫理的に取得された1,500万件のアドレスをご利用いただけます。問題が発生した場合は、有人サポートチームが24/7で対応します。地域ごとのアクセス方針に合わせてターゲティングを調整することも可能です。さらに、当社のプロキシは従量課金制で、1GBあたり$1という手頃な価格のため、予算への負担を抑えられます。開始するには、[email protected] までご連絡いただくか、画面右上の”今すぐ試す“ボタンをご利用ください。















