Qiita記事初投稿です。
APIの利用が初めてだったのも含めて、至らない点もあると思いますがよろしくお願いします。
概要・やりたいこと
私の会社ではサイト上の数値をGoogle Analytics(以降GA)を利用して計測しています。
社員もある程度おり数年以上利用を続けていたのですが、運用保守までしっかりと手が回らず、
様々なアカウントやプロパティが乱立してしまいました。
GAの管理画面上では、アカウントやプロパティの一覧をスクロールしながら表示することは可能です。
その結果をスプレッドシート上などで閲覧できる状態にしたい、というのが今回のゴールになります。
Try this APIを利用してみる(非エンジニア向け)
下記APIを利用すると、ログインしているChromeのアカウントに紐づくGAのアカウントデータをJSON形式で取得できます。
Management API > リファレンス > アカウント:list
実行結果を整形しても、ある程度やりたいことはできるようになります。
JSONファイルをExcelに変換
JSON ファイルを CSV ファイルに変換したい
1つ目の方法はExcelのバージョン都合で実行できず、2つ目の方法で実際に試したところ問題が発生しました。
- アウトプットの形式が意図通りではない
GAの構造ですが、アカウント > プロパティ > ビュー という構成になっています。
csv変換後のファイルは、アカウントの行数分だけ出力されます。
またアカウントによってプロパティ数は異なるため、個人的には意図していないデータが生成されました。
アカウント | プロパティ_1 | ビュー_1_1 | ビュー_1_2 | ・・・ | プロパティ_2 | ・・・ |
---|---|---|---|---|---|---|
A | Aに紐づくプロパティ1 | プロパティ1に紐づくビュー1 | プロパティ1に紐づくビュー2 | ・・・ | Aに紐づくプロパティ2 | ・・・ |
本来欲しかったのは、下記のような縦持ちのデータになります。
アカウント | プロパティ | ビュー |
---|---|---|
A | Aに紐づくプロパティ1 | プロパティ1に紐づくビュー1 |
A | Aに紐づくプロパティ1 | プロパティ1に紐づくビュー2 |
A | ・・・ | ・・・ |
A | A紐づくプロパティ2 | プロパティ2に紐づくビュー1 |
A | ・・・ | ・・・ |
B | Bに紐づくプロパティ1 | プロパティ1に紐づくビュー1 |
2.取得できるアカウントの数に限界がある?
社内では実行時59個のアカウントが存在していたのですが、取得できたのは49件でした。
パラメータの数値をいじったりしましたが、コードを書いてデータを取得しよう、となったため原因は深く調査していません。
何か心当たりがある方がいましたら、コメントいただけると嬉しいです。
開発環境・モジュールのバージョン
- python 3.8.2
- google-api-python-client 1.8.0
- build 1.0.2
- pandas 0.24.2
- numpy 1.16.4
事前の作業内容
発行したサービスアカウントを、取得したいGAのアカウントに追加した後に作業を行っています。
本来は社内の管理者アカウントに紐づくGAのアカウントを取得したかったのですが、対処方法が分からず。。
アカウントが多くてつらかったので、歌いながら片手間で作業して乗り切りました。笑
実装コード
以下、本題の実装コードになります。
実装コードの大部分が、下記からの引用です。
はじめてのアナリティクス API: サービス アカウント向け Python クイックスタート
APIを利用してアカウント、プロパティ、ビューごとのdfを作成し、空のdfにappendさせる、という処理を行っています。
Management API > リファレンス > ウェブ プロパティ: list
Management API > リファレンス > ビュー(旧プロファイル): list
from googleapiclient.discovery import build
from oauth2client.service_account import ServiceAccountCredentials
import pandas as pd
import numpy as np
def get_service(api_name, api_version, scopes, key_file_location):
credentials = ServiceAccountCredentials.from_json_keyfile_name(
key_file_location, scopes=scopes)
service = build(api_name, api_version, credentials=credentials)
return service
def get_account_propaty_view_info(service):
accounts = service.management().accounts().list().execute()
# アカウントの一覧をdfに格納する
account_df = pd.DataFrame(columns=['account_name', 'account_id'])
for account in accounts.get('items', []):
account_array = np.array([[account.get('name'), account.get('id')]])
df_account = pd.DataFrame(data=account_array,columns=account_df.columns)
account_df = account_df.append(df_account, ignore_index=False)
# プロパティの一覧をdfに格納する
property_df = pd.DataFrame(columns=['account_number','account_id', 'property_name', 'property_id'])
# アカウントのdfから、対象のプロパティ一覧を取得する
for i in range(len(account_df)):
properties = service.management().webproperties().list(accountId=account_df['account_id'].iloc[i]).execute()
for property in properties.get('items', []):
property_array = np.array([[i, account_df['account_id'].iloc[i], property.get('name'), property.get('id')]])
df_property = pd.DataFrame(data=property_array,columns=property_df.columns)
property_df = property_df.append(df_property, ignore_index=False)
# ビューの一覧をdfに格納する
view_df = pd.DataFrame(columns=['account_id', 'property_id', 'view_name', 'view_id'])
# プロパティのdfから、対象のビュー一覧を取得する
for i in range(len(property_df)):
views = service.management().profiles().list(accountId=property_df['account_id'].iloc[i],
webPropertyId=property_df['property_id'].iloc[i] ).execute()
for view in views.get('items', []):
view_array = np.array([[property_df['account_id'].iloc[i], property_df['property_id'].iloc[i], view.get('name'), view.get('id')]])
df_view = pd.DataFrame(data=view_array,columns=view_df.columns)
view_df = view_df.append(df_view, ignore_index=False)
# アカウントの一覧、プロパティの一覧、ビューの一覧を1つのdfにまとめてみる
# 結合時の処理都合でaccount_numberの位置が気になる方は、カラムの順序を変更してください。
ga_account_list = pd.merge(pd.merge(account_df, property_df, on='account_id', how='inner'), view_df, on=['account_id', 'property_id'], how='inner')
ga_account_list.to_csv('作成するcsvファイル名', encoding='utf_8_sig')
def main():
scope = 'https://www.googleapis.com/auth/analytics.readonly'
key_file_location = '発行したサービスアカウントのJSONキーファイル'
service = get_service(
api_name='analytics',
api_version='v3',
scopes=[scope],
key_file_location=key_file_location)
get_account_propaty_view_info(service)
if __name__ == '__main__':
main()
現状のアウトプット例
アカウントのIDは綺麗に数字が並んでいる訳ではないので、代わりにaccount_numberというものを持たせています
account_name | account_id | account_number | property_name | property_id | view_name | view_id |
---|---|---|---|---|---|---|
A | 10 | 0 | property_1 | 100 | view_1 | 1000 |
A | 10 | 0 | property_1 | 100 | view_2 | 1001 |
A | ・・・ | ・・・ | ・・・ | ・・・ | ・・・ | ・・・ |
A | 10 | 0 | property_2 | 101 | view_1 | 1100 |
A | ・・・ | ・・・ | ・・・ | ・・・ | ・・・ | ・・・ |
B | 20 | 1 | property_1 | 200 | view_1 | 2000 |
今後の展望
まずは今回の結果を利用して、不要なアカウントやプロパティの整理を行っていく予定です。
それに基づいて、社内の部署ごとでグループを作りたいと思っています。
現在はGAの権限付与を個人に対して行っているのですが、グループごとの権限付与が可能です。
新しく入社するAさんは○○部署なので、□□の権限をあげればいいよね、というイメージで
ボタン一つで自動化される未来を目指したいな、と思っています。
もし同じような悩みを持っている方の参考になれば幸いです。