
「キーワード登録不要」の検索順位チェックツールを作ってみた【維持費タダ】
在宅フリーランスエンジニアの広瀬と申します。
副業でITブログを運営し、最高で月10万PVの時もありました。(昔の話)
ところで、ブログを書いている人なら自分の記事がどれくらい読まれているのか気になりますよね? Google検索で1番目なんかに表示されれば、毎日そこそこの人が記事を見に来てくれます。
そこで活躍するのが「検索順位チェックツール」。
Googleで検索されそうなキーワードを登録しておけば、ボタン1つで自分の記事が何番目に出てくるのか分かって大変便利です。
ですが、記事を書く → ツールに検索キーワードを登録 を繰り返すのって…ぶっちゃけ面倒じゃないですか?
ぼくはそれがイヤで、けっきょく順位チェックツールを使わなくなってしまいました。。
そして月日は流れ、ある日ふと思いつきます。
「サーチコンソールを加工して順位チェックすれば良くね?」
ご存知 Googleサーチコンソール には、自分のサイトの
どの記事が
どんな検索キーワードで
何位に表示されているか
のデータがすべてそろっています。
このデータを引っこ抜いて表やグラフにすれば、順位チェックツールっぽくなるのでは…?
ということで、作ってみた結果がこちら↓






デザインはまぁ置いといて、欲しい情報をいい感じに整理できて個人的には満足な仕上がりです。
ということで、このnoteではそんな順位チェックツールもどきの作り方を紹介したいと思います。特に次にような方にオススメです。
・チェックツールにいちいちキーワード登録するのが面倒
・記事を書くことに集中したいから、順位チェックは自動でやってほしい
・そもそもキーワード選定してない。でも順位は気になる
・有料の順位チェックツールを使ってるが、正直もっと安く済ませたい
・WEB上のアプリやツールを触るのに抵抗が無い
・後で楽できるなら、最初の構築作業はがんばれる
ただし作業量は多いので、半日ほどの時間を確保してから挑戦してみてください。
あと、文字数が膨大になってしまうので最終ステップの「表・グラフの作り方」の詳細は割愛します。そのため有料ではありますが、 ↑ の表・グラフを一発で再現できるテンプレートをご用意したので、グラフ作るのが面倒な方はご検討ください。
※無料部分だけで構築までできますので、ぜひトライしてみてください。
はじめに 良い点・悪い点
良い点:キーワード登録しなくていい
ふつうの順位チェックツールだと、新しく記事を書くたびに「こんな単語で検索されるかな?」と考えて検索キーワードを登録する必要があります。
一方、サーチコンソールのデータを元にしたチェックツールであれば、このキーワード登録がまるっと不要。
なんせ全てのキーワードでの順位がもうサーチコンソールにあるので。
もちろん「順位チェック実行」みたいなボタンを押す必要もありません。
その他、以下のようなメリットがあります。
基本的には無料で使える(無料ツール群を組み合わせて作ります)
ブラウザでURLを叩くだけでいつでも最新データを見れる
グラフや表を自分でカスタマイズできる
悪い点:実際に検索されないとデータが無い
サーチコンソールのデータは、実際に誰かが検索してはじめてカウントされます。そのため、狙ったキーワードが決まっていても、必ずしも順位チェックできるとは限りません。
たとえば「note 使い方」というキーワードを狙って記事を書いたとします。
ところが誰もこのキーワードで検索しなければ、いつまで経ってもサーチコンソールには順位が表示されません。
とはいえ、実際に検索されない=順位チェックする意味がないキーワード と捉えれば、あまり悪い点でもないかもしれません。
その他、以下のようなデメリットがあります。
最短でも3日前のデータが最新(いま現在の順位は分からない)
Google以外の順位チェックはできない
競合サイトの順位チェックはできない(自分のサイトだけ)
7日ごとに手動で実行ボタンを押す必要がある(詳細は後述)
表やグラフにするのが大変(←なのでテンプレ用意しました)
注意:基本は無料で使えるが、課金される場合も
この記事でご紹介する順位チェックツールは、下記の無料ツールを組み合わせて作ります。
Googleサーチコンソール
Googleアナリティクス
Google Apps Script
Google Looker Studio(旧データポータル)
Google BigQuery(GCP)
このうち、最後の BigQuery というのだけ「1ヶ月あたり1TBのクエリ・10GBのストレージ」という無料枠の上限があり、これを超えると費用が発生するので要注意です。特に10GBの保存容量はいつか超えるかもしれません。
とはいえ、ぼくのブログ(月間2万PVくらい)でおよそ100日分のデータを貯め込んだら170MBのストレージ使用だったので、このペースなら16年間は無料で使えそうです。
キーワード登録の要らない順位チェックツールの作り方
まずは前提条件
自身でブログやWEBサイトを運営している
Googleアナリティクスを埋め込んでいる
Googleサーチコンソールを開ける
Looker Studio(旧データポータル)を触っている(または独学で勉強できる)
自分のブログを持っていて、アナリティクスやサーチコンソールを覗ければOKです。
あと表やグラフは Looker Studio というツールを使うので、ここだけ自分で調べて操作できる方が対象となります。
※Looker Studio(旧データポータル)の全般的な操作方法は、このnoteでは解説していません。
自分で順位チェックツールを作る3ステップ
それでは、具体的な作り方を解説していきます。
おおまなか流れは次のとおりです。
データを貯める器を用意
毎日データを引っこ抜く仕組みを作成
引っこ抜いたデータを見やすく表・グラフにする
なお、そこそこボリュームのある作業なので、半日ほど時間を確保してから挑戦されるのがおすすめです。
ステップ1:データを貯める器を用意
サーチコンソールのデータを引っこ抜いて順位チェックツールを作るので、引っこ抜いたデータの置き場が必要です。
今回はGoogleの業務用サービス「GCP」を使って、引っこ抜いたデータを保管していきます。
なぜGCPかというと、次の特徴があるためです。
無料枠がある(毎月●●までなら無料で使える)
ステップ2で紹介する仕組みと簡単に接続できる
ステップ3で紹介する表・グラフ作成ツールと簡単に接続できる
手順1. GCPの利用登録
GCPは利用登録をしないと使えないので、まずは下記のページで利用登録を済ませてください。(ぼくのブログ記事になります)
はじめてのGCP。利用登録~最低限の初期設定まで|家内SEの仕事術
手順2. プロジェクトを作成
GCPは、何に使うかの用途ごとに「プロジェクト」を作って管理することができます。イメージとしては、メールのフォルダ分けやLINEグループみたいな感じです。
プロジェクトを作っておくと管理がしやすくなるので、順位チェックツール用のプロジェクトを作っておきましょう。
▼左上のココ↓をクリックします。

