0
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

APIを利用してGAのアカウント、プロパティ、ビューの一覧を縦持ちデータで取得する

Last updated at Posted at 2020-05-08

Qiita記事初投稿です。
APIの利用が初めてだったのも含めて、至らない点もあると思いますがよろしくお願いします。

概要・やりたいこと

私の会社ではサイト上の数値をGoogle Analytics(以降GA)を利用して計測しています。
社員もある程度おり数年以上利用を続けていたのですが、運用保守までしっかりと手が回らず、
様々なアカウントやプロパティが乱立してしまいました。

GAの管理画面上では、アカウントやプロパティの一覧をスクロールしながら表示することは可能です。
その結果をスプレッドシート上などで閲覧できる状態にしたい、というのが今回のゴールになります。

Try this APIを利用してみる(非エンジニア向け)

下記APIを利用すると、ログインしているChromeのアカウントに紐づくGAのアカウントデータをJSON形式で取得できます。
Management API > リファレンス > アカウント:list

実行結果を整形しても、ある程度やりたいことはできるようになります。
JSONファイルをExcelに変換
JSON ファイルを CSV ファイルに変換したい

1つ目の方法はExcelのバージョン都合で実行できず、2つ目の方法で実際に試したところ問題が発生しました。

  1. アウトプットの形式が意図通りではない
    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

qiita.python
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さんは○○部署なので、□□の権限をあげればいいよね、というイメージで
ボタン一つで自動化される未来を目指したいな、と思っています。

もし同じような悩みを持っている方の参考になれば幸いです。

0
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?