本記事の構成および論理分析にはAI(人工知能)を使用しています。情報の正確性は、システム管理者(UNIXユーザー)による手動検証済みです。
Google Search Console APIで検索順位をTSVに記録するシェルスクリプトを作りました | UNIX Cafe

今回紹介するスクリプトは、GitHubの gsc-rank-tracker に置いています。
これまでは、Webサイトやブログの検索順位を自動で計測・管理するために、クラウド型の順位チェックツールを使っていたのですが、2025年後半のGoogle APIの仕様変更に伴う計測制限などで使いにくい面が目立ってきたので、自作スクリプトを作成することにしました。
Google Search Consoleを使って検索順位を確認することもできるのですが、サイトを切り替えて、検索パフォーマンスを開いて、クエリを探して、日付を合わせて確認するなど、たまに見るだけならよいのですが、同じキーワードを何度も確認するなら、手元にログとして残したくなります。
そこで、Google Search Console APIから検索クエリのデータを取得し、見たいキーワードだけをTSVに保存するシェルスクリプトを作りました。サンプルスクリプトはGitHubで公開していますので、興味のある方は使ってみてください。
今回作ったスクリプトは、check_rank.shです。
この記事では、check_rank.shで何を取得しているのか、どのファイルを用意するのか、どう実行するのかを整理します。
このスクリプトで取得する順位
最初に大事な点を書いておきます。
このスクリプトで扱う順位は、Google検索結果画面を直接確認した実順位ではありません。
Search Console APIが返すposition、つまりSearch Console上の平均掲載順位です。この記事では、これを「GSC平均掲載順位」と呼びます。
検索結果画面をスクレイピングして、ある時点の表示順位を取るものではなく、Search Consoleに記録された検索パフォーマンスのデータをAPIで取得します。
そのため、この記事でいう順位は「自分がブラウザで検索したときに見えた順位」と完全に一致するとは限りません。
今回作ったもの
check_rank.shは、指定したサイトとキーワードについて、GSC平均掲載順位を取得するシェルスクリプトです。
大まかな流れは次のようになります。
- サービスアカウントでGoogle APIに認証します
- Search Console APIからサイトごとの検索クエリ一覧を取得します
- ローカルのキーワード一覧と照合します
- date / site / query / position をTSVに保存します
- 今回の結果をターミナルにサイト別で表示します
Web UIはありません。DBにも保存しません。まずはローカルのTSVファイルに、必要なキーワードの順位だけを残すようにしています。
最小構成ですが、TSVで残しておけば、あとからグラフ化したり、前回との差分を見たり、通知に回したりできます。
このスクリプトでやること、やらないこと
今回のスクリプトでやることは、次の範囲です。
- サービスアカウントでGoogle APIのアクセストークンを取得します
- Search Console APIの searchAnalytics.query を呼び出します
- サイト一覧ファイルに書いた複数サイトをまとめて処理します
- サイト別キーワードファイルとAPI結果を照合します
- data/rank_history.tsv に履歴を保存します
- 同じ date + site + query の行があれば、今回の結果で置き換えます
逆に、次のことはやりません。
- Google検索結果画面のスクレイピング
- Web UI
- DB保存
- グラフ化
- 通知
- cron登録
検索順位の管理ツールを作るというより、「Search Console APIから必要な値を取り出して、あとで扱いやすい形で保存する」ための小さな道具です。
必要なコマンド
スクリプトでは、次のコマンドを使います。
curl
jq
opensslcurlでGoogle APIを呼び出し、jqでJSONを組み立てたりレスポンスを取り出したりします。opensslは、サービスアカウント認証で使うJWTの署名に使います。
スクリプトの先頭では、次の安全設定を入れています。
set -euo pipefail途中でコマンドが失敗したり、未定義の変数を参照したりしたときに、そのまま処理を続けないようにしています。
-e:エラー時に即時停止-u:未定義変数をエラーにする-o pipefail:パイプラインの途中のエラーも-eで検知できるようにする
用意するファイル
このスクリプトでは、主に次のファイルを使います。
~/.secret/gsc-service-account.json
config/sites.tsv
keywords/example.txt
data/rank_history.tsv- gsc-service-account.jsonは、Google Cloudで発行したサービスアカウントJSONキーです。
- sites.tsvには、Search Consoleの対象プロパティと、そのサイトで監視するキーワードファイルを書きます。
- examle.txtには、監視したいキーワードを1行1キーワードで書きます。
- rank_history.tsvは、取得した結果の保存先です。初回実行時に出力先として作られます。
サービスアカウントJSONキーを置く
Google Search Console APIを呼び出すために、サービスアカウントJSONキーを使います。
スクリプトでは、デフォルトで次のパスを見に行きます。
~/.secret/gsc-service-account.jsonJSONキーは秘密情報なので、リポジトリには入れません。スクリプト内にも直書きしません。
ファイル権限は、次のようにしておくと安心です。
chmod 600 ~/.secret/gsc-service-account.jsonまた、Search Console側で、対象プロパティにサービスアカウントのメールアドレスを追加しておく必要があります。
サービスアカウントから見えているサイトは、次のコマンドで確認できます。
./check_rank.sh --list-sitesここに出てこないサイトは、スクリプトからSearch Console APIを呼び出せません。
サイト一覧ファイルを書く
次に、config/sites.tsvを用意します。
形式は、次の2列です。
site_url keywords_file書式のサンプルです。
https://example.com/ keywords/example-com.txt
https://example.net/ keywords/example-net.txt
https://example.org/ keywords/example-org.txtsite_urlには、Search Console側のプロパティ名と完全に一致する値を書きます。
URLプレフィックスプロパティなら、末尾のスラッシュも含めて一致させます。ここがずれると、Search Console API側で対象サイトとして扱えません。
キーワード一覧を書く
キーワードファイルは、1行1キーワードで書きます。
例えば、keywords/example-com.txtは次のような形です。
keyword 1
keyword 2
keyword 3空行は無視します。#から始まる行も無視します。
各行の前後にある空白やタブは、スクリプト側で削除してから照合します。
実行する
基本の実行コマンドは次のとおりです。
./check_rank.sh取得対象日は、デフォルトでは3日前です。
Search Consoleのデータは当日分がすぐ安定するとは限らないため、少し前の日付を使うようにしています。
日付を指定したい場合は、TARGET_DATEを指定します。
TARGET_DATE='2026-09-07' ./check_rank.sh出力先を変えたい場合は、OUTPUT_FILEを指定します。
OUTPUT_FILE='data/my_rank_history.tsv' ./check_rank.shサイト一覧ファイルを変えたい場合は、SITES_FILEを指定します。
SITES_FILE='config/sites.tsv' ./check_rank.shターミナルに表示される結果
実行すると、まず認証や取得中の進捗が表示されます。
Authenticating with Google API... done
Checking accessible Search Console sites... done
Fetching https://example.com/ (keywords/example-com.txt): # done (1234 GSC query row(s))取得が終わると、サイトごとに区切った表を表示します。
Date: 2026-09-07
Sites: config/sites.tsv
--------------------------------------------------------------------------------
Site: https://example.com/
--------------------------------------------------------------------------------
Date GSC平均掲載順位 Query
------------ -------------- -----
2026-09-07 1.00 example query
2026-09-07 9.10 sample keyword数値の順位は、小さい順に表示します。
NAやERRORは、数値順位のあとに表示されます。
TSVに保存される結果
取得した結果は、デフォルトでは次のファイルに保存します。
data/rank_history.tsv保存形式はTSVです。
date site query position表示例です。
2026-09-07 https://example.com/ sample keyword 9.1
2026-09-07 https://example.com/ example query 1.0
2026-09-07 https://example.com/ missing keyword NA
2026-09-07 https://example.com/ example keyword ERRORNAは、APIで取得した検索クエリ一覧の中に対象キーワードがなかった状態です。
ERRORは、サービスアカウントから対象のSearch Consoleプロパティへアクセスできなかった状態です。
同じdate + site + queryの行がすでにある場合は、今回取得した結果で置き換えます。
そのため、同じ日付でスクリプトを再実行しても、同じキーワードの行が増え続けることはありません。
APIから直接キーワードを絞らない理由
このスクリプトでは、Search Console APIを呼び出す時点では、検索クエリのフィルターを指定していません。これは、APIの節約と実行時間の短縮のためです。検索キーワードが増えば増えるほど、この差は顕著になります。
そこで、まずサイトごとの検索クエリ一覧を取得して、そのあとで、ローカルのキーワード一覧と照合します。
一括取得のメリット
リクエスト数を劇的に削減できる(APIの節約)
- キーワード(
query)ごとにAPIを叩くと、1キーワード=1リクエストを消費します。 - キーワードを絞らずに「丸ごと(バルク)」取得すれば、1回のリクエストで最大25,000〜50,000行(ページネーションを利用)のデータをまとめて取得できます。
全体の実行時間を短縮できる(高速化)
- APIへのリクエストには、ネットワークの往復時間(レイテンシ)が発生します。
- 1万個のキーワードを1つずつリクエストすると膨大な時間がかかりますが、一括取得してプログラム側(PythonやSQLなど)でフィルタリングすれば、数秒〜数分で処理が完了します。
APIのクォータ(割当量)制限を回避できる
- Search Console APIには「1サイトあたり毎分1,200リクエスト」などの制限があります。個別リクエストが多いと、すぐにエラー(
429 Too Many Requests)になってしまいます。
リクエスト本文のイメージは次のようになります。
{
"startDate": "2026-09-07",
"endDate": "2026-09-07",
"rowLimit": 25000,
"dimensions": ["query"],
"dimensionFilterGroups": [
{
"filters": [
{
"dimension": "country",
"operator": "equals",
"expression": "jpn"
}
]
}
]
}国別フィルターは日本に固定しています。dimensionsはqueryだけです。
この形にしておくと、サイトごとにまとめてAPIを呼び出せます。
また、対象キーワードがAPI結果に存在しなかった場合も、NAとしてログに残せます。
キーワードの照合ルール
APIから取得した検索クエリと、ローカルのキーワード一覧は、次の順番で照合します。
- キーワード文字列の完全一致
- 完全一致がない場合、英字の大文字小文字を区別しない一致
- 見つからなければ NA
日本語キーワードは、基本的に完全一致で扱います。
英字を含むキーワードでは、大文字小文字の違いで取りこぼしにくくしています。
例えば、キーワードファイルにSample Keywordと書いてあり、API側のクエリがsample keywordだった場合でも、完全一致がなければ大文字小文字を無視して照合します。
サービスアカウントから見えないサイトの扱い
サイト一覧ファイルに書いたサイトが、サービスアカウントから見えていないこともあります。
その場合、Search Console APIの検索パフォーマンス取得は呼び出さず、そのサイトの各キーワードにERRORを入れて出力します。
例えば、次のような行になります。
2026-09-07 https://example.com/ example keyword ERRORこの状態になったら、まず./check_rank.sh --list-sitesで、サービスアカウントから見えているプロパティを確認します。
設定値は環境変数で変えられる
スクリプト内では、いくつかの値を環境変数で上書きできるようにしています。
SITES_FILE サイト・キーワード対応表
SERVICE_ACCOUNT_JSON サービスアカウントJSONキー
OUTPUT_FILE TSV出力先
TARGET_DATE 取得対象日
ROW_LIMIT 1サイトあたりの最大取得行数
VERBOSE no-dataメッセージの表示普段はデフォルト値のままで使い、必要なときだけ環境変数で変えます。
例えば、別のサービスアカウントJSONキーを使う場合は、次のように実行します。
SERVICE_ACCOUNT_JSON="$HOME/.secret/another-gsc-service-account.json" ./check_rank.shこのスクリプトを作ってよかったところ
1番良かったのは、複数サイトのキーワードを1回のコマンドで確認できることです。Search Consoleを開いてサイトを切り替える作業を、毎回やらなくてよくなります。
また、キーワード一覧をテキストファイルで管理できるので、「このサイトではこのキーワードを見る」というという対応が分かりやすくなりました。
そしてキーワードを書き直しても、その場でチェックできるので、順位計測ツールでよくある、次の計測日まで待つ必要がなくなり、何度でも書き直して、その場で順位の変化を見ることができます。
出力がTSVなので、あとからawkで見ることもできますし、表計算ソフトに読み込むこともできます。
今後足せそうなこと
今のスクリプトは、とりあえず最小構成にしていますが、欲しい機能があれば、後から追加することができます。
例えば次のような機能です。
- cronで毎日実行する
- TSVからグラフを作る
- 前回との差分を表示する
- 大きく順位が変わったキーワードだけ通知する
- サイト別の日報に組み込む
ただ、全部作ると重くなるので、そういうのは専門の順位計測ツールを使えばいいかなと思っています。
自分の用途には、今のスクリプトで十分なので、まずは、Search Console APIから必要なデータを取り、ローカルのTSVに安定して残すところまでにしました。
まとめ
check_rank.shを使うと、Google Search Console APIからGSC平均掲載順位を取得し、指定キーワードだけをローカルのTSVに記録できます。
Google検索結果画面をスクレイピングするものではなく、Search Console APIが返すpositionを記録するスクリプトです。
Web UIやDBはありませんが、複数サイトのキーワードをまとめて確認し、履歴として残す用途には十分です。
TSVで残しておけば、あとから集計、グラフ化、通知にもつなげやすくなります。









