【Java】Seleniumを使ったWebスクレイピングのサンプルコードを解説
JavaとSeleniumを使ってWebブラウザを自動操作し、Webサイトから情報を収集するWebスクレイピングの基本を学べます。Mavenでのプロジェクト設定から、ChromeDriverの準備、具体的なサンプルコードで検索結果のタイトルとURLを取得する方法まで、初心者向けに手順を追って解説しています。
開発環境
- Visual Studio Code:version 1.73.0
- OS:Windows10
- Selenium:4.27.0
JavaのSeleniumとは
Selenium(セレニウム)とは、Webブラウザを自動で操作するためのツールです。 このツールは、私たちが普段使っているGoogle ChromeやFirefoxといったWebブラウザを、プログラムの指示通りに動かすことができます。具体的には、Webページを開いたり、ボタンをクリックしたり、文字を入力したり、ページをスクロールしたりといった、人が手動で行う操作と同じことを自動で実行できるのです。
人がブラウザを操作するのと同じように動かせるため、例えばWebサイトの動作確認(テスト)を自動化したり、Webサイトから特定の情報を効率的に集めたりする際に非常に便利です。
Webページの中には、JavaScriptという技術を使って、ページの一部が後から表示されたり、ボタンのクリックによって新しい情報が読み込まれたりする動的なページがあります。このような「JavaScriptで動的に生成されるページ」から情報を集めること(これを「スクレイピング」と呼びます)は、通常のプログラムでは難しい場合があります。しかし、Seleniumはブラウザ自体を操作するため、JavaScriptが実行された後の最終的なページの状態を扱え、このような動的なページのスクレイピングにも利用できます。
Javaというプログラミング言語からSeleniumを利用するには、「selenium-java」という専用のライブラリを使います。このライブラリをJavaのプロジェクトに組み込むことで、JavaのプログラムからWebブラウザを操作する命令を書けるようになります。
公式ドキュメント:https://www.selenium.dev/ja/documentation/
JavaのSeleniumの使い方
このガイドでは、Javaを使ってWebブラウザの操作を自動化するためのライブラリ「Selenium」の基本的な使い方を解説します。Seleniumを利用することで、Webサイトのテスト、データ収集、定型的な操作の自動化などが可能になります。まずは、Seleniumを使うための準備から見ていきましょう。
Mavenプロジェクトを作成
まず、Javaのプロジェクト管理ツールであるMavenを使って、新しいプロジェクトを作成します。Mavenは、プロジェクトのビルド、依存関係の管理、ドキュメント生成などを自動化するためのツールです。これにより、複雑なプロジェクトも効率的に開発できます。
以下のコマンドを実行して、Mavenの基本的なプロジェクトのひな形(スケルトン)を作成します。
1mvn archetype:generate -DgroupId=com.example -DartifactId=selenium-example -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
このコマンドについて詳しく見ていきましょう。
-DgroupIdには、プロジェクトのパッケージ名(Javaのクラスを整理するための名前空間)を指定します。通常は会社や組織のドメイン名を逆にした形式(例: com.example)を使用します。
-DartifactIdには、プロジェクト名を指定します。この名前がプロジェクトのフォルダ名になります。
-DarchetypeArtifactIdには、Mavenのクイックスタートのテンプレートを指定しています。これにより、Javaアプリケーション開発の基本的な構成を持つプロジェクトが自動的に生成されます。
-DinteractiveMode=falseは、コマンド実行時に対話形式(質問に答えて進める形式)をオフにする設定です。これにより、コマンドを一度実行するだけでプロジェクトが作成されます。
Seleniumをインストール
次に、作成したプロジェクトでSeleniumの機能を使えるようにするために、Seleniumライブラリをプロジェクトに追加します。これを「依存関係の追加」と呼びます。
プロジェクトのルートフォルダにあるpom.xmlファイルを開いてください。このpom.xmlは、Mavenプロジェクトの設定ファイルであり、プロジェクトが使用するライブラリやビルド方法などが記述されています。
dependenciesというセクションに、以下のSeleniumの依存関係の設定を追加します。
1<dependency> 2 <groupId>org.seleniumhq.selenium</groupId> 3 <artifactId>selenium-java</artifactId> 4 <version>4.27.0</version> 5</dependency>
ここで指定している内容は以下の通りです。
groupIdとartifactIdは、Seleniumライブラリを一意に識別するための情報です。
versionは、使用したいSeleniumライブラリのバージョンを指定します。最新の安定版バージョンは、Maven Repository(https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java)で確認できます。このサイトでは、様々なJavaライブラリの情報を検索し、必要な依存関係の記述を見つけることができます。
ビルド設定をする
プロジェクトで作成したJavaのプログラムをコマンドラインから簡単に実行できるようにするため、pom.xmlにビルド設定を追加します。この設定により、Mavenがプログラムの実行方法を認識し、適切な処理を行います。
pom.xmlの<project>タグの直下(<dependencies>タグの後ろなど)に、以下のbuildの設定を追加します。
1<build> 2 <plugins> 3 <plugin> 4 <groupId>org.codehaus.mojo</groupId> 5 <artifactId>exec-maven-plugin</artifactId> 6 <version>3.1.0</version> 7 <configuration> 8 <mainClass>com.example.App</mainClass> 9 </configuration> 10 </plugin> 11 </plugins> 12</build>
この設定では、exec-maven-pluginというMavenプラグインを使用します。このプラグインは、JavaのアプリケーションをMavenから実行するための機能を提供します。
<mainClass>には、アプリケーションの実行開始地点となるクラス(通常はpublic static void main(String[] args)メソッドを持つクラス)を、パッケージ名を含めて正確に指定します。
設定が完了したら、コマンドプロンプトやターミナルでプロジェクトのフォルダ(selenium-example)に移動し、プロジェクトをビルドします。
1cd selenium-example 2mvn clean install
mvn clean installコマンドは、プロジェクトをクリーンアップ(以前のビルド成果物を削除)し、コンパイルして、ローカルリポジトリにインストール(通常はJARファイルを作成)する一連の処理を実行します。
ビルドが成功したら、以下のコマンドでメインクラスを実行してみましょう。
1mvn exec:java -Dexec.mainClass="com.example.App"
このコマンドで「Hello World!」というメッセージがコンソールに表示されれば、プロジェクトの作成と基本的な設定は成功です。これでSeleniumを使ったWeb操作自動化の準備が整いました。
ChromeDriverを準備する
SeleniumでGoogle Chromeブラウザを操作するには、「ChromeDriver」という専用のドライバが必要です。これは、Seleniumの指示をChromeブラウザに伝える役割を果たします。
お使いのChromeブラウザのバージョンと互換性のあるChromeDriverをダウンロードする必要があります。Chromeのバージョン115以降を使用している場合は、「Chrome for Testing」という特別なバージョンのChromeと、それに対応するChromeDriverが提供されています。
Chrome for Testingの可用性ダッシュボードから、お使いのChromeブラウザのバージョンに最も近い「Stable」(安定版)のChromeDriverをダウンロードしてください。 Chrome for Testing:https://googlechromelabs.github.io/chrome-for-testing/
ダウンロードページで、ご自身のオペレーティングシステム(OS)に合ったファイルをダウンロードします。例えば、Windowsの64bit版をお使いの場合は、「win64」と書かれたファイルをダウンロードします。
ダウンロードしたファイルは圧縮されていますので、解凍してください。解凍するとchromedriver.exe(Windowsの場合)という実行ファイルが現れます。
このchromedriver.exeファイルを、作成したMavenプロジェクトの直下にdriversという新しいフォルダを作成し、その中に配置します。これにより、プロジェクトからChromeDriverにアクセスしやすくなります。
フォルダの構成は以下のようになります。
1selenium-example 2├── drivers 3│ └── chromedriver.exe 4├── pom.xml 5└── src
JavaのSeleniumでスクレイピングする
次にJavaのSeleniumでスクレイピングするサンプルコードを解説していきます。JavaとSeleniumを使ってWebサイトから情報を自動で集める(スクレイピング)方法について、具体的なサンプルコードを使って詳しく解説していきます。
スクレイピングのサンプルコード
下記はSeleniumを使用してGoogleで「Javaとは」と検索し、検索結果のタイトルとURLの一覧を取得するサンプルコードです。
1package com.example; 2 3import org.openqa.selenium.By; 4import org.openqa.selenium.WebDriver; 5import org.openqa.selenium.chrome.ChromeDriver; 6import org.openqa.selenium.chrome.ChromeOptions; 7import org.openqa.selenium.WebElement; 8import org.openqa.selenium.support.ui.WebDriverWait; 9import org.openqa.selenium.support.ui.ExpectedConditions; 10import org.openqa.selenium.Keys; 11 12import java.time.Duration; 13import java.util.List; 14 15public class App { 16 17 public static void main(String[] args) { 18 // ドライバのパスを設定 19 System.setProperty("webdriver.chrome.driver", "drivers/chromedriver.exe"); 20 21 // ChromeDriverインスタンスの作成 22 ChromeOptions options = new ChromeOptions(); 23 WebDriver driver = new ChromeDriver(options); 24 25 try { 26 // Googleのホームページを開く 27 driver.get("https://www.google.com"); 28 29 // 検索ボックスを見つける 30 WebElement searchBox = driver.findElement(By.name("q")); 31 32 // "Javaとは" を入力してEnterキーを押す 33 searchBox.sendKeys("Javaとは"); 34 searchBox.sendKeys(Keys.RETURN); 35 36 // 検索結果が表示されるまで待機 37 WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(30)); 38 wait.until(ExpectedConditions.presenceOfElementLocated(By.id("search"))); 39 40 // 検索結果の a タグ内にある h3 要素を取得 41 List<WebElement> results = driver.findElements(By.cssSelector("#search a h3")); 42 43 for (WebElement result : results) { 44 // aタグ(親要素)を取得 45 WebElement parentLink = result.findElement(By.xpath("./ancestor::a")); 46 47 // タイトルとURLを取得 48 String title = result.getText(); 49 String url = parentLink.getDomAttribute("href"); 50 51 if (title != null && !title.isEmpty() && url != null && !url.isEmpty()) { 52 System.out.println("タイトル: " + title); 53 System.out.println("URL: " + url); 54 System.out.println(); 55 } 56 } 57 58 } catch (Exception e) { 59 e.printStackTrace(); 60 } finally { 61 // ドライバーを終了 62 if (driver != null) { 63 driver.quit(); 64 } 65 } 66 } 67}
作成したファイルは、以下のコマンドでビルドして実行できます。
1mvn clean install 2mvn exec:java -Dexec.mainClass="com.example.App"
クラスをインポートする
プログラムを動かすために、まず必要な部品(クラス)を準備する「インポート」という作業を行います。
1import org.openqa.selenium.By; 2import org.openqa.selenium.WebDriver; 3import org.openqa.selenium.chrome.ChromeDriver; 4import org.openqa.selenium.chrome.ChromeOptions; 5import org.openqa.selenium.WebElement; 6import org.openqa.selenium.support.ui.WebDriverWait; 7import org.openqa.selenium.support.ui.ExpectedConditions; 8import org.openqa.selenium.Keys; 9 10import java.time.Duration; 11import java.util.List;
それぞれ以下の役割があります。
By:Webページ上のボタンやテキストボックスといった部品(要素)を、どのように見つけるか(名前、ID、場所など)を指定するためのクラスです。WebDriver、ChromeDriver:Webブラウザ(Chrome)をプログラムから操作するための司令塔のような役割を果たすクラスです。ChromeOptions:Chromeブラウザを起動する際の、特別な設定(例えば、画面に表示せずに裏で動かす「ヘッドレスモード」など)を行うためのクラスです。WebElement:Webページ上で見つけた個々の部品(ボタン、テキスト、リンクなど)をプログラムで操作するために使うクラスです。WebDriverWait、ExpectedConditions:Webページの読み込みが完了するのを待ったり、特定の部品が表示されるまで待ったりするなど、ブラウザの状態を監視して、プログラムが適切なタイミングで動作するように制御するためのクラスです。Keys:キーボードのEnterキーやスペースキーなどの特殊なキー操作をプログラムで行うために使うクラスです。Duration、List:プログラムの待機時間を設定するためのDurationと、複数の部品(要素)をまとめて扱うためのListは、Javaの基本的な機能として使われます。
ChromeDriverの設定をする
次に、プログラムがChromeブラウザを動かすための準備として、Chromeを操作する特別なプログラム(ChromeDriver)の場所を設定し、実際にブラウザを動かすための「司令塔」を準備します。
1System.setProperty("webdriver.chrome.driver", "drivers/chromedriver.exe"); 2 3ChromeOptions options = new ChromeOptions(); 4WebDriver driver = new ChromeDriver(options);
System.setPropertyは、プログラムに「chromedriver.exeという、Chromeを動かすためのプログラムが、drivers/chromedriver.exeという場所にありますよ」と教えてあげるための設定です。これにより、JavaプログラムがChromeを操作できるようになります。
ChromeOptionsは、Chromeブラウザを起動するときの特別な設定を行うためのものです。ここでは特に設定していませんが、これを使ってChromeDriverを新しく作成すると、プログラムからChromeブラウザを自由に操作できる「driver」という司令塔が使えるようになります。
処理の終了時にドライバーを終了する
1try { 2 // スクレイピングの処理 3} catch (Exception e) { 4 e.printStackTrace(); 5} finally { 6 if (driver != null) { 7 driver.quit(); 8 } 9}
このtry〜catch〜finallyという書き方は、プログラムでエラーが起こった時でも、必ず実行したい処理がある場合に便利です。ここでは、スクレイピングの途中で何か問題が起きてプログラムが止まってしまっても、最後に必ずdriver.quit()が実行されて、開いたブラウザが閉じられるようにしています。これにより、ブラウザが開きっぱなしになるのを防ぎます。
driverはtryのブロックの外で用意することで、エラーが起きた場合でも、finallyのブロックからdriverを使ってブラウザを閉じることができるようになっています。
Googleにアクセスしてキーワードを検索する
次にGoogleのホームページを開き、検索ボックスにキーワードを入力して検索します。
1driver.get("https://www.google.com"); 2 3WebElement searchBox = driver.findElement(By.name("q")); 4 5searchBox.sendKeys("Javaとは"); 6searchBox.sendKeys(Keys.RETURN);
Googleの検索ボックスには、name="q"という名前がついています。これは、Webページの裏側にあるHTMLという情報で確認できるものです。この名前を使って、プログラムが検索ボックスを見つけ出します。
findElementは、Webページ上から特定の部品(ここでは検索ボックス)を1つだけ見つけ出すための命令です。見つけ出した検索ボックスに対して、sendKeysを使って「Javaとは」という文字を入力し、さらにKeys.RETURNを使ってキーボードのEnterキーを押す操作をしています。これで、手動で検索するのと同じように検索が実行されます。
検索結果が表示されるまで待機する
1WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(30)); 2wait.until(ExpectedConditions.presenceOfElementLocated(By.id("search")));
プログラムは非常に速く動くため、Webページが完全に読み込まれて表示される前に、次の操作(例えば検索結果の取得)をしようとしてしまうことがあります。そうなると、まだ表示されていない部品を探そうとして、何も見つけられずにエラーになってしまうため、ここで「待機」する処理を入れています。
WebDriverWaitを使って、最大30秒間(Duration.ofSeconds(30)で指定)Webページの特定の部品(ここではid="search"という名前がついた検索結果全体の部分)が表示されるまで待つように設定しています。ExpectedConditions.presenceOfElementLocatedは、「この部品がWebページ上に存在するようになるまで待つ」という意味です。
検索結果のタイトルとURLを取得する
最後に検索結果のタイトルとURLを取得して出力します。
1List<WebElement> results = driver.findElements(By.cssSelector("#search a h3")); 2 3for (WebElement result : results) { 4 WebElement parentLink = result.findElement(By.xpath("./ancestor::a")); 5 6 String title = result.getText(); 7 String url = parentLink.getDomAttribute("href"); 8 9 if (title != null && !title.isEmpty() && url != null && !url.isEmpty()) { 10 System.out.println("タイトル: " + title); 11 System.out.println("URL: " + url); 12 System.out.println(); 13 } 14}
Googleの検索結果のタイトルは、通常h3というタグ(見出しを示すHTMLの部品)で表示されています。ここでは、findElementsという命令を使って、id="search"という検索結果全体の中から、リンク(aタグ)の中にあるh3タグの部品をすべて探し出し、リストとして取得しています。
./ancestor::aという記述は、現在見ている部品(h3タグ)の親方向をたどっていき、一番近いaタグ(リンクの部品)を見つけ出すための特別な方法です。これを「XPath(XML Path Language)」と呼び、Webページの構造を使って部品を指定する際に使われます。
getText()は、見つけた部品(h3タグ)に表示されている文字(タイトル)を取得する命令です。また、getDomAttribute("href")は、リンクの部品(aタグ)に設定されている「リンク先のアドレス(URL)」を取得する命令です。これらで取得したタイトルとURLが、どちらも空でない場合に、プログラムを実行している画面(ターミナル)に表示されるようにしています。
このプログラムを実行すると、自動的にChromeブラウザが起動し、「Javaとは」で検索が行われます。そして、検索結果のタイトルとURLが、ターミナルに表示されるのを確認できます。
おわりに
この記事では、JavaとSeleniumを使ってWebブラウザを自動で操作し、Webサイトから情報を収集するWebスクレイピングの基本を学びました。Mavenでのプロジェクト作成からSeleniumライブラリの追加、そしてChromeDriverの準備といった開発環境のセットアップ手順を解説しました。具体的には、Google検索結果からタイトルとURLを取得するサンプルコードを通して、Web要素の特定や入力、ページの読み込み待機、情報の抽出方法を習得しました。これにより、JavaScriptで動的に生成される動的なWebページからも、必要な情報を効率的に収集する仕組みを理解できたでしょう。今回学んだWebブラウザの自動操作技術は、Webアプリケーションのテスト自動化やデータ収集の効率化など、幅広い分野で活用できます。