▼[新しいプロジェクト]をクリックします。

▼プロジェクト名(何でもOK。ここでは例として SearchPositionCheck)を入力して[作成]をクリックします。

▼プロジェクトが作成されたので[プロジェクトを選択]をクリックします。

▼左上のプロジェクト名が切り替わっていればOKです。
以降はいつでもココ↓からプロジェクトの切り替えができます。

▼いったんGCPのダッシュボードに行って、今回つくったプロジェクトの「プロジェクト番号」を控えておいてください。(ステップ2で使います)

手順3. BigQuery にテーブル(器)を作成
GCPには様々な機能がありますが、今回は「BigQuery」というデータ保存の機能を使います。
▼GCPの画面の左にメニューが並んでいるので、その中から「BigQuery」というのを探してクリックします。

▼BigQueryの画面になるので、図↓のように[3点(メニュー)]→[データセットを作成]とクリックします。

▼右側に入力画面が出るので
①データセット:なんでもOK。ここでは例として SearchConsoleData と入力
②データのロケーション:us-west1(オレゴン)
を入力し[データセットを作成]をクリックします。

▼データセットというモノができるので[3点]→[テーブルを作成]とクリックします。

▼右側に入力画面が出るので
①テーブル:なんでもOK。ここでは例として DailyData と入力
②[テキストとして編集]をクリック
と操作します。

