GoogleアナリティクスUAデータのAPIを用いたバックアップ取得手順と注意

# 対応経緯
GoogleAnalyticsのUA（ユニバーサルアナリティクス）が終了し、2024年7月1日より、データが閲覧もできなくなります。

https://support.google.com/analytics/answer/11583528

それに備え、データのバックアップを取得しておく必要がありました。
レポート画面でひとつずつ手動でエクスポートしていられないため、Google Analytics Reporting APIを使用して取得したいと考えました。
# 環境
Windows10
Python3.7
（PCはプロキシ設定がされています）
# まず確認したもの
APIの仕様をまずは理解する必要があるので、公式のドキュメントを読みました。

https://developers.google.com/analytics/devguides/reporting/core/v4?hl=ja

公式ドキュメントにチュートリアルは存在しています。チュートリアルの通りに対応して問題なく取得できれば良かったのですが、いろいろと悪戦苦闘したため、今回まとめて記載しておこうと思いました。

https://developers.google.com/analytics/devguides/reporting/core/v4/quickstart/service-py?hl=ja

# UAのバックアップデータ取得までの手順
1. Google Cloud Platform（GCP）でプロジェクトを新規作成。
1. Google Cloud Platform（GCP）で「APIとサービス」からGoogle Analytics Reporting APIを有効にする。
1. Google Cloud Platform（GCP）でサービスアカウントを作成。鍵のjsonファイルをダウンロード。
1. Google Analyticsの「管理」の「ユーザーの管理」から、作成したサービスアカウントのアドレスがアクセスできるように「閲覧」の権限を追加
1. Pythonをインストール
1. PCのプロキシ設定の確認（プロキシ設定がされているPCを使用している場合のみ）
1. 必要なモジュールである「google-api-python-client」「oauth2client」をインストール（プロキシ設定がされているPCを使用している場合はプロキシオプションを使用）
1. APIを実行するコードを作成
1. 実行（プロキシ設定がされているPCを使用している場合はプロキシオプションを使用。実行時に取得した鍵のjsonファイルが必要。）
1. 出力ファイルの確認

実行手順や、コードは下記の記事が大変参考になりました。

https://dev.classmethod.jp/articles/ga-api-v4/

1回のレスポンスで受け取れるデータ量には上限がありますが、**こちらで紹介いただいているコードはデータを全件取得できるように工夫がされており**、「バックアップとして全期間データ(大きなデータ)を取得したい」という今回の目的と非常に噛み合っていました。

私はこちらのコードをcsvファイルで出力される仕様にアレンジしつつ実行してみるところから始めました。

**本投稿を再現目的で閲覧している方がもしいれば、上記の記事を見ていただくのがはやい**と思います。
私の投稿では、上記記事を見ながら進めた上で**つまづいた点**について記載をできればと思います。

# 実際に対応してみてつまづいた点
- プロキシ設定の突破
- GAのサンプリングがされてしまう問題
- APIの割り当て上限の問題
- バックアップするディメンションと指標の選定

## プロキシ設定の突破
pip installでモジュールをインストールしようとした際にエラーが起きてしまい、プロキシ設定の存在を思い出しました。
pip install を実行するにあたり、プロキシオプションをつければプロキシは突破できるものの、プロキシ設定ファイルを見つけるのに時間がかかってしまいました。
### ・手動プロキシセットアップの場合
1. Windowsスタートボタンから「設定」を開き、「ネットワークとインターネット」をクリックします。
1. 左側のメニューから「プロキシ」をクリックします。
1. 「手動プロキシセットアップ」という項目に設定情報の記載がありました。
### ・自動プロキシセットアップの場合
1. 手動プロキシセットアップと同様の画面まで進みます。
1. 「自動構成」のセットアップスクリプトの「アドレス」をコピーし、ブラウザでアドレスにアクセスします。
1. ファイルダウンロードが始まるのでそのままダウンロードします。
1. ダウンロードしたファイルをエディタで開きます。
1. ファイルの一番下に、 「return "PROXY xxxx.xxxx.com:8080」といった設定情報の記載がありました。

こちらで調べた設定情報を用いて、モジュールのインストールや実行作業を行いました。

**▼モジュールのインストール例**
```
$ pip install --proxy="http://xxxx.xxxx.com:8080" -upgrade google-api-python-client
```
プログラムを実行する際にもAPIを使用するためProxyの環境変数が設定されていなければプログラムを実行できません。
それについてはコマンドプロンプトで下記を入力すれば設定できます。

**▼コマンドプロンプトで環境変数を設定した例**
```
$ set HTTP_PROXY=http://xxxx.xxxx.com:8080
$ set HTTPS_PROXY=http://xxxx.xxxx.com:8080
```
しかし、コマンドプロンプトを立ち上げ直すたびに入力が必要になるかつ、プログラムを実行ファイルに変換する場合はそれができずに困るので、私は今回、プログラム内の冒頭にProxyの環境変数の定義を記載をしておきました。

**▼Pythonコード内で環境変数を定義した例**
```
import os
os.environ['http_proxy'] = 'http://xxxx.xxxx.com:8080'
os.environ['https_proxy'] = 'http://xxxx.xxxx.com:8080'
```

## GAのサンプリングの問題
Google Analyticsでは、データが大きい場合にサンプリングしたデータを表示させる機能があります。
APIでデータを取得する際にもこのサンプリングが発生します。

