GA4|Google Analytics 4のデータをPythonで取得する
はじめに
Google Analytics 4のデータをpythonで処理したいなーと思い、Analytics Data APIを使ってみました。使ってみて思ったことをまとめたので、このAPIを利用する参考になれば幸いです。
使用したコードこちらからダウンロードできます.
まずは使ってみる
準備
公式のクイックスタートに沿って以下の準備を行います。
<手順1> Google Analytics Data APIを有効にする
クイックスタートのページの[Enable the Google Analytics Data API v1]というボタンを押し、GCPプロジェクトを新規作成します。
このとき同時に認証用のJSONファイルがダウンロードをダウンロードしておきます。
<手順2> サービスアカウントにGA4のユーザーに追加
先ほどダウンロードした認証用のJSONファイルを開くと、client_email
の項目からサービスアカウントが確認できます。
次にGA4にアクセスし、[管理 > プロパティのアクセス管理]の項目からサービスアカウントを新規ユーザーに追加し、閲覧権限以上の権限を与えてください。
<手順3> クライアント向けライブラリのインストール
以下のコマンドを実行し、クライアントライブラリをインストールします。
pip install google-api-python-client
pip install google-analytics-data
以上で、準備は完了です。
アクティブユーザー数の推移を取得する
日付毎にアクティブユーザー数を取得するプログラムは次のようになります(公式ドキュメントのサンプルを参考にしています)
"""アクティブユーザーの日次推移を取得するプログラム"""
from google.analytics.data_v1beta import BetaAnalyticsDataClient
from google.analytics.data_v1beta.types import DateRange
from google.analytics.data_v1beta.types import Dimension
from google.analytics.data_v1beta.types import Metric
from google.analytics.data_v1beta.types import RunReportRequest
import os
# アカウント設定
# credential.jsonを/credentialに保存 && GA4 プロパティIDを設定
os.environ['GOOGLE_APPLICATION_CREDENTIALS'] = 'credential/credential.json'
GA_PROPERTY_ID = {YOUR GA4 PROPERTY ID}
def sample_run_report(property_id=GA_PROPERTY_ID):
client = BetaAnalyticsDataClient()
request = RunReportRequest(
property=f"properties/{GA_PROPERTY_ID}",
dimensions=[Dimension(name="date")],
metrics=[Metric(name="activeUsers")],
date_ranges=[DateRange(start_date="28daysAgo", end_date="yesterday")],
)
response = client.run_report(request)
for row in response.rows:
print(row)
if __name__ == '__main__':
sample_run_report()
実行結果を見ると、各行が次のような形で取得できていることがわかります。
{
dimension_values: [{value: "20221021"}],
metric_values: [{value: "19"}],
}
コードの説明
RunReportRequest
のパラメータのうち、使用頻度の高いものを挙げておきます。
パラメータ | 意味 |
---|---|
property |
プロパティ ID。properties/{property ID} の形で指定します |
dimensions |
ディメンション(リスト) (詳しいディメンション・指標名はAPI Dimensions & Metrics) |
metrics |
指標(リスト) |
dateRanges |
データ取得期間 |
dimensionFilter |
ディメンションのフィルタを指定します |
その他のオプションについてはこちらから確認できます。
使い方に関するTips
ここでは、Analytics Data APIを使う際に役立ちそうなことを紹介します。
フィルタ
指定した条件を満たすデータに対象を絞って集計できます。
次のリクエストは、トップページ(パスが'/'に一致)を訪れたアクティブユーザー数のデータを取得します。
request = RunReportRequest(
property=f"properties/{GA_PROPERTY_ID}",
dimensions=[Dimension(name="date")],
metrics=[Metric(name="activeUsers")],
date_ranges=[DateRange(start_date="7daysAgo", end_date="yesterday")],
dimension_filter=FilterExpression(
filter=Filter(
field_name="pagePath",
string_filter=Filter.StringFilter(value="/"),
)
)
)
文字列の条件はFilter
オブジェクトのパラメータで指定できます。
パラメータ | 説明 | 例 |
---|---|---|
string_filter |
完全一致 |
Filter.StringFilter(value='/') トップページ(パス /)のみ集計 |
string_filter |
前方一致 |
Filter.StringFilter(match_type='BEGINS_WITH', value='/products')) /productsで始まるパスのみ集計 |
string_filter |
前方一致 |
Filter.StringFilter(match_type='ENDS_WITH', value='/thanks')) /thanksで終わるパスのみ集計 |
string_filter |
部分一致 |
Filter.StringFilter(match_type='CONTAINS', value='2022')) 2022を含むパスのみ集計 |
string_filter |
正規表現一致 |
Filter.StringFilter(match_type='PARTIAL_REGEXP', value='products.*detail')) 'products.*detail'に正規表現一致するパスのみ集計 |
in_list_filter |
リスト |
Filter.InListFilter(values=['/aaa', '/bbb'])) '/aaa'または'/bbb'に一致するパスのみ集計 |
さらに詳しいフィルタ指定についてはこちら
取得した結果をデータフレームに加工する
実際の用途を考えると、runReport
から取得したデータをデータフレームに加工したい場面が多いと思います。
そこで次のようなクラスを用意して、より簡潔に書けるでしょう:
from google.analytics.data_v1beta.types import DateRange
from google.analytics.data_v1beta.types import Dimension
from google.analytics.data_v1beta.types import Filter
from google.analytics.data_v1beta.types import FilterExpression
from google.analytics.data_v1beta.types import FilterExpressionList
from google.analytics.data_v1beta.types import Metric
from google.analytics.data_v1beta.types import RunReportRequest
"""
class: Google Analytics4 Report
see doc https://developers.google.com/analytics/devguides/reporting/data/v1/basics
"""
class GoogleAnalytics4Report:
def __init__(self, propertyId):
self._propertyId = propertyId
self._metrics = []
self._dimensions = []
self._dateRange = ['28daysAgo', 'yesterday']
self._filters = None
self._result = []
def setMetrics(self, metrics):
"""setter for report metrics."""
self._metrics = metrics
return self
def setDimensions(self, dimensions):
"""setter for report dimensions."""
self._dimensions = dimensions
return self
def setDateRange(self, dateRange):
"""setter for date range."""
self._dateRange = dateRange
return self
def setFilters(self, **kwargs):
"""setter for report filters."""
self._filters = kwargs
return self
def run(self, client):
"""Run this report on a Data API(GA4)."""
def filterExprBuilder(filters):
if isinstance(filters, list):
return FilterExpressionList(expressions=[FilterExpression(filter=filter) for filter in filters])
return FilterExpression(filter=filters)
dimension_filter = None
if self._filters is not None:
dimension_filter = FilterExpression(
**dict(map(lambda filter: (filter[0], filterExprBuilder(filter[1]) if filter[0] != 'filter' else filter[1]), self._filters.items()))
)
request = RunReportRequest(
property=f"properties/{self._propertyId}",
metrics=[Metric(name=name) for name in self._metrics],
dimensions=[Dimension(name=name) for name in self._dimensions],
date_ranges=[DateRange(start_date=self._dateRange[0], end_date=self._dateRange[1])],
dimension_filter=dimension_filter
)
response = client.run_report(request)
print(f"{response.row_count} rows received")
self._result = [self._parseRow(row) for row in response.rows]
return self
def getResult(self):
"""get result returned by Data API(GA4)."""
return self._result
def getRecords(self):
"""get result as a list of record."""
columns = [('dimensions', col) for col in self._dimensions]
columns.extend([('metrics', col) for col in self._metrics])
return [dict([(name, item[i][name]) for i, name in columns]) for item in self._result]
def _parseRow(self, row):
dimensions = self._dimensions
metrics = self._metrics
return {
'dimensions':dict([(name, row.dimension_values[i].value) for i, name in enumerate(self._dimensions)]),
'metrics':dict([(name, float(row.metric_values[i].value)) for i, name in enumerate(self._metrics)])
}
使用例 アクティブユーザーの日次推移データをデータフレームに加工する
from google.analytics.data_v1beta import BetaAnalyticsDataClient
import datetime
import pandas as pd
import os
"""アクティブユーザーの過去7日間の推移データを取得(GA4)"""
# アカウント設定
# credential.jsonを/credentialに設置 && GA4 プロパティIDを設定
os.environ['GOOGLE_APPLICATION_CREDENTIALS'] = 'credential/credential.json'
GA_PROPERTY_ID = {YOUR_PROPERTY_ID}
client = BetaAnalyticsDataClient()
activeUserReport = GoogleAnalytics4Report(GA_PROPERTY_ID).setDimensions(
dimensions=['date']
).setMetrics(
metrics=['activeUsers']
).setDateRange(
dateRange=['7daysAgo', 'yesterday']
).run(client)
# データフレームに加工
df = pd.DataFrame.from_records(activeUserReport.getRecords())
df['date'] = pd.to_datetime(df['date']) # datetime型に変換
df['date'] = df['date'].dt.to_period('D')
df
date activeUsers
0 2022-10-21 19.0
1 2022-10-20 15.0
2 2022-10-25 15.0
3 2022-10-26 14.0
4 2022-10-22 9.0
5 2022-10-24 9.0
6 2022-10-23 7.0
Discussion