この記事は個人ブログと同じ内容です
Google Analytics(以下、GA)では、2022 年 7 月にユニバーサルアナリティクス(以下、UA)プロパティでの計測処理が停止します。
計測停止後、およそ半年程度は GA の画面から計測結果を閲覧できるとのことですが、それ以降はページすら見れなくなるそうです。
これを受けて我々は UA プロパティから GA4 プロパティへと移行しなくてはならないわけですが、移行と言っても正確には GA4 プロパティでの計測を新たに開始することであり、この時、これまで UA プロパティで計測してきた過去のデータを GA4 プロパティ側に持ってくることはできません。
では折角積み上げてきた UA プロパティでの計測データをこのまま手放すしかないのでしょうか。
今回は Google が提供している Analytics Reporting API を使って UA での計測データを一括してエクスポートしていきます。
Google Analytics Reporting API v4
Google アナリティクス Reporting API v4 は、GA のレポートデータを取得することのできる GA 公式の API です。
Google アナリティクス Reporting API v4 は、Google アナリティクス のレポートデータにアクセスするための最も高度な プログラマティック メソッドです。 Google アナリティクス Reporting API では、次のことが可能です。
API を使わなくても GA の画面から各レポートのデータエクスポートが出来ますが、できるだけ未集計のデータで落としたいなどの場合にはこれでは難しい場合があります。
例えばレポートの日付範囲を選択するとその範囲で集計されたレポートがエクスポートされるため、ログデータのように時系列で並んだ個々の計測データとして落とすことはおそらく標準の計測項目だけでは不可能です。 (カスタムディメンジョン使ったらいけるかもしれないけどやってみたことはありません)
こういった、できるだけ「1 計測 1 レコード」のような形式で期間的に広範囲なデータをまとめてエクスポートしたい場合は Analytics Reporting API が使えます。
これを使って GA から UA での計測データを一括で持ってきます。
エクスポートするデータの計画
まずはどんなデータを、どんな形で落とすかを計画しておきます。
今回は、PV(PageView)のデータをエクスポートしたいとしましょう。
エクスポートするデータはできるだけ集計されておらず、計測された日時順に並んだログのような体裁で落として、それを何らかのデータベースに入れて分析に使えるようなデータとして落としたいです。
引っ張るものとしては以下がほしいですね
- 計測日時
- ページ URL(どのページを閲覧したのか)
- リファラー(pvなのでセットでほしい)
- ホスト名(環境が複数あっても識別できるように)
ひとまずこれくらいのデータが UA プロパティから持ってこれれば、ページビューのデータが最低限救出できたと言えそうです。
Analytics Reporting API の有効化
まずは GCP 側で Reporting API を使えるようにします。
以下のページの「1. API を有効にする」を行えば API が使えるようになります。
やることは大きく 3 つです。
- Analytics Reporting API の有効化
- サービスアカウントを作成し、キー(Credential)を作成。そしてそれをダウンロード(JSONファイル)
- GA 側に作成した API ユーザーを登録
2 で取得する Credential(JSONファイル)は API を使用する際に必要になります。
実装について
Analytics Reporting API を用いたデータエクスポートの実装は PHP で行います。
composer を実行できる環境が必要です。
パッケージインストール
Google API クライアント ライブラリを composer でインストールします。
composer require google/apiclient:^2.0
Analytics Reporting API を用いたデータエクスポートの実装
それでは Reporting API を用いて、UA データの救出プログラムを実装していきます。
サンプルコードは予め Github に上げてあります。
手続き的に実装するとしても、以下を上から順番につらつらと記述していけば実行できます。
1. クライアント初期化
まずは API と通信を行うクライアントオブジェクトを作成(インスタンス化)します。
<?php $client = new Client(); $client->setApplicationName("Analytics Reporting"); $client->setAuthConfig('<ここに credential JSON ファイルのパス>'); $client->setScopes(['https://www.googleapis.com/auth/analytics.readonly']); $analytics = new AnalyticsReporting($client);
setAuthConfig() の引数には、事前にダウンロードした credential(JSON ファイル)のパスを渡します。
ここで最終的に作成する AnalyticsReporting オブジェクトが、 GA のレポートデータにアクセスする役割を担います。
2. リクエストの作成
次に、GA へのリクエストを実装します。
「どのようなデータを取得したいか」の条件の部分を定義していく工程です。
リクエストオブジェクト作成
<?php $request = new ReportRequest(); $request->setViewId('<ViewID>');
setViewId() の引数には、UA プロパティの「ビュー ID」を渡します。
「ビュー ID」は、GA の UA プロパティ管理画面「ビュー」にある ID のことです。
取得する日付範囲の指定
<?php $dateRange = new DateRange(); $dateRange->setStartDate('2022-07-01'); $dateRange->setEndDate('2022-07-09'); $request->setDateRanges($dateRange);
いつからいつまでのデータを取得するかをセットしています。
ディメンジョン指定
<?php $pagePath = new Dimension(); $pagePath->setName("ga:pagePath"); $hostname = new Dimension(); $hostname->setName("ga:hostname"); $dateHourMinute = new Dimension(); $dateHourMinute->setName("ga:dateHourMinute"); $sourceMedium = new Dimension(); $sourceMedium->setName("ga:sourceMedium"); $previousPagePath = new Dimension(); $previousPagePath->setName("ga:previousPagePath"); $request->setDimensions([ $dateHourMinute, $hostname, $pagePath, $sourceMedium, $previousPagePath ]);
ディメンジョン(軸)を指定しています。
エクスポートするデータの計画に従い、今回は以下をディメンジョンとして指定しました。
- ga:pagePath:計測ページ URL
- ga:hostname:ホスト名
- ga:dateHourMinute:計測日時
- ga:sourceMedium:参照元 / メディア
- ga:previousPagePath:前のページ URL
ちなみに、リファラのディメンジョンとして ga:fullReferrer
がありますが、「外部から来たのか」「サイト内回遊なのか」がわかれば良いので今回は取得していません。
「参照元 / メディア」を見れば「外部リンクから」「検索結果から」「ブックマークなど直接」くらいはわかるので、あとは「前のページ URL」がどうなっているかでサイト内回遊かどうかがわかる。というところで今回のディメンジョン指定になっています。
ディメンジョンとセットする値の対照は下記ページに記載があるので実際に指定したいものを探せます。
ディメンジョンのフィルター
指定したディメンジョンに対してフィルターを掛けることができます。
特定のページに絞ったり、あのリファラは除外したり。みたいなことです。
<?php $pathFilter = new DimensionFilter(); $pathFilter->setDimensionName('ga:pagePath'); $pathFilter->setOperator('REGEXP'); $pathFilter->setExpressions(['^\/entry\/[0-9]+$']); $filters = new DimensionFilterClause(); $filters->setFilters([$pathFilter]); $request->setDimensionFilterClauses($filters);
上の例では、ページ URL に対して、正規表現で指定したものに合致するページのみに絞り込む指定を行っています。
フィルタリングする条件が複数ある場合は、以下のようにして記述します。
<?php // ページ URL 絞り込み $pathFilter = new DimensionFilter(); $pathFilter->setDimensionName('ga:pagePath'); $pathFilter->setOperator('REGEXP'); $pathFilter->setExpressions(['^\/entry\/[0-9]+$']); // 特定のリファラを除外 $referrerFilter = new DimensionFilter(); $referrerFilter->setDimensionName('ga:fullReferrer'); $referrerFilter->setOperator('EXACT'); $referrerFilter->setExpressions(['(direct)']); $filters = new DimensionFilterClause(); $filters->setOperator('AND'); // 両方の条件を AND 条件として絞る $filters->setFilters([$pathFilter, $referrerFilter]); $request->setDimensionFilterClauses($filters);
ポイントとして、DimensionFilterClause クラスの setOperator() によって AND 条件か OR 条件かを指定できます。
なお、DimensionFilter クラスの setOperator() によって、「条件の形式(完全一致、部分一致など)」を指定できますが、引数としてどういった形式を指定できるのかは下記のページで確認することができます。
ちなみにディメンジョンとしてセットできるのは最大 9 個までです。
メトリクス指定
次に、メトリクスを指定します。
<?php $pageView = new Metric(); $pageView->setExpression("ga:pageviews"); $pageView->setAlias("pageviews"); $request->setMetrics([$pageView]);
今回はページビューを取りたいので、その指定を行っています。
ここで、できる限り集計されていない生データのような状態(1 計測 1 レコード)でエクスポートしたいのですが、標準のディメンジョンの場合、時間に関するものの最小値が「分」のため、同一分の PV はまとまってしまうので、そこは許容するしかありません。 (カスタムディメンジョンを作成してマイクロミリ秒まで送信したらもしかしたらいけるかもしませんが、同一分で全く同じ PV ならどうせ移植先のデータベースで同じものとして集計するだろうし、今回はこのままにしています)
データの並び順指定
<?php $orderByDate = new OrderBy(); $orderByDate->setFieldName('ga:dateHourMinute'); $orderByDate->setSortOrder('ASCENDING'); $request->setOrderBys([$orderByDate]);
時系列で並べたいので、ga:dateHourMinute にて昇順で取得するように指定しています。
ページサイズ指定
<?php $request->setPageSize(2000);
「一回のリクエストで何件取得したいか」を指定しています。
ここでは 2000 を指定していますが、取得する全件のデータが 10,000 件だった場合、そのうちの 2,000 件を一回のリクエストで取得する。という意味になります。
Reporting API ではページングやオフセット的にデータを取得できるので、エクスポート対象が数万、数十万件であっても、このページサイズの指定によってマシンのスペックに見合った件数に分割して取得していくことができます。
つまり、2000 件ずつの取得でループさせて計 5 回のリクエストにて 10000 件取得していくような流れで実装するイメージです。
これで一通りのリクエストを作成できました。
3. データの取得
作成したリクエストを以て、GA からデータを取得します。
<?php $body = new GetReportsRequest(); $body->setReportRequests([$request]); $response = $analytics->reports->batchGet($body);
setReportRequests() の引数である変数 $request は、この前の工程で作成した ReportRequest オブジェクトです。
前工程で作成した AnalyticsReporting オブジェクトより、(厳密には内包されている Reports オブジェクトの)batchGet() を実行することで、GA からデータを取得できます。
変数 $response にデータが入ってくるので、あとは好きに整形して CSV に書き込むなりすれば、UA プロパティからデータをエクスポートできます。
UA データ救出大作戦実行
動作確認を行ってみます。
これまでは Reporting API の実装をポイントで解説したため、ループや取得データの整形、保存含め、一連の実装については Github のサンプルコードを参照いただくとわかりやすいと思います。 (サンプルコードは、必要な箇所を設定・定義すれば動作するようにはなっていますが、PC に予め composer と Docker Desktop のインストールが必要です。)
今回は、2022 年 6 月(一ヶ月分)の、ある箇所のページビューのみに絞って取得してみます。 3000 件ずつ取得し、データは CSV に書き込んでいくようにしています。
ターミナルにてコマンド実行します。
% docker compose run --rm php-81-cli php index.php 2022-06-01 - 2022-06-30 remaining: 42291 remaining: 39291 remaining: 36291 remaining: 33291 remaining: 30291 remaining: 27291 remaining: 24291 remaining: 21291 remaining: 18291 remaining: 15291 remaining: 12291 remaining: 9291 remaining: 6291 remaining: 3291 remaining: 291
3,000 件ずつ取得し、全部で 42,300 件程度データをエクスポートしました。
date,datetime,hostname,pageview,page_location,source_medium,previous_page_path 2022-06-01,"2022-06-01 00:06:00",www.ritolab.com,1,/entry/56,"google / organic",(entrance) 2022-06-01,"2022-06-01 00:08:00",www.ritolab.com,1,/entry/24,"google / organic",(entrance) 2022-06-01,"2022-06-01 00:09:00",www.ritolab.com,1,/entry/54,"google / organic",(entrance) 2022-06-01,"2022-06-01 00:09:00",www.ritolab.com,1,/entry/93,"google / organic",(entrance) . . . 2022-06-30,"2022-06-30 23:50:00",www.ritolab.com,1,/entry/217,"google / organic",(entrance) 2022-06-30,"2022-06-30 23:51:00",www.ritolab.com,1,/entry/93,"google / organic",(entrance) 2022-06-30,"2022-06-30 23:52:00",www.ritolab.com,1,/entry/93,"google / organic",(entrance) 2022-06-30,"2022-06-30 23:57:00",www.ritolab.com,1,/entry/67,"google / organic",(entrance)
まとめ
今回はページビューで取りましたが、ユーザーやセッションなど、ディメンジョンやメトリクスの指定で一通りデータは取れますし何より一括でまとめて落とせますので、UA プロパティのデータが必要な場合には Analytics Reporting API を活用すると効率的にデータを持ってこれます。
ちなみにリクエストに関する制限(どれくらいの数や量をリクエストできるのか)は以下に記載がありますが、そこそこ寛容なので大きすぎる規模でなければ制限ラインには抵触しないかなと思います。
Analytics Reporting API 便利なので試してみてください。
現在 back check 開発チームでは一緒に働く仲間を募集中です。