Google Search Console APIを利用してWebページのインデックス登録状況を確認してみた

Google Search Consoleへsitemapを送信するエンドポイントがあったのですが、いつのまに非推奨になっていました。

参考URL

代替方法を探していたところ、サーチコンソールの操作を行うAPIが提供されていたので、試しに利用してみました。

インデックスの登録を自動化できればという思惑があったのですが、Google Search Console APIではインデックス登録状況を確認することはできても、インデックス登録までは残念ながらできませんでした。

目的

新規作成または更新したブログ記事をインデックスに登録するのが目的だった(しかし前述した通りインデックスの登録はGoogle Search Console APIではできない)。

しかし今後なにか別の用途で使うことがあるかもしれないので、内容をまとめます。

ちなみにAPIの操作はGoのライブラリを使うことにしました。

Google Search Console APIの利用料金

無料で使えるとのこと(ただし利用制限はある) 。

All use of Google Search Console API is free of charge. However, it is subject to usage limits. https://developers.google.com/webmaster-tools/pricing

準備

GCPのプロジェクト作成

サーチコンソールAPIを使うには、Google Developers Consoleでプロジェクトを作成したり、認証情報を設定しないといけません。

上記URLをひらいて、まずGCPのプロジェクトを作ります。作ったら、APIの有効化、サービスアカウントの作成、サチコへの登録作業を行います。

Google Search Console APIの有効化

  1. APIs & Servicesを開く
  2. Enable APIs & servicesを開く
  3. Google Search Console APIを検索→有効にする

サービスアカウントの作成とjsonキーの追加

  1. IAM → Service Accountsを開き、サービスアカウントを作成
  2. 作成したサービスアカウントを開き、キーを作成→JSON形式でダウンロード

Google Search Consoleにサービスアカウントを登録

  1. サーチコンソールの画面の設定→ユーザーと権限をクリック
  2. ユーザー追加を押して、サービスアカウントのメールアドレスを登録

Go言語のAPIクライアントのセットアップ

Shell Scriptなどでいけそうですが、APIを楽に扱えるライブラリが提供されていたので、私はGoのライブラリを利用することにしました。

go get コマンドを使用して Google API Go Client ライブラリをインストールします。

go get google.golang.org/api/webmasters/v3

Go以外にもPythonやJavaなどのプログラミング言語に対応しているので、使いたい言語のライブラリを使えます。

コードの実装

package main

import (
	"context"
	"flag"
	"fmt"
	"log"
	"os"

	"google.golang.org/api/option"
	"google.golang.org/api/searchconsole/v1"
)

func main() {
	// コマンドライン引数で、サービスアカウントのjson keyと、確認したいwebページのURLを受け取る。
	jsonKeyPath := flag.String("json_key_path", "", "JSON key")
	inspectionURL := flag.String("inspection_url", "", "Inspection URL")
	flag.Parse()

	if *jsonKeyPath == "" || *inspectionURL == "" {
		log.Fatalf("Both json_key_path and inspection_url are required.")
	}

	jsonKeyByte, err := os.ReadFile(*jsonKeyPath)
	if err != nil {
		log.Fatalf("Error reading file: %v", err)
	}

	// Search Console APIの初期設定。
	svc, err := searchconsole.NewService(context.Background(), option.WithCredentialsJSON(jsonKeyByte))
	if err != nil {
		log.Fatalf("Unable to retrieve Search Console client: %v", err)
	}

	// 検査対象の設定。
	urlInspectionIndexService := searchconsole.NewUrlInspectionIndexService(svc)
	urlInspectionIndexInspectCall := urlInspectionIndexService.Inspect(&searchconsole.InspectUrlIndexRequest{
		InspectionUrl: *inspectionURL,
		SiteUrl:       "ここにWebサイトのURLをかく",
	})

	// Google Search Console APIにリクエストを投げる。
	if response, err := urlInspectionIndexInspectCall.Do(); err != nil {
		log.Fatalf("Failed to execute urlInspectionIndexInspectCall.Do(): %v", err)
	} else if response != nil {
		fmt.Println(response.InspectionResult.InspectionResultLink)
		fmt.Println(*response.InspectionResult.IndexStatusResult)
	}
}

実行

go main.go --json_key_path=xxx --inspection_url=xxx

結果

https://search.google.com/search-console/inspect?resource_id=https://...
{Crawled - currently not indexed MOBILE https://... INDEXING_ALLOWED 2023-11-23T06:42:18Z SUCCESSFUL [] ALLOWED [https://.../indenx.xml https://.../sitemap.xml]  NEUTRAL [] []}

トラブルシュート

401になる

googleapi: Error 401: API keys are not supported by this API. Expected OAuth2 access token or other authentication credentials that assert a principal. See https://cloud.google.com/docs/authentication

指定したAPIキーの情報がおかしいのでクレデンシャルの情報を見直す。

403になる

googleapi: Error 403: You do not own this site, or the inspected URL is not part of this property.

urlInspectionIndexService.Inspect()の引数に設定した構造体のフィールド値がおかしいか、サービスアカウントの権限まわりに問題があるので見直す。

例えば、SiteUrlの値はhttps://hogehoge-mogumogu-tekuteku.com/だったとして、末尾のトレイリングスラッシュ(/)の有る無しだったり、プロトコル(https:)の代わりにsc-domain:を使うわ無いといけなかったりするケースが有るので、そこらへんを見直す。

私の場合はサービスアカウントの権限に問題があり、再作成したら正常にレスポンスが返ってきました。

まとめ

前準備が少し手間ですが、準備が整えばGoで簡単に呼び出せて便利でした。

インデックスの登録を促す方法は、Google Search CnetralのIndexing APIを利用することもできそうですが、動画や雇用関連の情報を扱うものが対象らしく、ブログ用のAPIではないので使いませんでした。

そもそもこのブログの目的を考えると、Googleにインデックスされることがそれほど重要ではないことに気づいたため、sitemapなどの最低限の対策だけ行い、クローラーに任せるのが良いのではと思ったりしました。

あとは、PubSubHubbubが気になっているので、それを使ってみるのはありかもなと考えています。