【使いまわせる！】Google Analytics 4からPython APIを使ってデータを取得する

本記事では、Google Analytics 4（GA4）にあるデータをPythonから取得する方法を紹介します。
紹介するPythonプログラムは、設定ファイルのパスやデータの取得期間などをインタフェースとして使いまわしがし易いようにしておりますので、ぜひご活用ください！

:::note info
本記事は元々、データパレード様のブログに私が執筆した技術ノウハウとして掲載したものです（下記）。Qiitaを通じてより多くの方に届けられれば、そして技術者の方と知見を共有し、フィードバックをいただく目的で許可をいただき掲載しました。
:::
https://data-parade.com/get-ga4-by-python/

# 事前準備
## GA4の設定

GA4からData APIを使ってデータを取得するためには、サービスアカウントを作成や認証ファイルの取得が必要です。この部分はさまざまなページで紹介されています。

個人的には、Google 公式のQuick Startおよび下記のページが参考になりました。

https://developers.google.com/analytics/devguides/reporting/data/v1/quickstart-client-libraries?hl=ja

https://www.lifewithpython.com/2023/01/python-migrate-to-google-analytics-data-api-v1.html

## Pythonライブラリのインストール

今回紹介するPythonスクリプトを実行するために、下記よりライブラリをインストールしてください。

```
pip install pandas
pip install google-analytics-data
```

# PythonからGA4のデータを取得してCSVに出力
## ユーザー設定ファイルの作成

GA4からデータを取得する上で必要な認証ファイル及びプロパティIDを指定しておく設定ファイルを作成します。下記をコピー＆ペーストして、「config_GA4.ini」などとして保存します。

```ini
[DEFAULT]
GOOGLE_APPLICATION_CREDENTIALS = C:\Workspace\python\get_data_GA4\configs\sample-test-user-*****.json
PROPERTY_ID = 123456789
FILTER_FIELD = pagePathPlusQueryString
FILTER_EXPRESSION = /aaa
```

* GOOGLE_APPLICATION_CREDENTIALS：認証ファイルのパスを指定
* PROPERTY_ID：プロパティIDを指定
* FILTER_FIELD/FILTER_EXPRESSION：取得するデータに対して絞り込みを行う際に指定。例のように「pagePathPlusQueryString」、「/aaa」のように指定するとアクセスされたページパスのうち、「/aaa」から始まるページのみに絞り込まれます。絞り込みを行わない場合は、「FILTER_EXPRESSION = 」といった形で右辺を空欄にすればOK

## Pythonスクリプトの作成

下記はGA4からデータを取得するPythonスクリプトの一例です。こちらを「get_GA4_data_main.py」などとして保存します。

