Java 1.8 + Selenium (selenium-java 4.7.2) + Google Chrome による簡単検索サンプルメモ

Selenium (selenium-java 4.7.2) をもちいた原始的なサンプルを Java 1.8 ベースで仮組みしてみました。
最近の Selenium 動向の学習＋記憶の復活が目的です。

以下の構成にて、なんとなく動作しました。最新系だとローカルへの Driverインストールは不要なんですね。
勝手に Google Chrome が起動して文字入力していく様は、久しぶりに目にするのもあって、見ていて面白いですね。
※後続のソースコードを見ればわかるように例外処理などは全く実装されていません。あくまでサンプル。

| キー | 値 |
| --- | --- |
| Selenium | selenium-java 4.7.2 |
| Web browser | Google Chrome 108.0.5359.124 （arm64） |
| Java | Oracle Java 1.8 |
| Build system | Apache Maven 3.8.6  |
| OS  | macOS Ventura 13.1 |

ここでは例として国会図書館を挙げていますが、実際には 国会図書館の robots.txt にあるようにこちらのサイトにロボットでアクセスしてはなりません。

# Java

Javaソースコードは以下のようになります。

```java
package jp.igapyon;

import java.time.Duration;
import java.util.List;

import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

public class App {
    public static void main(String[] args) {
        System.err.println("Google Chrome を開きます。");
        final WebDriver driver = new ChromeDriver();

        System.err.println("国会図書館のスマホページを開きます。");
        System.err.println("※あくまでもサンプルであり、このサンプルをもとに国会図書館に対する実用的なアプリを作って実行しないこと。");
        System.err.println("※詳しくは、接続先サイトの robots.txt を参照してください。");
        driver.get("https://iss.ndl.go.jp/sp/");
        sleep(1000);

        System.err.println("詳細検索をクリックします。");
        driver.findElement(By.id("ui-id-2")).click();
        sleep(1000);

        System.err.println("タイトルの検索文字列（一部）を設定します。");
        driver.findElement(By.id("rft.title")).sendKeys("Java");
        sleep(500);

        System.err.println("著者名を設定します。");
        final WebElement eleAuthor = driver.findElement(By.id("rft.au"));
        eleAuthor.sendKeys("伊賀敏樹");
        sleep(500);

        System.err.println("出版社を設定します。");
        driver.findElement(By.id("rft.pub")).sendKeys("技術評論社");
        sleep(500);

        System.err.println("出版年（From）を設定します。");
        driver.findElement(By.id("datefrom")).sendKeys("2000");
        sleep(500);

        System.err.println("出版年（To）を設定します。");
        driver.findElement(By.id("dateto")).sendKeys("2022");
        sleep(500);

        System.err.println("チェックボックスについて、最初のチェック以外をOFFにするよう試みます（その1）");
        final List<WebElement> checkBoxs1 = driver.findElements(
                By.cssSelector("#repository_nos_"));
        boolean isFirstCheck = true;
        for (WebElement look : checkBoxs1) {
            if (isFirstCheck) {
                isFirstCheck = false;
            } else {
                try {
                    look.click();
                    sleep(100);
                } catch (Exception ex) {
                }
            }
        }

        System.err.println("チェックボックスについて、最初のチェック以外をOFFにするよう試みます（その2）");
        final List<WebElement> checkBoxs2 = driver.findElements(
                By.cssSelector("#mediatypes_"));
        isFirstCheck = true;
        for (WebElement look : checkBoxs2) {
            if (isFirstCheck) {
                isFirstCheck = false;
            } else {
                try {
                    look.click();
                    sleep(100);
                } catch (Exception ex) {
                }
            }
        }

        System.err.println("チェックボックスについて、最初のチェック以外をOFFにするよう試みます（その3）");
        final List<WebElement> checkBoxs3 = driver.findElements(
                By.cssSelector("#libraries_"));
        isFirstCheck = true;
        for (WebElement look : checkBoxs3) {
            if (isFirstCheck) {
                isFirstCheck = false;
            } else {
                try {
                    look.click();
                    sleep(100);
                } catch (Exception ex) {
                }
            }
        }

        System.err.println("ENTERキーを押して検索を実施します。");
        eleAuthor.sendKeys(Keys.ENTER);
        sleep(1000);

        System.err.println("次画面が開くのを10秒を上限に待機します。");
        final WebElement nextPageCheck = new WebDriverWait(driver, Duration.ofSeconds(10))
                .until(ExpectedConditions.elementToBeClickable(
                        By.className("changeDevice")));
        sleep(1000);

        System.err.println("検索結果からタイトル文字列を取得します。");
        final List<WebElement> eleSearchResultList = driver.findElements(
                By.cssSelector("p.celltitle.celltitle-small"));
        for (WebElement look : eleSearchResultList) {
            System.out.println("  book title: " + look.getText());
        }

        sleep(3000);

        System.err.println("処理が終わりました。Webブラウザを閉じます。");
        driver.quit();
    }

    private static void sleep(int millisec) {
        try {
            Thread.sleep(millisec);
        } catch (InterruptedException e) {
        }
    }
}

```

## pom.xml

pom.xmlは以下のようになります。

```xml
<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>jp.igapyon</groupId>
  <artifactId>seleniumsample</artifactId>
  <version>1.0-SNAPSHOT</version>

  <name>seleniumsample</name>
  <url>https://www.igapyon.jp</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
  </properties>

  <dependencies>
    <dependency>
      <groupId>org.seleniumhq.selenium</groupId>
      <artifactId>selenium-java</artifactId>
      <version>4.7.2</version>
    </dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

  <build>
    <pluginManagement>
      <plugins>
        <plugin>
          <artifactId>maven-clean-plugin</artifactId>
          <version>3.1.0</version>
        </plugin>
        <plugin>
          <artifactId>maven-resources-plugin</artifactId>
          <version>3.0.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.8.0</version>
        </plugin>
        <plugin>
          <artifactId>maven-surefire-plugin</artifactId>
          <version>2.22.1</version>
        </plugin>
        <plugin>
          <artifactId>maven-jar-plugin</artifactId>
          <version>3.0.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-install-plugin</artifactId>
          <version>2.5.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-deploy-plugin</artifactId>
          <version>2.8.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-site-plugin</artifactId>
          <version>3.7.1</version>
        </plugin>
        <plugin>
          <artifactId>maven-project-info-reports-plugin</artifactId>
          <version>3.0.0</version>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>
</project>
```

# メモ

- 最近の Google Chrome には、ローカルからの Selenium アクセスを許容する仕組みが最初から組み込まれている模様
- セレクタ文字列は Google Chrome の DevTools をもちいると取得しやすい
- 次画面遷移における画面遷移待機は `WebDriverWait...until` を用いて実現できるようだ (こんな命令昔はなかったと思う、が自信はない)