note.nkmk.me

Search Console APIで検索クエリ別・日別の検索順位・クリック数を取得

Date: 2018-08-19 / tags: Python, Web API

GoogleのSearch Console APIを使うと、検索クエリ別や日別の検索順位やクリック数、表示回数などが取得できる。

Web上のサーチコンソールでは最大1000件の検索クエリしか取得できないが、APIを使うと最大5000件の検索クエリが取得可能。

ここではPythonを使った例を紹介する。

  • 公式のドキュメント・チュートリアル
    • プロジェクト・アカウントなどの設定
    • Pythonのクライアントライブラリのインストール
    • サンプルコードの実行
  • Search Console APIの基本的な使い方
    • 基本的な流れ
    • dimensions
    • ページネーション
    • データの不一致
  • データをCSVで保存するサンプルコード

Google Analytics APIについては以下の記事を参照。

スポンサーリンク

公式のドキュメント・チュートリアル

公式のドキュメントは以下。

公式のクイックスタートガイドには書かれていないが、Google Analytics APIと同様にサービスアカウントを使った認証も可能。

ここではサービスアカウントを使うプロセスについて説明する。

プロジェクト・アカウントなどの設定

プロジェクトやアカウントなどの設定は以下のような流れ。基本的にはGoogle Analytics APIと同じ。

  • Google API Consoleでプロジェクトを作成
    • 既存のプロジェクトを使うことも可能
  • セットアップツールでSearch ConIole をプロジェクトに登録
    • そのままウィザードに従って認証情報を作成することもできるが、一旦キャンセルしてからサービスアカウントを作成したほうが分かりやすい
  • サービスアカウントを作成
    • サービスアカウントのページからサービスアカウントを作成
    • 認証情報を含むJSONファイルがダウンロードされる
  • サーチコンソールアカウントにサービス アカウントを追加
    • Search Consoleのホームから対象のプロパティのプロパティの管理ユーザーを追加/削除新しいユーザーを追加
    • サービスアカウントのメールアドレスを追加する
    • データを取得するだけであれば権限制限付きでOK

Pythonのクライアントライブラリのインストール

Google謹製のクライアントライブラリをインストールする。インストールされている場合も--upgradeで最新版にアップデートしておく。

$ pip install --upgrade google-api-python-client

サンプルコードの実行

以下のコードのスクリプトを作成する。

from apiclient.discovery import build
from oauth2client.service_account import ServiceAccountCredentials

SCOPES = ['https://www.googleapis.com/auth/webmasters.readonly']
KEY_FILE_LOCATION = '<REPLACE_WITH_JSON_FILE>'

credentials = ServiceAccountCredentials.from_json_keyfile_name(KEY_FILE_LOCATION, SCOPES)
webmasters = build('webmasters', 'v3', credentials=credentials)

print(webmasters.sites().list().execute())

以下の修正が必要。

  • <REPLACE_WITH_JSON_FILE>をJSONファイルへのパスに変更
    • サービスアカウント作成時にダウンロードされたJSONファイルへのパスを指定する
    • JSONファイルをスクリプトファイルと同じディレクトリに置いておく場合は<REPLACE_WITH_JSON_FILE>をファイル名(xxxxx.json)に置き換えればOK

エラーなく実行できれば諸々の設定はOK。以下のような出力がされる。

{'siteEntry': [{'siteUrl': 'https://xxxxx/', 'permissionLevel': 'siteRestrictedUser'}]}

Search Console APIの基本的な使い方

基本的な流れ

Googleのクライアントライブラリを使う場合、

  • ServiceAccountCredentials.from_json_keyfile_name()でJSONファイルからCredentials(資格情報)を抽出
  • Credentialsをもとにapiclient.discovery.build()でサービスオブジェクトを作成
  • サービスオブジェクトから処理を呼び出し実行

という非常にシンプルな流れになる。

上のサンプルではサービスオブジェクトのsites().list().execute()でURLを確認したが、データを取得する場合はsearchanalytics().query().execute()を使う。

query()の引数siteUrlに対象のプロパティのURL、同じくquery()の引数bodyにリクエストの設定を辞書(dict型オブジェクト)で指定する。

dimensionsについては後述。

