Search Console APIをサービスアカウントで使う

API

「Google Search Console のデータを Python で自動取得したい」――そう思って調べ始めると、サービスアカウント? OAuth? APIキー? と、いきなり選択肢の多さに手が止まります。

さらに設定した通りに動かしたはずなのに 403(アクセス禁止)で弾かれる、という壁も待っています。この記事では、Search Console API をサービスアカウント方式でセットアップし、Python でデータが返ってくるところまでを、つまずきポイントを先回りしながら解説します。

この記事で分かること:

  1. Search Console API と Indexing API の違い(混同しやすい)
  2. なぜ「サービスアカウント」を選ぶのか
  3. Google Cloud 側の設定手順(プロジェクト作成〜JSONキー発行)
  4. なぜ Google Cloud だけでなく Search Console 側の設定も必要なのか
  5. Python での疎通確認と、403 が出たときの切り分け


前提:この記事のゴール

ゴールは「Python を実行したら、自分のサイトの検索クエリと表示回数・クリック数・掲載順位が返ってくる」状態です。取得したデータを分析・活用する方法は範囲を広げすぎるため、別記事で扱います。

まずは「配線を通してデータが流れることを確認する」ところまでを、確実に到達させます。

事前準備:あなたのサイトが、すでに Google Search Console にプロパティとして登録・確認済みであることが前提です。まだの場合は先にサイト登録を済ませてください。


Search Console API と Indexing API は別物です

最初に、多くの人が混同する2つの API を区別しておきます。名前が似ていて、Google Cloud での設定手順もほぼ同じなので、検索するとどちらの記事も入り混じって出てきます。しかし用途はまったく別です。

API用途今回
Search Console API検索クエリ・表示回数・順位などのデータを読み取る。サイトマップ送信やインデックス状況の確認も可能。✅ 使う
Indexing API「このURLをクロールして」と Google に通知する。ただし大半のサイトでは求人情報・配信イベント用途に限定される。❌ 使わない

つまり Search Console API は「見る」ための API、Indexing API は「知らせる」ための API です。今回やりたいのは検索パフォーマンスのデータ取得なので、使うのは Search Console API です。

後述する権限設定で「オーナー権限が必要」と書いている記事を見かけますが、それは Indexing API を使う場合の話が混ざっていることが多いです。データを読むだけなら「制限付き」権限で足ります。


なぜ「サービスアカウント」を選ぶのか

Google Cloud で認証情報を作る画面には、3種類の選択肢が並びます。

種類用途自動実行
APIキー一般公開データへのアクセス❌ ユーザー固有のGSCデータには使えない
OAuth 2.0 クライアントIDブラウザで人が同意してアクセス❌ 無人の自動実行に不向き
サービスアカウントプログラム専用のアカウント✅ これを選ぶ

OAuth を選ぶと、実行のたびにブラウザが立ち上がって同意を求められます。定期実行のように人がいない場面では、そこで処理が止まってしまいます。一方サービスアカウントは、プログラム自身が持つ専用のアカウントで、同意画面を経由せずに動くため自動実行に向いています。

認証情報の画面上部に「OAuth 同意画面を構成してください」という黄色い警告が出ますが、サービスアカウントは同意画面を使わないため、この警告は無視して構いません。


Google Cloud 側の設定

ステップ1:プロジェクトを作成する

