アナリティクス Reporting API v4を使ってGoogle Analyticsのデータを取得する

2020.10.22

はじめに

データアナリティクス事業本部のkobayashiです。

Google AnalyticsのデータをPythonで扱う必要があったのでその手順を調べました。弊社ブログにもその設定方法があったのですが、データを取得するGoogle Analytics APIのバージョンがV4になっていたので改めて方法を調べましたのでその内容をまとめます。

Google アナリティクス Core Reporting API バージョン 3.0 を使った取得方法はこちらになります。

環境

  • macOS Mojave
  • Python 3.7.4

Google Analytics APIでデータを取得する手順

Analytics APIを使ってGoogle Analyticsのデータを取得するには、

  • Analytics APIの設定を行う
  • クライアントライブラリをインストールする
  • Pythonでコードを記述し実行する

となります。

では初めに設定を行います。

Analytics API を使う準備

Analytics API V4を使うにはまず以下の設定が必要になります。

  • GCP上に新規プロジェクト作成(または既存のプロジェクトがあればそれでもOK)
  • GCPプロジェクトに対してAPIを有効にする
  • GCP上でAPI用のサービスアカウントを作り鍵をJSON形式で作成する
  • サービスアカウントを作成した際にサービスアカウントIDをGoogleAnalitycsへユーザー登録する。

今回は既存のGCPプロジェクトで設定を行っていくのでGCPプロジェクト作成は割愛いたします。

GCPでAnalytics APIを有効化する

手順1)GCPにログインしAPIとサービスへ進み、ライブラリを押下する。

手順2)検索フォームにAnalyticsと打ち込みGoogle Analytics Reporting APIを検索し、ライブラリの画面で有効にするを押下してライブラリを有効化する。

GCPでサービスアカウントを作成後鍵をダウンロードする

手順1)IAMと管理サービスアカウントと進み、サービスアカウントを作成を押下する。

手順2)モーダルが表示されるのでサービスアカウントとサービスアカウントIDに適当な値を入力し、完了を押下してサービスアカントを作成する。

手順3)作成したサービスアカウントの詳細画面に進み、鍵を追加を押下してサービスアカウント用のJSON形式の鍵を作成する。

ここでダウンロードできる鍵は再作成できないのとこの鍵があれば権限が与えられたGCPサービスを使えてしまうので厳重に管理します。

Google Analyticsでサービスアカウント用のユーザーに権限を与える

手順1)ユーザー管理の権限を持ったアカウントでGoogle Analyticsにログインし、メニューから管理を押下する。

手順2)アカウントユーザーの管理を押下する。

手順3)右上の+を選択し、ユーザーを追加を押下する。

手順4)先ほど作成したサービスアカウントのサービスアカウントIDをメールアドレスに入力する。権限はデータを取得するだけなので表示と分析にする。

ここまでの手順を行うと下図の様になります。

これでサービスアカウントに対してGoogle Analyticsでデータを取得できるようになりましたので設定は終わりです。

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

pipを使ってインストールできますので下記のコマンドを実行します。

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

以上で準備が整ったので実際にデータを取得するコードを記述します。

Analytics APIを使ってデータを取得する

アナリティクス Reporting API v4のドキュメント にサンプルコードが記載されていますが、以下のようなコードにします。

from googleapiclient.discovery import build
# oauth2clientからgoogle-auth-library-pythonへ変更
from google.oauth2 import service_account
from pprint import pprint

SCOPES = ["https://www.googleapis.com/auth/analytics.readonly"]
KEY_FILE_LOCATION = '<REPLACE_WITH_JSON_FILE>'
VIEW_ID = '<REPLACE_WITH_VIEW_ID>'


# サービスアカウントキーファイルを使用した認証
def initialize_analytics_reporting():
    credentials = service_account.Credentials.from_service_account_file(KEY_FILE_LOCATION)
    scoped_credentials = credentials.with_scopes(SCOPES)
    return build("analyticsreporting", "v4", credentials=scoped_credentials)