https://support.google.com/analytics/answer/2637192?hl=ja#zippy=%2C%E3%81%93%E3%81%AE%E8%A8%98%E4%BA%8B%E3%81%AE%E5%86%85%E5%AE%B9

私が試みた時点の情報で、このサンプリングが発生する条件は「選択した期間でプロパティ単位のセッション数が50万件以上」と記載されていました。
要は、2020-01-01〜2022-12-31のデータ取得を1リクエストで送った際に、その期間のセッション数が50万を超えていればサンプリングがかかってしまう、という話だと受け止めました。（実際にサンプリングかかりました）

サンプリングレベルを調整できるフィールドが存在していたため、最もサンプリングを発生させないという「"samplingLevel":"LARGE"」を使用しましたが、サンプリングは発生しました。（サンプリングが発生したかどうかは、レスポンスのsamplesReadCounts、 samplingSpaceSizesいずれかの中身を確認すればわかります。）

https://developers.google.com/analytics/devguides/reporting/core/v4/basics?hl=ja#sampling

どうしてもサンプリングを発生させたくなかったため、やむを得ず、取得期間を分割してリクエストを送ることにしました。

具体的な例で記載すると、下記のようなイメージです。

**▼サンプリングが発生するリクエスト**
取得期間：2020-01-01〜2020-12-31
セッション数：合計90万

**▼サンプリングが発生しないようにしたリクエスト**
取得期間：2020-01-01~2020-06-30と、2020-07-01~2020-12-31
セッション数：45万と、45万　合計90万

どれくらいの幅で分割するかの決定については、GAのレポート画面で「月」「週」「日」別でそれぞれレポートを確認しながら、どの幅であればセッション数が50万を超えていないかを確認して決めました。

月ごとに分割し10年分取得しようとすれば、120回実行が必要になってしまうため、ここは入力した開始日から終了日まで、毎月のデータ取得リクエストを順番繰り返し送信する仕様をプログラムに追加で実装しました。



## APIの割り当て上限の問題
APIにはリクエストを送ることができる回数に上限が設定されています。
日ごと、分ごと、ビューごと、プロジェクトごとに細かい設定があります。

> - プロジェクトごとに 1 日 50,000 件のリクエスト
> - ビュー（旧プロファイル）あたり 1 日 10,000 件のリクエスト（引き下げ不可）
> - プロジェクトごとに 100 秒あたり 2,000 件のリクエスト
> - プロジェクトあたり 1 ユーザー、100 秒あたりのリクエスト数: 100（Google API Console で 1,000 に増やすことができます）。

リクエストが失敗した場合の上限も決まっているため注意が必要です。
> - プロジェクトあたり 1 時間あたり 10 件のサーバーエラーで、1 ビューあたりに失敗した回数
> - プロジェクトあたり 1 日 50 件のサーバーエラー（ビュー/プロファイル）エラーの回数

https://developers.google.com/analytics/devguides/reporting/core/v4/limits-quotas?hl=ja

余裕のある上限設定なため、１実行あたり１リクエストしか送らない場合は大きな障害になることはないかと思います。

しかし、私が対応したように**データがサンプリングされてしまうことを懸念して、短いスパンに分割して複数回リクエストを送るようなプログラムを用意した場合には注意が必要**ということになります。

期間を分割して実行する際は、プログラム内で分割数をnumに入れておき、下記の確認項目をセーフティとして実装しておきました。
```
check = input(f"{num}件のリクエストを送信します。問題ないですか？（y/n）：")
if check != "y":
    print("プログラムを終了します。")
    exit()
```


# バックアップするディメンションと指標の選定
これは実装とは少しズレた話になります。
ローデータがそのまま取得できるわけではないため、「どのディメンション」に対し、「どの指標」を指定してバックアップを取得しておくかを定めなければいけませんでした。
欲張るとキリがないため悩みましたが、ここは決めの問題だと思います。

ディメンションと指標が決まったら、Google側からも推奨されているこちらのサイトを利用してリクエスト時にどのような記述で指定をすれば良いかを確認しました。
日本語翻訳表示にしているとエラーが起きるためその点は注意が必要です。

https://ga-dev-tools.google/dimensions-metrics-explorer/

1点詰まった点として、**GAの設定で「データ保持期間」の「ユーザーデータの保持」が短い期間に設定されてしまっていると、その期間の分しかディメンションの掛け合わせのデータを取得できません**でした。

https://support.google.com/analytics/answer/7667196?hl=ja

**▼データ保持期間内**
ディメンション「ユーザータイプ」「参照元」「メディア」、指標「セッション」
ディメンション「国」「参照元」「メディア」、指標「セッション」
などが取得可能

**▼データ保持期間外**
ディメンション「ユーザータイプ」、指標「セッション」
ディメンション「参照元」「メディア」、指標「セッション」
などであれば取得可能

期間が短く設定されていた場合は、一刻も早くデータのバックアップを取得しなければ掛け合わせたデータが消えていくため注意が必要です。



# 最後に
なんとか無事データをダウンロードできたため、その後ダウンロードしたcsvファイルはPowerBIで可視化しました。
知識、経験の乏しさゆえか、ぶちあたる壁の問題解決ひとつひとつに時間をかなり費やしてしまったように感じています。
2024年7月1日にこのAPIも使用できなくなる点を踏まえるとなんとも言えない気持ちですが、今後、何回かこちらのプログラムを使用する予定があることが唯一の救いです。

これから同じことをしようとしている方がいれば、ご健闘をお祈りしています。