Google Cloud Console(https://console.cloud.google.com/)にアクセスし、新しいプロジェクトを作成します。この記事ではプロジェクト名を GSCAPI としています。

プロジェクトの作成

今回プロジェクト名:GSCAPI


ステップ2:Search Console API を有効化する

左メニューの「APIとサービス」→「有効なAPIとサービス」を開く

「+ APIとサービスを有効にする」をクリック

検索窓に「Google Search Console API」と入力して検索

「Google Search Console API」を選択

「有効にする」を押下


ステップ3:認証情報からサービスアカウントを作成する

「認証情報」→「認証情報を作成」→「サービスアカウント」を選択。

つまずきポイント:ロールの付与は空でよい
作成の途中で「ロールを付与」という画面が出ますが、何も選ばずに進めて構いません。ここで選ぶロールは Google Cloud のリソースに対する権限であって、Search Console のデータ閲覧権限とは無関係だからです。閲覧権限は後述の Search Console 側で別途付与します。

サービスアカウント名に gsc-reader と入力します。その他の項目は未入力で構いません。


ステップ4:JSONキーを発行する

作成されたサービスアカウントの「メール」をクリック

「鍵」タブ →「鍵を追加」→「新しい鍵を作成」→ キーのタイプで JSON を選択

ボタンを押した瞬間に鍵ファイルがダウンロードされます

重要:この JSON キーは再ダウンロードできません。紛失した場合は鍵を作り直すことになります。またこのファイルはパスワードと同等の機密情報です。第三者に渡ると検索データを読まれてしまうため、GitHub などに誤ってアップロードしないよう注意してください。


ステップ5:JSONキーを作業ディレクトリに配置する

ダウンロードした鍵を、これから使うプロジェクトのフォルダへ移動します(パスは環境に合わせてください)。

mkdir -p ~/Desktop/claude/keyword-hunter/credentials
mv ~/Downloads/GSCAPI-xxxxxxxx.json ~/Desktop/claude/keyword-hunter/credentials/service-account.json
cat ~/Desktop/claude/keyword-hunter/credentials/service-account.json | grep client_email

最後のコマンドで gsc-reader@GSCAPI-xxxxxx.iam.gserviceaccount.com のようなメールアドレスが表示されます。これをコピーしておいてください。次のステップで使います。


なぜ Search Console 側の設定も必要なのか

ここが、この設定でもっとも直感に反する部分です。Google Cloud で作業したのに、なぜ別サービスの Search Console でも設定が要るのか? 疑問に思う人が多い箇所です。理由は、今おこなった作業とこれからおこなう作業が、まったく別の「許可」だからです。

  • Google Cloud 側(完了):API という窓口を使う権利
  • Search Console 側(これから):このサイトのデータを見る権利

Google Cloud 側の設定は、銀行の「窓口システムを操作できる行員証」を発行するようなものです。しかし行員証を持っていても、口座の持ち主が「この行員に見せてよい」と許可しなければ、他人の口座は見られません。Search Console も同じで、サイトの持ち主が明示的に招待しない限り、誰にもデータを見せません。

さらに重要なのが、サービスアカウントは「あなた自身」とは別のアカウントだという点です。あなたが Search Console のオーナーであっても、gsc-reader@... というサービスアカウントは、Search Console から見れば初対面の他人です。この「他人」を招待して初めて、データを読めるようになります。

Google Search Console(https://search.google.com/search-console)を開き、対象プロパティを選択して以下の手順を進めます。

左メニュー最下部の「設定」をクリック

「ユーザーと権限」を選択

「ユーザーを追加」をクリック

コピーしたサービスアカウントのメールアドレスを貼り付け、権限を「制限付き」にして「追加」

    ユーザーが追加されたことを確認

    重要:この手順を飛ばすと、必ず 403(アクセス禁止)になります。Google Cloud 側の設定だけでは「窓口は叩けるが、あなたのサイトを見る許可がない」状態だからです。403 は「見つからない(404)」ではなく「入る権利がない」という意味です。原因を切り分けるときに覚えておくと役立ちます。


    Python で疎通確認する

    まずは必要なライブラリをインストールします。

    cd ~/Desktop/claude/keyword-hunter
    pip3 install google-auth google-api-python-client

    仮想環境(venv)の利用がおすすめです。システムの Python を汚さずにパッケージを管理できます。詳しくは「【Python】pyenvとvenvの違いと併用方法」で解説しています。

    続いて、確認用のスクリプト gsc_test.py を用意します。

    """
    GSC API 疎通確認スクリプト
    使い方: python gsc_test.py
    """
    from google.oauth2 import service_account
    from googleapiclient.discovery import build
    from datetime import date, timedelta
    
    # ── 設定 ──────────────────────────────
    CREDENTIALS = "./credentials/service-account.json"
    
    # プロパティの指定形式に注意(後述)
    PROPERTY = "https://example.com/"
    # ──────────────────────────────────────
    
    SCOPES = ["https://www.googleapis.com/auth/webmasters.readonly"]
    
    creds = service_account.Credentials.from_service_account_file(
        CREDENTIALS, scopes=SCOPES
    )
    service = build("searchconsole", "v1", credentials=creds)
    
    # 直近28日・上位5クエリだけ取得してみる
    end = date.today() - timedelta(days=2)
    start = end - timedelta(days=28)
    
    request = {
        "startDate": start.isoformat(),
        "endDate": end.isoformat(),
        "dimensions": ["query"],
        "rowLimit": 5,
    }
    
    resp = service.searchanalytics().query(siteUrl=PROPERTY, body=request).execute()
    
    rows = resp.get("rows", [])
    if not rows:
        print("接続は成功したが、データが0件。期間やプロパティを確認してください。")
    else:
        print(f"接続成功! 上位{len(rows)}クエリ:\n")
        for r in rows:
            q = r["keys"][0]
            print(f"  {q}  表示{int(r['impressions'])}  "
                  f"クリック{int(r['clicks'])}  順位{r['position']:.1f}")

    スコープ名 webmasters.readonly は誤字ではありません。Search Console はかつて「ウェブマスターツール(Webmaster Tools)」という名称で、その名残でスコープ名に webmasters が残っています。.readonly は読み取り専用の意味です。

    プロパティの指定形式に注意してください。PROPERTY の値は、プロパティの種類によって書き方が変わります。ここを間違えると 403 かデータ0件になります。

    プロパティの種類Search Console 上の表示例PROPERTY の値
    URLプレフィックス型https://example.com/"https://example.com/"(末尾スラッシュまで一致)
    ドメイン型example.com"sc-domain:example.com"

    Search Console の左上に表示されているプロパティ名を見て、どちらの形式かを確認してください。スクリプトを実行します。

    python gsc_test.py

    次のように、クエリと数値が表示されれば設定は成功です。

    接続成功! 上位5クエリ:
      eclipse jar 作成  表示50  クリック32  順位1.1
      insightface  表示308  クリック18  順位5.9
      ...

    Python 3.9 をお使いの場合:実行時に「FutureWarning: You are using a Python version 3.9 past its end of life」という警告が出ることがあります。これはエラーではなく、サポート終了バージョンに対する注意喚起です。動作自体には影響しませんが、いずれ Python 3.11 以上へ上げておくと安心です。


    403 が出たときの切り分け

    設定した通りに進めても 403 が出ることがあります。原因は主に次の4つです。上から順に確認してください。

    確認順確認項目備考
    Search Console へのユーザー追加サービスアカウントのメールを「ユーザーと権限」に追加したか(最も多い原因)
    反映待ち追加直後は反映に数分かかることがある。5分ほど待って再実行する
    プロパティの形式PROPERTY が URLプレフィックス/ドメインの正しい形式か。末尾スラッシュも確認
    API の有効化Google Cloud で Search Console API を有効化したか

    特に ① と ③ が二大原因です。「Google Cloud 側は完璧なのに 403」という場合、ほぼ Search Console 側の追加漏れか、プロパティ形式の不一致です。


    まとめ

    • Search Console API は「見る」ための API。「知らせる」Indexing API とは別物
    • 自動実行にはサービスアカウントを選ぶ。OAuth ではない
    • ロール付与は空でよい。閲覧権限は Search Console 側で付ける
    • Google Cloud 側と Search Console 側、両方の許可が揃って初めて動く
    • 403 の二大原因は「Search Console への追加漏れ」と「プロパティ形式の不一致」

    これでデータを取得できるようになりました。この API を使えば「どの既存記事をリライトすれば検索順位が伸びるか」を数字で判断することができます。掲載順位11〜30位の記事を機械的に洗い出し、優先度をつけて改善していく――その具体的な方法は、次回の記事で解説します。


    参考リソース

    コメント

    タイトルとURLをコピーしました