▼「テキストとして編集」の下に文字入力の枠が出るので、下記をすべてコピー&貼り付けてください。
[
{
"mode": "NULLABLE",
"name": "date",
"type": "DATE"
},
{
"mode": "NULLABLE",
"name": "query",
"type": "STRING"
},
{
"mode": "NULLABLE",
"name": "url",
"type": "STRING"
},
{
"mode": "NULLABLE",
"name": "clicks",
"type": "INTEGER"
},
{
"mode": "NULLABLE",
"name": "impressions",
"type": "INTEGER"
},
{
"mode": "NULLABLE",
"name": "position",
"type": "FLOAT"
},
{
"mode": "NULLABLE",
"name": "ctr",
"type": "FLOAT"
},
{
"mode": "NULLABLE",
"name": "comparePosition",
"type": "FLOAT"
},
{
"mode": "NULLABLE",
"name": "compareImpressions",
"type": "FLOAT"
},
{
"mode": "NULLABLE",
"name": "compareClicks",
"type": "FLOAT"
},
{
"mode": "NULLABLE",
"name": "compareCtr",
"type": "FLOAT"
}
]

▼貼り付けが終わったら、残りの項目の
①パーティショニング:date
②パーティショニングタイプ:1日ごと
と選択して[テーブルを作成]をクリックします。

▼これでテーブル(データを貯める器)が完成です。
このあとのステップ2で使うので テーブル名(例:DailyData)→ 詳細 → テーブルID の文字をメモっておいてください。
(↓の画面を消さずに残しておくでもOK)

ステップ2:毎日データを引っこ抜く仕組みを作成
つづいて、毎日決まった時間にサーチコンソールからデータを引っこ抜いて、先程のテーブルにデータを貯める仕組みを作ります。
今回は GAS(Google Apps Script)という、無料でプログラムを動かせるサービスを使います。
また、サーチコンソール・GAS・GCP の3者でデータのやり取りができるように設定していきます。
手順1. サーチコンソールAPIを有効化
サーチコンソールのデータをプログラムから取得する入り口が存在するので、それをONにします。
▼サーチコンソールAPIの画面で[有効にする]をクリックします。

手順2. OAuth同意画面の作成
GAS と サーチコンソール・GCP との間でデータのやり取りをするために、OAuth同意画面というのを作ります。
OAuth同意画面とはこういうやつです。

この画面で「許可」を押すことで、ツール間でデータのやり取りができるようになります。
それでは早速作ってみましょう。
▼GCPの左側のメニューから[APIとサービス]→[OAuth同意画面]をクリックします。

▼[外部]→[作成]とクリックします。

▼次の箇所を入力して[保存して次へ]をクリックします。
①アプリ名:なんでもOK。例:サーチコンソール&BigQueryへの接続
②ユーザーサポートメール:自分のGmailアドレス
③メールアドレス:自分のGmailアドレス
※Gmailアドレスを複数持っている場合は、GCPやサーチコンソールで使っているGoogleアカウントと同じアドレスを入れてください。

▼何も入力せず[保存して次へ]をクリックします。

▼[+ADD USERS]をクリックして自分のGmailアドレスを登録したら[保存して次へ]をクリックします。

▼これでOAuth同意画面が完成です。

手順3. GASでプログラムを作成
サーチコンソール・GAS・GCP の3者でデータをやり取りする準備ができたので、実際にデータを引っこ抜くプログラムを作っていきます。
▼GAS のページを開いて[Start Scripting]をクリックします。

▼[新しいプロジェクト]をクリックします。

▼プログラムを入力する画面になるので、まずは最初からあるプログラムを消してまっさらにします。

