はじめに
この記事を読んでいる皆さんは、UAのバックアップは終わりましたでしょうか?
UAは2024/07/01
以降には、完全に削除されてしまいます。
なので、それまでにデータが必要であれば、バックアップする必要があります。
今回は以下APIを使用して、データをcsvに出力することをしたので、そのアウトプットとなります。
最終的には、出力したcsvをBigQueryにインポートするまで対応しますが、アウトプットはAPIの実装のみとなります。
この記事では、プロジェクトの作成方法や認証情報の取得に関しては、解説を行いません。
あくまで、APIの実装方法がメインとなります。
前提
- サービスアカウント認証を利用
- 認証情報をJSONファイルは取得済み
Reporting API を利用するための準備は、以下記事を参照してください。
他サービスの検討
- BigQueryエクスポート
- trocco
- スプレッドシートのアドオン
BigQueryエクスポート
有料のGAを使用していれば、直接GAのデータをBigQueryにエクスポートしてくれる機能があります。
しかも、APIなどは加工されたデータしか取得できないですが、これは生データを取得することができます。
ただ使用しなかったのは、直近13ヶ月分のデータしか取得することができず、過去のデータ全てに対応することができなかったため、早々に検討から外しました。
trocco
ETLツールで、UAのデータを直接BigQueryに入れることができるので、非常に便利だと思います。
ただ、実行時間で課金がされるので、他事業で過去〇年分まで対応する...。となると、すごいことになってしまう予想をしました。
また、後ほど注意点にも記載しますが、サンプリングもあるため、troccoも検討から外しました。
スプレッドシートのアドオン
アドオンも便利ですが、これもサンプリングが問題になるのと、サンプリングがかからない期間で取得しようとすると、すごい期間になったり、実行時間が長過ぎてしまうので、これも検討から外しました。
なので、
- サンプリングがかからない期間(1日単位)で、データを取得することができる
- 過去のデータも取得できる
主に、この2点でAPIしかないと判断して、実装を進めました。
実装
require 'googleauth'
require 'google/apis/analyticsreporting_v4'
require 'csv'
require 'time'
VIEW_ID = '111111111'
START_DATE = Date.parse('2018-01-01')
END_DATE = Date.parse('2018-12-31')
FORMAT_NAME = 'test'
PROPATY_NAME = 'propaty_test'
TRACKING_ID = 'UA-111111111-11'
def get_analytics_data(client, analytics, date_str, dimension, page_token = nil)
date_range = analytics::DateRange.new(start_date: date_str, end_date: date_str)
metric = [
analytics::Metric.new(expression: 'ga:users', alias: 'users'),
analytics::Metric.new(expression: 'ga:pageviews', alias: 'pageviews'),
analytics::Metric.new(expression: 'ga:totalEvents', alias: 'total_events'),
analytics::Metric.new(expression: 'ga:sessions', alias: 'sessions'),
analytics::Metric.new(expression: 'ga:bounceRate', alias: 'bounce_rate'),
analytics::Metric.new(expression: 'ga:exitRate', alias: 'exit_rate'),
analytics::Metric.new(expression: 'ga:timeOnPage', alias: 'time_on_page'),
analytics::Metric.new(expression: 'ga:newUsers', alias: 'new_users')
]
report_request = analytics::ReportRequest.new(
view_id: VIEW_ID, metrics: metric, dimensions: dimension, date_ranges: [date_range], page_size: 100000
)
report_request.page_token = page_token if page_token
request = analytics::GetReportsRequest.new(report_requests: [report_request])
client.batch_get_reports(request)
end
# CSV output
def save_to_csv(all_rows, response, date_str)
filename = "#{VIEW_ID}/analytics_data_#{date_str}_#{FORMAT_NAME}.csv"
dimension_header = response.reports.first.column_header.dimensions
CSV.open(filename, 'w', force_quotes: true) do |csv|
header = ['property_name', 'tracking_id', 'view_id'] + dimension_header + response.reports.first.column_header.metric_header.metric_header_entries.map { |entry| entry.name }
csv << header
all_rows.each do |row|
dimensions = row.dimensions
metrics = row.metrics.first.values
csv << [PROPATY_NAME, TRACKING_ID, VIEW_ID] + dimensions + metrics
end
end
puts "データが #{filename} に保存されました。"
end
# 実行開始時刻を記録
start_time = Time.now
scope = ['https://www.googleapis.com/auth/analytics.readonly']
analytics = Google::Apis::AnalyticsreportingV4
client = analytics::AnalyticsReportingService.new
client.authorization = Google::Auth::ServiceAccountCredentials.make_creds(
json_key_io: File.open('test-analysis-abc123456789.json'),
scope: scope
)
# 実行回数をカウントする変数
total_execution_count = 0
execution_count = 0
sleep_time = 30
execution_limit = 95
# 各日付ごとにデータを取得しCSVに保存
(START_DATE..END_DATE).each do |date|
# 日付の文字列変換
date_str = date.strftime('%Y-%m-%d')
original_dimension = [
analytics::Dimension.new(name: 'ga:date'),
analytics::Dimension.new(name: 'ga:deviceCategory'),
analytics::Dimension.new(name: 'ga:pagePath'),
analytics::Dimension.new(name: 'ga:sourceMedium'),
analytics::Dimension.new(name: 'ga:landingPagePath')
]
client_dimension = [
analytics::Dimension.new(name: 'ga:dimension27')
]
dimension = original_dimension + client_dimension
# データ取得
response = get_analytics_data(client, analytics, date_str, dimension)
all_rows = response.reports.first.data.rows
puts response.reports.first.data.row_count
while response.reports.first.next_page_token
next_page_token = response.reports.first.next_page_token
next_response = get_analytics_data(client, analytics, next_page_token)
all_rows.concat(next_response.reports.first.data.rows)
response = next_response
end
# データをCSVに保存
save_to_csv(all_rows, response, date_str) unless all_rows.nil?
end
# 実行終了時刻を記録
end_time = Time.now
execution_time = end_time - start_time
puts "プログラムの実行時間: #{execution_time} 秒"
ディレクトリ構成
- VIEW_ID(フォルダ)
- この配下にcsvが出力される
- script.rb
- test-analysis-abc123456789.json
環境
- ruby:3.2.2
- Gem:google-api-client
- 3.4.10
gem install google-api-client
解説
複数のプロパティ・ビューを取得したい場合、主に定数を変更するだけで良いようにしています。
client = analytics::AnalyticsReportingService.new
client.authorization = Google::Auth::ServiceAccountCredentials.make_creds(
json_key_io: File.open('test-analysis-abc123456789.json'),
scope: scope
)
上記で認証を行っています。
このrubyファイルと同じディレクトリに、事前に作成したjsonファイルを置いていただければ、問題ございません。
report_request = analytics::ReportRequest.new(
view_id: VIEW_ID, metrics: metric, dimensions: dimension, date_ranges: [date_range], page_size: 100000
)
report_request.page_token = page_token if page_token
APIは、最大行数を超えると、別ページとなり、再度リクエストを送らないと取得することができません。
今回は、page_size: 100000
としているので、この行よりも多く返ってきてしまった場合も、もう一度リクエストを走らせて取得できるよう実装しています。
あとは、利用制限を気をつけつつ、メトリクス・ディメンションを設定していただければ、csvに出力できるかなと思います。
注意点
1日の利用制限
利用制限を超えてしまうと、データが取得できなかったり、エラーになってしまいます。
ここはしっかり読んで、把握しておきましょう。
サンプリングがかかってしまう
長い期間を設定して、一気にデータを取得しようとすると、GA側で全てのデータの中からある程度のデータで計算されてしまう仕様がサンプリングになります。
そのため、1年間を一気に取得しようとすると、1日ずつ取得したデータと差異を生じることがあります。
なので、1日ずつ取得するよう、APIは実装しています。
まとめ
データを取得するだけですが、考慮しないといけない点が多く、とても時間がかかる作業です。
今回アウトプットした実装を例に、皆様がやりやすいように修正して、使っていただけたら幸いです。
最後までご覧いただき、ありがとうございました。