def get_report(analytics, next_page_token="0"):
    request_body = {
        "reportRequests": [{
            "viewId": VIEW_ID,
            "pageSize": 100000,
            "pageToken": next_page_token,
            "dateRanges": [{'startDate': '7daysAgo', 'endDate': 'today'}],
            "metrics": [{"expression": "ga:pageviews"}],
            "dimensions": [{"name": "ga:pagePath"}, {"name": "ga:pageTitle"}],
            "orderBys": [{"fieldName": "ga:pageviews", "sortOrder": "DESCENDING"}]
        }]
    }
    return analytics.reports().batchGet(body=request_body).execute()


def get_response(response):
    rows = []
    for report in response.get("reports", []):
        column_header = report.get("columnHeader", {})
        dimension_headers = column_header.get("dimensions", [])
        metric_headers = column_header.get("metricHeader", {}).get("metricHeaderEntries", [])
        next_page_token = report.get('nextPageToken')

        for row in report.get("data", {}).get("rows", []):
            row_data = {}
            dimensions = row.get("dimensions", [])
            date_range_values = row.get("metrics", [])
            for header, dimension in zip(dimension_headers, dimensions):
                row_data[header] = dimension
            for i, values in enumerate(date_range_values):
                for metricHeader, value in zip(metric_headers, values.get("values")):
                    row_data[metricHeader.get("name")] = value
            rows.append(row_data)
    return rows, next_page_token


def print_response(analytics):
    next_page_token = "0"
    rows = []
    while next_page_token is not None:
        response = get_report(analytics, next_page_token)
        r, next_page_token = print_response(response)
        rows.extend(r)

    pprint(rows)


def main():
    analytics = initialize_analytics_reporting()
    print_response(analytics)


if __name__ == "__main__":
    main()

サンプルコードからの主な変更ポイントとしては以下になります。

  • サービスアカウントキーファイルを使用した認証をサンプルコード内で使用されているoauth2client のモジュールがメンテされいていないの google-auth-library-python へ変更
  • reports.batchGetメソッド のリクエストでデータを全件取得するためpageSizepageTokenを使用
    • pageSizeは指定しないと1000なのでリクエストの最大値の100000にする
    • pageTokenpageSizeで指定した値以上の件数がある場合にページングで次のデータを取得する
  • リクエストでpageTokenを使っているのでリクエストをprint_responseのループ内で行っている

実際にこのコードを実行してDevelopers.IOのデータを取得すると以下の様になります。

{
  'ga:pagePath': '/',
  'ga:pageTitle': 'クラスメソッド発「やってみた」系技術メディア | Developers.IO',
  'ga:pageviews': 'xxxxxxxxxx'
},
{
  'ga:pagePath': '/articles/iphone_simplified_chart/',
  'ga:pageTitle': '[iPhone] 歴代iPhone早見表をまとめてみました(2020年前期時点) | Developers.IO',
  'ga:pageviews': 'xxxxxxxxxx'
},
{
  'ga:pagePath': '/articles/visualize-the-biggest-aeon-mall-with-alteryx-and-tableau/',
  'ga:pageTitle': '「イオンモールの総賃貸面積ランキング」ダッシュボードをノンコーディングで作ってみた #tableau #alteryx | Developers.IO',
  'ga:pageviews': 'xxxxxxxxxx'
},
{
  'ga:pagePath': '/articles/introduction-of-one-observability-demo-workshop/',
  'ga:pageTitle': '3〜4時間でAWSの監視系のサービス一気に学べたらコスパ良いと思いませんか | Developers.IO',
  'ga:pageviews': 'xxxxxxxxxx'
},
...

概ね上記のコードで必要なデータを取得して加工する事はできると思いますので後は取得したいディメンションとメトリックスのフィールドを下記のリンクから欲しい内容に書き換えて利用すればよいかと思います。

まとめ

Google AnalyticsのデータをAnalytics API V4を使って取得してみました。Core Reporting API v3と使い方の流れは変わっていませんが今後の新機能の開発はV4で実装されていくので、新しくAnalytics APIを使う場合はV4を使うようにしたほうが恩恵を受けられるでしょう。

最後まで読んで頂いてありがとうございました。