note.nkmk.me

Google Analytics APIでページ別・日別のPV・AdSense収益などを取得

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

Googleアナリティクス Reporting APIを使うとページ別や日別のPV(アクセス数)やユーザー数、直帰率、離脱率、平均ページ滞在時間、AdSense収益・クリック数などが取得できる。

GoogleアナリティクスのページからExcelやCSVなどの形式でエクスポートすることもできるが、最大で5000行ずつという制限がある。大量のデータをまとめてダウンロードする場合はAPIを使うと便利。

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

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

Search Console APIについては以下の記事を参照。

スポンサーリンク

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

Google公式のドキュメントおよびチュートリアルが非常に充実している。日本語。

まずはこのページに従ってサンプルを実行するといい。

Pythonのサンプルとしては、

  • サービス アプリケーション
  • インストール済みアプリケーション

の2つがあるが、自サイトのデータをダウンロードする場合は「サービス アプリケーション」のほうが簡単だと思う。

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

プロジェクトやアカウントなどの設定は以下のような流れ。

  • Google API Consoleでプロジェクトを作成
    • 既存のプロジェクトを使うことも可能
  • セットアップツールでReporting APIをプロジェクトに登録
    • そのままウィザードに従って認証情報を作成することもできるが、一旦キャンセルしてからサービスアカウントを作成したほうが分かりやすい
  • サービスアカウントを作成
    • サービスアカウントのページからサービスアカウントを作成
    • 認証情報を含むJSONファイルがダウンロードされる
  • Google アナリティクス アカウントにサービス アカウントを追加
    • Googleアナリティクス管理から対象のビューを開き、ユーザー管理者+ボタンから新しいユーザーを追加
    • サービスアカウントのメールアドレスを追加する

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

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

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

公式のサンプルコードの実行

公式のサンプルコードで動作確認する。

以下の修正が必要。

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

エラーなく実行できれば諸々の設定はOK。

Googleアナリティクス Reporting APIの基本的な使い方

基本的な流れ

公式のサンプルコードを見ると分かる通り、Googleのクライアントライブラリを使う場合、

  • ServiceAccountCredentials.from_json_keyfile_name()でJSONファイルからCredentials(資格情報)を抽出
  • Credentialsをもとにapiclient.discovery.build()でサービスオブジェクトを作成
  • サービスオブジェクトからreports().batchGet().execute()でデータ取得

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

リクエストの設定はbatchGet()の引数bodyに辞書(dict型オブジェクト)で指定する。

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

レスポンスの値はすべて文字列なので注意。

dimensionsとmetrics

リクエスト設定のなかで重要なのがdimensionsmetrics。これらを指定することで所望のデータを取得できる。

  • dimensions
    • ページURLや日付、地名など
    • 最大7つまで
  • metrics
    • PVやユーザー数、平均ページ滞在時間、AdSense収益・クリック数など
    • 最大10つまで

dimensionsmetricsの種類は以下のページから検索できる。

複数指定する場合は、以下のように辞書のリストを指定する。

'dimensions': [{'name': 'ga:pagePath'}, {'name': 'ga:date'}],
'metrics': [{'expression': 'ga:pageviews'}, {'expression': 'ga:avgTimeOnPage'}]

ページネーション

デフォルトでは1000行のデータが取得できる。

リクエストでpageSizeを指定するとその行数分のデータが一気に取得できる。リファレンスには「最大10,000 行」と書いてあったが、それ以上の値(例えば100000)を指定してみると20000行程度のデータが取得できた。仕様がいまいちよくわからない。

pageSizeを超えたデータが存在する場合、レスポンスのdatanextPageTokenが指定され、その値をリクエストのpageTokenに指定すると続きのデータが取得可能。

辞書のget()メソッドを使うと、nextPageTokenがある場合にはその値、ない場合にはNoneを取得できる。

response['reports'][0]['data'].get('nextPageToken')

サンプリング