```python
import os
import argparse

from google.analytics.data_v1beta import BetaAnalyticsDataClient
from google.analytics.data_v1beta.types import (
    DateRange,
    Dimension,
    Metric,
    Filter,
    FilterExpression,
    RunReportRequest,
)
import configparser
import pandas as pd

parser = argparse.ArgumentParser(description='This script gets GA4 data and store as CSV. ')
parser.add_argument('-configfile_GA_path', help = "Set path including config file name e.g. C:/Users/hogehoge/config.ini ", required = True)
parser.add_argument('-startdate', help = "Set startdate to insert into database as hyphen dilimiter yyyy-mm-dd e.g. 2021-01-01 ", required = True)
parser.add_argument('-enddate', help = "Set enddate to insert into database as hyphen dilimiter yyyy-mm-dd e.g. 2021-01-07 ", required = True)
parser.add_argument('-csv_path', help = "Set path to save csv path e.g. C:/Users/hogehoge", required = True)
parser.add_argument('-csv_prefix_name', help = "Set prefix csv name as [prefix name]yyyy-mm-dd~yyyy-mm-dd[suffix name]. ", default = "", required = False)
parser.add_argument('-csv_suffix_name', help = "Set suffix csv name as [prefix name]yyyy-mm-dd~yyyy-mm-dd[suffix name]. ", default = "", required = False)
args = parser.parse_args()

DIMENSIONS = [
    "date", 
    "dateHourMinute",
    "pagePathPlusQueryString",
    "sessionSource",
    "deviceCategory", 
    "operatingSystem", 
    "pageTitle"
    ]

METRICS = [
    "totalUsers",
    "sessions",
    "screenPageViews",
    "userEngagementDuration"
]

class get_GA4_data():
    def __init__(self, config_ini_path):
        config_ini = configparser.ConfigParser()
        if not os.path.exists(config_ini_path):
            raise FileNotFoundError(config_ini_path + " is not found. ")
        config_ini.read(config_ini_path, encoding="utf-8")
        

        self.GOOGLE_APPLICATION_CREDENTIALS = config_ini['DEFAULT']['GOOGLE_APPLICATION_CREDENTIALS']
        os.environ['GOOGLE_APPLICATION_CREDENTIALS'] = config_ini['DEFAULT']['GOOGLE_APPLICATION_CREDENTIALS']
        self.PROPERTY_ID = config_ini['DEFAULT']['PROPERTY_ID']
        self.FILTER_FIELD = config_ini['DEFAULT']['FILTER_FIELD']
        self.FILTER_EXPRESSION = config_ini['DEFAULT']['FILTER_EXPRESSION']
        print(f"self.FILTER_FIELD: {self.FILTER_FIELD}")
        print(f"self.FILTER_EXPRESSION: {self.FILTER_EXPRESSION}")


    def sample_run_report(self, startdate = "2023-03-01", enddate = "2023-03-07"):
        """Runs a simple report on a Google Analytics 4 property."""
        # TODO(developer): Uncomment this variable and replace with your
        #  Google Analytics 4 property ID before running the sample.
        # property_id = "YOUR-GA4-PROPERTY-ID"

        # Using a default constructor instructs the client to use the credentials
        # specified in GOOGLE_APPLICATION_CREDENTIALS environment variable.
        client = BetaAnalyticsDataClient()

        request = RunReportRequest(
            property=f"properties/{self.PROPERTY_ID}",
            dimensions=[ Dimension(name = dim) for dim in DIMENSIONS],
            metrics=[ Metric(name = met) for met in METRICS],
            date_ranges=[DateRange(start_date=startdate, end_date=enddate)],
            dimension_filter=FilterExpression(
                filter=Filter(
                    field_name = self.FILTER_FIELD,
                    string_filter = Filter.StringFilter(match_type = "BEGINS_WITH", value = self.FILTER_EXPRESSION),
                )
            ),
        )
        self.response = client.run_report(request)

    def make_dataframe(self):
        output_header = DIMENSIONS + METRICS
        print(output_header)
        
        ### 辞書にしてDataframe化
        output_dic = {}
        for header in output_header:
            output_dic[header] = []

        for row in self.response.rows:
            value_list = []
            value_list += [elem.value for elem in row.dimension_values]
            value_list += [elem.value for elem in row.metric_values]

            for k,v in zip(output_header, value_list): 
                output_dic[k].append(v)
        
        self.df = pd.DataFrame(output_dic)
        
    def write_csv(self, filename):
        self.df.to_csv(filename, index=False)

def main():
    config_GA_path = args.configfile_GA_path
    csv_path = args.csv_path
    csv_prefix_name = args.csv_prefix_name
    csv_suffix_name = args.csv_suffix_name
    startdate = args.startdate
    enddate = args.enddate
    
    con_GA = get_GA4_data(config_GA_path)
   
    con_GA.sample_run_report(startdate=str(startdate), enddate=str(enddate))
    con_GA.make_dataframe()
    filename = csv_path + "/" + csv_prefix_name + str(startdate) + "~" + str(enddate) + csv_suffix_name +".csv"
    con_GA.write_csv(filename)

if __name__ == "__main__":
    main()

```

取得データに含めたいDIMENSIONSもしくはMETIRCSは、コード上部のリストに直接追加してください。

# 実行

では実行してみましょう！コマンドプロンプトから下記のコマンドを実行します。

```
python .\get_GA4_data_main.py -configfile_GA_path "C:\Workspace\python\get_data_GA4\configs\config_GA4.ini" -startdate "2024-01-01" -enddate "2024-01-07" -csv_path "C:\Workspace\python\get_data_GA4\data\"
```

* -configfile_GA_path：「ユーザー設定ファイルの作成」節で作成したiniファイルのパスを指定
* -startdate/-enddate：データを取得する期間を「yyyy-mm-dd」の形式で指定
* -csv_path：CSVファイルを出力するパスを指定

上記を実行すると、指定したフォルダに指定した期間のCSVファイルが出力されていることを確認できますね！！

![画像1-1536x385.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4099119/f03f076c-3caa-45a1-b463-dcc4400edeb4.png)

# さいごに
本記事では、PythonからGA4のデータを取得する方法について紹介しました。汎用的に使えるようCSVファイルとして出力する設計にしておりますので、例えばデータベースに格納したり、BIツールで分析して、データの"活用"を進めてみてくださいね！

Google Sheet上で管理・分析する場合には、こちらの記事も参考になるので是非ご覧ください！

https://qiita.com/ebi_ebi_dev/items/696e9b4f44289c2942e7