▼次のテキストをすべてコピーして、さきほど文字を消した部分にペースト(貼り付け)します。
// 直近何日分を取得するか(3以上)
const days = 3;
//サーチコンソールから取得するドメイン名を定義
const siteDomain = "書き換えA";
// BigQuery設定
const bigQueryId = '書き換えB';
let projectId;
let datasetId;
let tableId;
function execute() {
projectId = bigQueryId.split('.')[0];
datasetId = bigQueryId.split('.')[1];
tableId = bigQueryId.split('.')[2];
// 開始日を取得
var startDate = new Date();
startDate.setDate(startDate.getDate() - days);
Logger.log('開始日:' + Utilities.formatDate( startDate, 'Asia/Tokyo', 'yyyy-MM-dd'));
// 終了日(3日前の日付)を取得 ※サーチコンソールから取れる最新は3日前までっぽい
var endDate = new Date();
endDate.setDate(endDate.getDate() - 3);
Logger.log('終了日:' + Utilities.formatDate( endDate, 'Asia/Tokyo', 'yyyy-MM-dd'));
do {
Logger.log('処理実行:' + Utilities.formatDate( startDate, 'Asia/Tokyo', 'yyyy-MM-dd') + '(' + String(Math.round(((new Date()) - startDate) / 1000 / 60 / 60 / 24)) + '日前)');
// サーチコンソールからデータ取得
let data = getSearchConsoleApi( startDate, startDate );
// 対象日の前日との変動率を追記
data = setComparisonByYesterday( data, startDate );
// BigQueryから対象日のデータをいったん削除
let sql = "DELETE FROM `" + projectId + "." + datasetId + "." + tableId + "` WHERE date = '" + Utilities.formatDate( startDate, 'Asia/Tokyo', 'yyyy-MM-dd') + "'";
runQuery( sql );
// BigQueryに登録
insertToTable(data);
// 開始日を1日加算
startDate.setDate(startDate.getDate() + 1);
} while (startDate.getTime() <= endDate.getTime());
}
// サーチコンソールからデータ取得
function getSearchConsoleApi( startDate, endDate ) {
//リクエストするAPIのURLを設定する
let apiURL = 'https://www.googleapis.com/webmasters/v3/sites/https%3A%2F%2F' + siteDomain + '%2F/searchAnalytics/query';
//サーチコンソールから取得する最大クエリ数を設定する
let maxQuery = 25000; // MAX設定(https://developers.google.com/webmaster-tools/search-console-api-original/v3/searchanalytics/query#rowLimit)
//APIリクエスト時にセットするペイロード値を設定する
let payload = {
'startDate' : Utilities.formatDate( startDate, 'Asia/Tokyo', 'yyyy-MM-dd'),
'endDate': Utilities.formatDate( endDate, 'Asia/Tokyo', 'yyyy-MM-dd'),
"dimensions" : ["page","query","date"],
"rowLimit" : maxQuery
};
//HTTPSのPOST時のオプションパラメータを設定する
let options = {
'payload' : JSON.stringify(payload),
'myamethod' : 'POST',
'muteHttpExceptions' : true,
'headers' : {"Authorization" : "Bearer " + ScriptApp.getOAuthToken()},
'contentType' : 'application/json'
};
//APIリクエストを行った結果のJSONデータを変換する
let response = UrlFetchApp.fetch(apiURL, options);
let json = JSON.parse(response);
Logger.log('サーチコンソール取得件数:' + json["rows"].length);
//JSONデータをJSONL形式に変換
let jsonl = [];
for (i=0;i<json["rows"].length;i++) {
jsonl[i] = {
date: json["rows"][i]["keys"][2],
query: json["rows"][i]["keys"][1],
url: json["rows"][i]["keys"][0],
clicks: json["rows"][i]["clicks"],
impressions : json["rows"][i]["impressions"],
position: json["rows"][i]["position"],
ctr: json["rows"][i]["ctr"]
};
}
// URL末尾に「#toc」とつくデータを除去(検索結果に表示されるページ内リンクなので、記事本体の評価だけで十分なため)
jsonl = jsonl.filter( value => value['url'].match(/\/#.*?$/) == null);
Logger.log('#toc除去後の件数:' + jsonl.length);
return jsonl;
}
// 対象日の前日との変動率を追記
function setComparisonByYesterday( data, startDate ) {
// 対象日の前日のデータを取得
let beforeDate = new Date(startDate.getFullYear(), startDate.getMonth(), startDate.getDate());
beforeDate.setDate(beforeDate.getDate() - 1);
let yesterdayData = getSearchConsoleApi( beforeDate, beforeDate );
// 対象日の前日との差分を計算してセット
let result = data.map( ( row, index ) => {
let yesterdayRow = yesterdayData.filter( value => {
return value['query'] === row['query'] && value['url'] === row['url']
});
if ( yesterdayRow.length > 0 ){
// 順位変動
row['comparePosition'] = row['position'] - yesterdayRow[0]['position'];
// 表示回数
row['compareImpressions'] = (row['impressions'] / yesterdayRow[0]['impressions']) - 1;
// クリック数
row['compareClicks'] = (row['clicks'] / yesterdayRow[0]['clicks']) - 1;
// CTR
row['compareCtr'] = row['ctr'] - yesterdayRow[0]['ctr'];
}
return row;
});
return result;
}
// BigQueryでSQL実行
function runQuery(sql) {
let result = BigQuery.Jobs.query(
{
useLegacySql: false,
query: sql,
},
projectId
);
if ( typeof result.rows === "undefined" ) return [];
// カラム名取得
let colmuns = result.schema.fields.map(value => {
return value.name
});
// 行データ取得
let rows = result.rows.map(row => {
return row.f.map(cell => cell.v)
});
// 連想配列に変換
let data = rows.map(row => {
var array = {};
for(i=0; i<colmuns.length; i++){
array[colmuns[i]] = row[i];
}
return array;
});
return data;
}
// BigQueryに登録
function insertToTable(jsonl) {
const data = Utilities.newBlob(jsonl.map(o => JSON.stringify(o)).join('\n'));
BigQuery.Jobs.insert({
configuration: {
load: {
destinationTable: { projectId, datasetId, tableId },
sourceFormat: 'NEWLINE_DELIMITED_JSON'
}
}
}, projectId, data);
}

▼貼り付けたら、5行目、8行目の「書き換え」の部分を次のように書き換えます。注意点として「’」の記号は消さないで、’ と ‘ で文字を囲うように書き換えます。
書き換えA:順位チェックするブログのドメイン
書き換えB:ステップ1の最後に登場した「テーブルID」
こんな感じになればOKです。

▼つづいて、サーチコンソール・GCPとの接続設定をします。
左側の[プロジェクトの設定]をクリックします。

▼①のチェックを入れて[プロジェクトを変更]をクリックします。

▼ステップ1で控えた「プロジェクト番号」を入力して プロジェクトを設定 をクリックします。

▼こんな感じになればOKです。

▼つづいて、左側の[エディタ]をクリックします。

▼[appsscript.json]をクリックします。

▼はじめから何か書いてあるので、いったんすべて消します。

▼消したら、下記のテキストをすべてコピー&貼り付けます。
{
"timeZone": "Asia/Tokyo",
"dependencies": {
"enabledAdvancedServices": [
{
"userSymbol": "BigQuery",
"version": "v2",
"serviceId": "bigquery"
}
]
},
"exceptionLogging": "STACKDRIVER",
"oauthScopes": [
"https://www.googleapis.com/auth/webmasters",
"https://www.googleapis.com/auth/script.external_request",
"https://www.googleapis.com/auth/bigquery"
],
"runtimeVersion": "V8"
}

▼これでプログラムの用意ができたので、フロッピーアイコン(保存)をクリックして保存します。

▼ちゃんと動くか一度テストしてみましょう。
[コード.gs]→ ②の部分で「execute」を選んで →[実行]をクリックします。

▼初回実行時は、ツール間でデータのやり取りをしてよいかの許可を求められます。図のようにどんどんOKで進んでください。




▼下の方に「お知らせ 実行完了」と出れば成功です。
※もしエラーになったら、もう一度「手順3. GASでプログラムを作成」を見直したり、やり直したりしてみてください。

▼ステップ1で作成したBigQueryのテーブルでプレビューをクリックすると、サーチコンソールから引っこ抜いたデータが入っているのが確認できます。

手順4. 自動で毎日実行するようにタイマーを設定
プログラムが完成したので、夜間など毎日実行するようにセットしておくと、常に最新の情報で順位チェックできます。
▼左側の[トリガー]をクリックします。

▼[トリガーを追加]をクリックします。

▼①タイプを「日付ベースのタイマー」、②時刻を「午前0時~1時」とセットして[保存]をクリックします。
※②はお好きな時間帯でもOKです。

▼これでトリガー(自動実行タイマー)がセットされました。

▼さいごに、今回つくった「プログラム+実行タイマー」に分かりやすい名前を付けておきましょう。
「無題のプロジェクト」の部分をクリックすると名前を変えられます。

以上で、毎日夜間にサーチコンソールのデータを引っこ抜いてGCP(BigQuery)に保存する仕掛けが完成です。
ここで1つ注意点がありまして、基本は毎晩自動で動いてくれますが、権限の関係で7日ごとに手動で[実行]ボタンを押す必要があります。

上記のようなメールが届くので、そしたら改めてGASの画面を開いて[実行]ボタンを押してください。

※上記の他、たまにタイマー実行に失敗するとこんなメール↓が届くので、そしたらプログラムのページを開いて手動で[実行]ボタンを押し直してみてください。(実行ボタンは何度押しても問題ありません)

いちおう↑の原因ですが、サーチコンソール側でまだ集計中でデータが整っていないときにエラーになります。
サーチコンソールで検索パフォーマンスを見たときに、↓のような表記だとまだ集計中なので、集計が終わったら[実行]をリトライしてみてください。

手順5. ひとまず過去90日分のデータを引っこ抜く
仕組みはできたものの、ある程度データが集まらないと順位チェックできません。そこで、ひとまず過去90日分のデータをまとめて引っこ抜いておきましょう。
▼GASのプログラムの2行目の「3」という数字を「90」に書き換えて、上の実行ボタンをクリックします。
すこし時間は掛かりますが、過去90日分のデータ取得&BigQueryにデータ保存されます。

取得が完了したら、また数字を3に戻して保存(フロッピーアイコン)を押しておいてください。
※下図のようにタイムアウトになった場合は、「処理実行:○○○○-○○-○○(●日前)」と書いてある部分を探します。
この図では36日前とあり、36日前の処理中に中断したことが分かるので、プログラム2行目の数字を「36」と書いて[実行]ボタンを押すと再開できます。

ステップ3:引っこ抜いたデータを見やすく表・グラフにする
サーチコンソールの生データをゲットできたので、最後に表やグラフで見やすくしましょう。
今回は、ブラウザ上でかんたんに表やグラフを作れる無料ツール「Google Looker Studio」(旧データポータル)を使います。
▼Looker Studio を開いて[無料で利用する]をクリックします。

▼[作成]→[レポート]とクリックします。

▼初回だけ設定が必要なので、次のように入力して[続行]をクリックします。
①国:日本
②利用規約:チェック

▼おすすめメール等を送ってよいかと出るので、好きな方を選択してください。

▼つづしてデータ接続という画面が出るので[BigQuery]をクリックします。

▼[承認]をクリックします。

▼ステップ1で作ったテーブルを選択し、④分割表にチェックを入れて[追加]をクリックします。

▼すると、GCP(BiqQuery)に入れたデータを読み込んで、表やグラフにすることができます。

あとは Looker Studio 上で見た目を整えていくのですが、ここが最大の山場で、ぼくも1ヶ月くらい掛かりました。。
そして、1つ1つ手順を解説するととんでもない文量になってしまうので、すみませんが詳細は割愛させていただきます。
ですがここまでやったら、サーチコンソールのデータを引っこ抜いて表・グラフにする環境までは整ったので、がんばって自分好みの表・グラフに仕上げてみてください!
とはいえ「そんな時間無いよ」という方は、有料ではありますが冒頭のレポートを再現できるテンプレートを用意しましたのでご活用ください。
お値段の方は、順位チェックツールとして定番の「GRC」の3ヶ月分なので、4ヶ月以上使うのならテンプレートの方がお得です。(本テンプレートは買い切りです)
有料テンプレートの前提条件
本noteのステップ1・ステップ2をすべて完了している
Googleアナリティクスは旧(UA)ではなく新(GA4)を使いますので、すでにGA4を利用している
Looker Studio(旧データポータル)の基本的な操作ができる、または自分で調べて扱える
※上記の準備ができていない方はお金のムダになってしまうので、購入はお控えください。
※もし購入後に「思ってたのと違う…」となったら、noteの返金機能で24時間以内であれば返金を受け付けています。
ここから先は
¥ 1,490
この記事が気に入ったらチップで応援してみませんか?