[Custom Search API(V1)] JavaでGoogle検索する(準備編)

Custom Search API(V1)をJavaで使ってみました。
今回の記事はAPIを利用開始するのに行うことを記事にしました。

***Custom Search APIとは***
Googleが提供するカスタム検索エンジンで検索することができるAPIです。

カスタム検索エンジンでは、Google検索の様にWeb全体を検索できます。
ただし、Google検索とカスタム検索エンジンは下記の点が異なります。

・ウェブ上の他の検索結果よりも自分のウェブサイトの検索結果が強調される
・アカウントに基づく情報など、一部のGoogle検索の機能が含まれない
・検索結果が10件を超える場合、サブセットの検索結果が表示されることがある

:::note info
実際のCustom Search APIの実行コードは
[⧉[Custom Search API(V1)] JavaでGoogle検索する](https://qiita.com/doran/items/5e05d10d6259971f37ba)
を参照ください。
:::

|No|||目次|
|---|---|---|---|
|1|||[Custom Search APIを使用するための準備](#1-custom-search-apiを使用するための準備)|
||1||[プロジェクトの作成](#11-プロジェクトの作成)|
||2||[Custom Search APIの設定](#12-custom-search-apiの設定)|
||3||[APIを使用するためのキー取得](#13-apiを使用するためのキー取得)|
|||1|[サービス アカウント](#131-サービス-アカウント)|
|||2|[OAuth2.0 クライアントID](#132-oauth20-クライアントid)|
|||3|[APIキー](#133-apiキー)
|2|||[Custom Search Engine（カスタム検索エンジン）の設定](#2-custom-search-engineカスタム検索エンジンの設定)|
|3|||[Custom Search APIを使ってみる](#3-custom-search-apiを使ってみる)|
||1||[googleライブラリの読み込み](#31-googleライブラリの読み込み)|
||2||[CustomSearchAPIインスタンスを取得](#32-customsearchapiインスタンスを取得)|
|||1|[サービスアカウントを利用する場合](#321-サービスアカウントを利用する場合)|
|||2|[OAuth 2.0 クライアントIDを利用する場合](#322-oauth-20-クライアントidを利用する場合)|
|||3|[APIキーを利用する場合](#323-apiキーを利用する場合)|
||3||[プログラムの実行](#23-プログラムの実行)|
|4|||[APIを叩いてみる](#4-apiを叩いてみる)|

# 1. Custom Search APIを使用するための準備
設定は下記から行います。
[⧉Google クラウド プラットフォーム](https://console.cloud.google.com/)

やることは下記の４つです。
[1. GCPプロジェクトの作成](#11-プロジェクトの作成)
[2. Custom Search APIの有効化](#12-custom-search-apiの設定)
[3. プログラムで使用するキーの取得](#13-apiを使用するためのキー取得)
[4. カスタム検索エンジンの設定](#2-custom-search-engineカスタム検索エンジンの設定)

3.は、サービスアカウントかOAuth2.0かAPIキーを利用する3つの方法があります。

### 1.1. プロジェクトの作成
まずはGCPでプロジェクトを作成します。
詳細はこちらの記事を参照ください
[⧉[Google Sheets API] Google Sheets API v4をJavaで操作する(1.1. プロジェクトの作成)](https://qiita.com/doran/items/3d43f776188b2281044c/#11-プロジェクトの作成)

### 1.2. Custom Search APIの設定
Custom Search APIを使えるようにします。
###### 1. メニューの 「APIとサービス」 -> 「ライブラリ」 を選択します。
<img width="480" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/2fda7515-ffdf-11d7-4142-fed896cc8413.png">

###### 2. custom search と入力して「Custom Search API」を検索します。
<img width="480" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/31d6fdc8-a8de-104c-9fce-63283ede4f4d.png">

###### 3. 「有効にする」ボタンを押して「Custom Search API」を使用可能にします。
<img width="480" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/7fac249b-acfc-c04e-a55c-0d4da3cd8372.png">

### 1.3. APIを使用するためのキー取得
プログラムからAPIを実行するための準備を行います。
サービスアカウント、OAuth2.0、APIキーを利用する3つの方法があります。

#### 1.3.1. サービス アカウント
同じ内容を下記の記事に掲載してますので、下記の記事を参照ください。
[⧉[Google Sheets API] Google Sheets API v4をJavaで操作する(1.3. Googleサービスアカウントの作成)](https://qiita.com/doran/items/3d43f776188b2281044c/#13-googleサービスアカウントの作成)

#### 1.3.2. OAuth2.0 クライアントID
同じ内容を下記の記事に掲載してますので、下記の記事を参照ください。
[⧉[Google Drive API v3] JavaでDrive APIを使う(1.3.2. OAuth2.0 クライアントID)](https://qiita.com/doran/items/15b2c59adb410ddeeb8a/#132-oauth20-クライアントid)

#### 1.3.3. APIキー
APIを操作するためにAPIキーを取得します。

「APIとサービス」 -> 「認証情報」　を選択すると以下の画面が表示されます。
<img width="480" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/d7801ca1-1ac3-21c2-4dc6-22af9a031367.png">

「認証情報を作成」 -> 「APIキー」 を選択します。
<img width="480" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/f360485a-787f-3dc8-e1cf-92d3db21d51e.png">

APIキーが作成されますので、「自分のAPIキー」の値を保持してください。
この値をプログラムで指定します。
<img width="380" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/bccbd62b-3554-ace2-5d71-1b668aaf977d.png">

# 2. Custom Search Engine（カスタム検索エンジン）の設定
下記の画面でカスタム検索エンジンを設定します。
[⧉Custom Search Engine（カスタム検索エンジン）](https://cse.google.com/cse/all)

新しい検索エンジンを作成を作成します。
<img width="480" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/da2956d3-959d-91ef-13e4-12c21df6252e.png">

検索エンジンの名前と検索設定等を設定して、
「作成」ボタンを押すと検索エンジンが作成されます。
画像で選択している箇所（クエリパラメータCX）の値を保持してください。
この値をプログラムで指定します。
<img width="480" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/f12ce6a3-66ef-d1f1-6b41-fa763418ec07.png">

# 3. Custom Search APIを使ってみる
### 3.1. googleライブラリの読み込み
Custom Search APIを使用するためにライブラリのパスを設定します。
私の環境はpom.xmlで下記を指定しています。
Javaのバージョンは21を使用しています。

```xml
<dependencies>
    <dependency>
        <groupId>com.google.api-client</groupId>
        <artifactId>google-api-client</artifactId>
    </dependency>
    <dependency>
        <groupId>com.google.auth</groupId>
        <artifactId>google-auth-library-oauth2-http</artifactId>
    </dependency>

    <dependency>
        <groupId>com.google.apis</groupId>
        <artifactId>google-api-services-customsearch</artifactId>
        <version>v1-rev20240326-2.0.0</version>
    </dependency>
    
    <!-- OAuth2.0でAPIを使う場合は下記の2つを追加してください。 -->
    <dependency>
        <groupId>com.google.oauth-client</groupId>
        <artifactId>google-oauth-client-java6</artifactId>
    </dependency>
    <dependency>
        <groupId>com.google.oauth-client</groupId>
        <artifactId>google-oauth-client-jetty</artifactId>
    </dependency>
</dependencies>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>com.google.cloud</groupId>
            <artifactId>libraries-bom</artifactId>
            <version>26.31.0</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>
```

### 3.2. CustomSearchAPIインスタンスを取得

#### 3.2.1. サービスアカウントを利用する場合
コード中の「JSONファイルのパス」は、
[⧉[Google Sheets API] Google Sheets API v4をJavaで操作する(1.3. Googleサービスアカウントの作成)](https://qiita.com/doran/items/3d43f776188b2281044c#13-googleサービスアカウントの作成)
で取得したJSONファイルのパスを指定してください。

Custom Search APIを利用するための「スコープ」は、
「https:\//www.googleapis.com/auth/cse」のみです。

```java
private static CustomSearchAPI getCustomSearchAPI() throws Exception {
    HttpTransport transport = GoogleNetHttpTransport.newTrustedTransport();
    JsonFactory jsonFactory = GsonFactory.getDefaultInstance();
    
    try(InputStream input = new FileInputStream("JSONファイルのパス")){
        GoogleCredentials credentials = GoogleCredentials
                .fromStream(input)
                .createScoped( Arrays.asList("https://www.googleapis.com/auth/cse"));
        
        return new CustomSearchAPI.Builder(transport, jsonFactory, new HttpCredentialsAdapter(credentials)).build();
    }
}
```
#### 3.2.2. OAuth 2.0 クライアントIDを利用する場合
コード中の「JSONファイルのパス」は、
[⧉[Google Drive API v3] JavaでDrive APIを使う(1.3.2.1 認証情報の作成)](https://qiita.com/doran/items/15b2c59adb410ddeeb8a/#1321-認証情報の作成)
で取得したJSONファイルのパスを指定してください。

コード中の「認証情報を保存するフォルダパス」は、
認証情報が保存されるフォルダのパスを指定してください。
このコードを実行するとOAuth同意画面が表示されます。
ユーザーが同意をすると認証情報を保存するフォルダにファイルが生成されます。
このファイルが存在した場合は、再度実行してもOAuth同意画面は表示されません。

Custom Search APIを利用するための「スコープ」は、
「https:\//www.googleapis.com/auth/cse」のみです。
```java
private static CustomSearchAPI getCustomSearchAPI() throws Exception {
    HttpTransport transport = GoogleNetHttpTransport.newTrustedTransport();
    JsonFactory jsonFactory = GsonFactory.getDefaultInstance();
    
    try(Reader reader = new InputStreamReader(new FileInputStream("JSONファイルのパス"))){
        GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(jsonFactory,reader);

        GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
                transport, jsonFactory, clientSecrets, 
                Arrays.asList("https://www.googleapis.com/auth/cse"))
            .setDataStoreFactory(new FileDataStoreFactory(new java.io.File("認証情報を保存するフォルダパス")))
            .build();
        
        LocalServerReceiver receiver = new LocalServerReceiver.Builder().build();
        Credential credential = new AuthorizationCodeInstalledApp(flow, receiver).authorize("user");
        
        return new CustomSearchAPI.Builder(transport, jsonFactory, credential).build();
    }
}
```

#### 3.2.3. APIキーを利用する場合
コード中の「APIキー」は、
[1.3. APIを使用するためのキー取得(1.3.3. APIキー)](#133-apiキー)
で取得したAPIキーを指定してください。

```java
private static CustomSearchAPI getCustomSearchAPI() throws Exception {
    HttpTransport transport = GoogleNetHttpTransport.newTrustedTransport();
    JsonFactory jsonFactory = GsonFactory.getDefaultInstance();
    
    CustomSearchAPIRequestInitializer key = new CustomSearchAPIRequestInitializer("APIキー");
    return new CustomSearchAPI.Builder(transport, jsonFactory, null)
            .setGoogleClientRequestInitializer(key).build();
}
```

### 3.3. プログラムの実行
プログラムを動かします。

コード中の「CXキー」は[2. Custom Search Engine（カスタム検索エンジン）の設定](#2-custom-search-engineカスタム検索エンジンの設定)
で取得した値を設定してください。
この値は必須です。

サンプルでは「doran」を検索しています。

```java
public static void main(String[] args) throws Exception{
    CustomSearchAPI customSearch = getCustomSearchAPI2();
    CustomSearchAPI.Cse cse = customSearch.cse();
    
    CustomSearchAPI.Cse.List list = cse.list();
    list.setQ("doran");
    list.setCx("CXキー");
    
    Search res = list.execute();
    System.out.println(res);
}
```
# 4. APIを叩いてみる

APIの詳細はこちらの記事を参照ください。
[⧉[Custom Search API(V1)] JavaでGoogle検索する](https://qiita.com/doran/items/5e05d10d6259971f37ba)

<br>
<br>
おしまい。。