データ数が多いと自動的にサンプリングされてデータが省略される場合がある。

50万セッションがしきい値のようで、それ以上だとデータが間引かれる。リクエストの設定samplingLevelで精度を指定できるが、必ずすべてのデータを取得できるわけではない。サンプリングされるのを避けるためには適当に期間を区切ってリクエストする必要がある。

サンプリングされた場合はレスポンスのdatasamplesReadCountssamplingSpaceSizesが含まれる。サンプリングされていない場合はそれらのキーがないので、そこを確認すればサンプリングされているかどうかを判別可能。

辞書のget()メソッドを使うと、samplesReadCountsなどがある場合にはその値、ない場合にはNoneを取得できる。

response['reports'][0]['data'].get('samplesReadCounts')

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

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

上述のように、厳密にはページネーションやサンプリングを考慮する必要があるが、以下は期間とdimensionsmetricsなどを指定してレスポンスをpandas.DataFrameに変換、CSVとして保存するシンプルなもの。

import pandas as pd

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

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

credentials = ServiceAccountCredentials.from_json_keyfile_name(KEY_FILE_LOCATION, SCOPES)
analytics = build('analyticsreporting', 'v4', credentials=credentials)

m_list = ['users', 'sessions', 'pageviews', 'bounceRate', 'exitRate', 'avgTimeOnPage',
          'adsenseRevenue', 'adsenseAdsClicks', 'adsenseViewableImpressionPercent']
d_list = ['pagePath', 'date']

metrics = [{'expression': 'ga:' + m} for m in m_list]
dimensions = [{'name': 'ga:' + d} for d in d_list]

start_date = '2018-07-01'
end_date = '2018-07-31'
page_size = 100000
sampling_level = 'LARGE'

body = {
    'reportRequests': [
        {
            'viewId': VIEW_ID,
            'dateRanges': [{'startDate': start_date, 'endDate': end_date}],
            'metrics': metrics,
            'dimensions': dimensions,
            'pageSize': page_size,
            'samplingLevel': sampling_level
        }
    ]
}

response = analytics.reports().batchGet(body=body).execute()

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

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

for i, m in enumerate(m_list):
    df[m] = df['metrics'].apply(lambda x: x[0]['values'][i])

df.drop(columns=['dimensions', 'metrics'], inplace=True)

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

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

レスポンスのrowsは以下のような辞書になっている。d0, m0は結果の値。

{'dimensions': [d0, d1, d2...],
 'metrics': [{'values': [m0, m1, m2...]}]}

これをpd.io.json.json_normalize()で変換すると、dimensionsmetricsの二つの列のpandas.DataFrameとなる。

dimensions列の要素はリスト[d0, d1, d2...]metrics列の要素は[{'values': [m0, m1, m2...]}]となるため、apply()メソッドでそれぞれの結果を新たな列として取り出し、そのあとでdimensionsmetricsの二つの列を削除している。

上述のように結果の値はすべて文字列。pandas.DataFrameをそのまま処理する場合はastype()でデータ型を変更する必要がある。

to_csv()でCSVファイルとして保存したあとでread_csv()で読み込むと数値として読み込まれる。

dimensionsに日付dateを指定したときの結果は20180101のようなYYYYMMDD形式になる。これをpd.to_datetime()で変換する場合は引数formatを指定する必要があるので注意。

df['date'] = pd.to_datetime(df['date'], format='%Y%m%d')

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

なお、サンプルコードではAdSenseの収益adsenseRevenueやクリック数adsenseAdsClicksなどを取得するようにしているが、これはAdSenseとAnalyticsを連携しておく必要がある。

AdSenseとAnalyticsの連携設定はGoogleアナリティクスのサイトの管理、プロパティのAdSenseのリンク設定から行う。Googleアナリティクスのサイトの行動サイト運営者サイト運営者のページサイト運営者の収益などの項目が表示されていれば連携できている。

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

関連カテゴリー

関連記事