{
  "startDate": string,
  "endDate": string,
  "dimensions": [
    string
  ],
  ...
  "rowLimit": integer,
  "startRow": integer
}

レスポンスとして、クリック数(clicks)、表示回数(impressions)、CTR(ctr)、掲載順位(position)が返る。

{
  "rows": [
    {
      "keys": [
        string
      ],
      "clicks": double,
      "impressions": double,
      "ctr": double,
      "position": double
    }
  ],
  "responseAggregationType": string
}

リクエストおよびレスポンスの詳細は以下の公式ドキュメントを参照。

query()を使ったサンプルコードについては後述。

dimensions

リクエストの設定でdimensionsを指定する。

dimensionsはWeb上のサーチコンソールの検索パフォーマンス(旧バージョンでは検索アナリティクス)で選択できる分類に対応し、それぞれ以下の文字列で指定する。

  • クエリ: query
  • ページ: page
  • 国: country
  • デバイス: device
  • 検索での見え方: searchAppearance
  • 日付: date

複数のdimensionsを指定する場合はリストを使う。

'dimensions': ['query', 'page']

ページネーション

一度のリクエストで取得できるのは最大25000行(デフォルト1000行)。

Max行数は'rowLimit'で指定し、オフセットは'startRow'で指定する。

例えば、最初の25000件を取得する場合は以下の設定(startRowはデフォルトが0なのでこの場合は省略可能)。

'rowLimit': 25000,
'startRow': 0

続く25000件を取得する場合は以下の設定。

'rowLimit': 25000,
'startRow': 25000

詳細は以下の公式ドキュメントを参照

なお、dimensionsqueryとしたときに取得できる最大行数は5000行。公式のドキュメントやリファレンスのどこに書いてあるか分からなかったが、rowLimit25000に設定しても5000行分しか返ってこない(2018/08/19時点)。

データの不一致

dimensionsdatepageとするかqueryとするかで、同じ期間でもクリック数や表示回数の合計が異なる。

これは、queryではすべての検索クエリが抽出されるわけではないのが原因。

グループ化の対象となるのは、検索結果にサイトが返された検索のみです。非常に珍しいクエリは、ユーザーのプライバシー保護のため表示されません。
検索アナリティクス レポート - Search Console ヘルプ

Googleアナリティクスの集客Search Console検索クエリでは、抽出されなかった検索クエリがまとめてotherとして表示されているが、Search Consle上では非表示。Search Console APIでもotherという項目は取得できない。

データをCSVで保存するサンプルコード

pandasを使ってデータをCSVファイルで保存するサンプルコードを示す。

import pandas as pd

from apiclient.discovery import build
from oauth2client.service_account import ServiceAccountCredentials

SCOPES = ['https://www.googleapis.com/auth/webmasters.readonly']
KEY_FILE_LOCATION = '<REPLACE_WITH_JSON_FILE>'

credentials = ServiceAccountCredentials.from_json_keyfile_name(KEY_FILE_LOCATION, SCOPES)
webmasters = build('webmasters', 'v3', credentials=credentials)

url = '<REPLACE_WITH_SITE_URL>'
d_list = ['query', 'page']
start_date = '2018-07-01'
end_date = '2018-07-01'
row_limit = 25000

body = {
    'startDate': start_date,
    'endDate': end_date,
    'dimensions': d_list,
    'rowLimit': row_limit
}

response = webmasters.searchanalytics().query(siteUrl=url, body=body).execute()

df = pd.io.json.json_normalize(response['rows'])

for i, d in enumerate(d_list):
    df[d] = df['keys'].apply(lambda x: x[i])

df.drop(columns='keys', inplace=True)

df.to_csv('{}.csv'.format(start_date), index=False)

出力行が格納されているresponse['rows']pd.io.json.json_normalize()pandas.DataFrameに変換している。

rowsの中のkeysdimensionsごとの値がリストで格納されているので、apply()メソッドでそれぞれの値を新たな列として取り出し、そのあとでkeys列を削除している。

最後にto_csv()でCSVファイルとして保存。

複数ディメンションを指定した場合はgroupby()を使うと各ディメンションごとに集約して合計や平均が算出できて便利。

スポンサーリンク
シェア
このエントリーをはてなブックマークに追加

関連カテゴリー

関連記事