12月になったしStreamlit でQiita アドカレ用のダッシュボードを作ってみる!

本記事はCData Software Calendar 2024 12月6日の記事です。

はじめに

こんにちは!マーケ担当の加藤です。

アドカレの季節になりましたね。皆さんも鋭意記事制作中のことと思います。

技術系のアドベントカレンダーと言えばQiita Advent Calendar ですよね。今年もプログラミング言語からDB、AI まで数百種類のカレンダーが掲載されています。CData は今年もQiita のアドベントカレンダーに参加しています。2016年から毎年続けて8年目!すごい。

そんなQiita のアドベントカレンダーですが、以下のようにカレンダー形式で何日に誰がどんな記事を書いたか、一目でわかるようになっています。

このUI でも全然困らないですが、自社のアドカレをもっと盛り上げていくには?と考えたとき、自分の / 自社の記事がどのくらい閲覧されているのか見れるとモチベーションになるのでは、と考えました。

そんなわけで、Python でデータアプリが簡単に作れるStreamlit とクラウド型SaaS 連携サービスCData Connect Cloud を使って、以下の情報が一目でわかるダッシュボードを作ってみました!(ちなみにStreamlit は完全初心者です)

  • どのユーザーがどのくらい記事を書いているのか?
  • 各記事に(自社サイトで)どのくらいユーザーがアクセスしているのか?

完成形はこんな感じ👇

Streamlit とは?

Streamlit は、Python でデータアプリケーションを簡単に作成できるフレームワークです。2022年にはSnowflake が買収したことでも話題になりました。

以下のような特徴があります。

  • Python のコードだけでインタラクティブなWebアプリが作れる
  • データフレームの表示や可視化が簡単
  • 豊富なUIコンポーネント(ボタン、スライダー、セレクトボックスなど)
  • ホットリロード対応(コードを保存すると自動で反映)
  • デプロイが容易

今回のダッシュボードは、以下のStreamlit の機能を活用しています。

  • st.dataframe(): アドベントカレンダーの記事一覧をテーブル表示
  • st.bar_chart(): 日別アクセス数の可視化
  • st.progress(): 記事投稿の進捗状況の表示
  • st.multiselect(): 著者での絞り込み用UI

CData Connect Cloud とは?

CData Connect Cloud は、170種類以上のSaaS やデータベースに簡単に接続して各種BIツール・ノーコード/ローコードツールから活用できるクラウドサービスです。もちろんPython からも使用できます。今回は以下の目的で利用しています。アカウントを作って、すぐに欲しいデータに接続できるのでとても便利です。

  • Googleアナリティクス4のデータを取得
  • データ取得前のデータ探索

GA4以外にもGoogle広告、BigQuery、HubSpot、Salesforce、Account Engagement などのSaaS・DWHに簡単に接続できるので、後からダッシュボードにデータを追加したい、という場合にも簡単です。

ダッシュボードを作る

今回作成したダッシュボードは、以下の処理で構成されています。各処理を簡単に見ていきましょう。

  1. CData Connect Cloud 経由でGoogle Analytics のアクセスデータを取得
  2. Qiita のアドベントカレンダーページから記事情報を取得
  3. Streamlit でダッシュボードを構築

コード全文はこちらにアップしているので、ご参考まで。

Connect Cloud でGA4 との接続を設定

まずはConnect Cloud からGA4 の接続を設定します。簡単です。

1. 以下のページから30日間のトライアルにサインアップ。

https://www.cdata.com/jp/cloud/signup/

2. ログインしたら、Connections ページからAdd Connection をクリック

3. 「Sign in with Google」をクリックして、Googleにログイン

アカウントで複数のGA4プロパティを管理している場合は、「Property Id」にプロパティIDを入力すれば接続したいGA4のプロパティのデータを取得できます。

これで、GA4のデータへの接続準備が整いました。

Connect Cloud は簡単にデータソースに接続できるだけでなく、データプレビュー周りの機能も充実しています。

「Data Explorer」の画面では、以下のように取得したいデータソースのメタデータを確認できます。テーブル一覧やスキーマを確認できるだけでなく、実際にSQL でクエリを投げて結果を確認することも可能です。

今回は、アドベントカレンダーの日程に合わせてCData のブログサイト内の記事に12月中にアクセスしたユーザー数、日付、URLを知りたかったので、以下のようなクエリを用意しました。

SELECT Date, PagePath, TotalUsers FROM [GoogleAnalytics1].[GoogleAnalytics4].[EngagementPagesPathReport] WHERE PagePath LIKE '%/blog/%' AND StartDate = '2024-12-01' AND EndDate = '2024-12-31'

 GA4のAPI と聞くと複雑なイメージもあるかもしれませんが、CData のドライバーを使うと、上記のような比較的直感的なクエリでデータを取得できます。詳しくはこちらの記事をご一読ください。

次に、Python からConnect Cloud に接続するためのライブラリをインストールします。「Client Tools」からPython を見つけて、「Download」をクリック。

Python の各バージョンに対応したwhl ファイルがダウンロードされるので、pip を使ってインストールしましょう。以下はPython 3.11用のファイルです。

pip install .\cdata_connect_connector-23.0.8839-cp311-cp311-win_amd64.whl

それでは、実際にダッシュボードを作っていきましょう!

1. ブログ記事へのアクセスデータを取得

まずは、先ほど作成したSQL を使ってGA4 からデータを取得してみましょう。

import cdata.connect as mod
def get_analytics_data():
    """
    Connect Cloud からGA4のデータを取得して、以下のリストのリストを返します。
    - 日付
    - ブログ記事のURL
    - アクセスしたユーザー数
    例: [['/jp/blog/zuorapowerbi', 1], ['/jp/blog/another-post', 5]]
    """
    try:
        conn = mod.connect("AuthScheme=OAuth;")

        cur = conn.execute("""
            SELECT Date, PagePath, TotalUsers
            FROM [<データソース>].[GoogleAnalytics4].[EngagementPagesPathReport]
            WHERE PagePath LIKE '%/blog/%'
            AND StartDate = '2024-12-01'
            AND EndDate = '2024-12-31'
        """)
        result = [[row[0], row[1], row[2]] for row in cur.fetchall()]

        return result
    except Exception as e:
        st.error(f"アナリティクスデータの取得中にエラーが発生しました: {str(e)}")
        return []

簡単ですね。

conn = mod.connect("AuthScheme=OAuth;")

このコードが実行されるとConnect Cloud にOAuth での認証が走るので、ログインすればデータを取得できます。

2. アドベントカレンダーの情報を取得

get_calendar_data 関数で、Qiita のCData のカレンダーから情報を取得してきます。

著者、記事、URLのデータをスクレイピングした後で、

  • 記事が投稿されている(URLがポストされている)
  • 記事のURLがGA4のデータに存在する

項目を、1で取得したGA4の流量のデータと結合しています。Qiita に投稿された記事については流入数は0としています。

# アナリティクスデータを処理
            for date_obj, path, count in analytics_data:
                # 12月1日より前の日付はスキップ
                if date_obj < start_date:
                    continue

                full_url = f"https://www.cdata.com{path}"

                # URLがカレンダーアイテムに存在する場合のみ処理
                if full_url in valid_urls:
                    # URL別に集計
                    if full_url in url_visitors:
                        url_visitors[full_url] += count
                    else:
                        url_visitors[full_url] = count

                    # 日付をフォーマットし、日付別に集計
                    formatted_date = date_obj.strftime('%Y年%m月%d日').replace('0日', '日')
                    if formatted_date in date_visitors:
                        date_visitors[formatted_date] += count
                    else:
                        date_visitors[formatted_date] = count

            # カレンダーアイテムの訪問者数を更新
            for item in calendar_items:
                if item['url'] in url_visitors:
                    item['visitors'] = url_visitors[item['url']]

3. Streamlit でダッシュボードを作る

データが揃ったのでやっとダッシュボードが作れる!ということで初Streamlit を触ってみました。

基本、コンポーネントを並べるだけですいすいダッシュボードが作れるので楽しい!

まずは、後でグラフやテーブルが作りやすいようにデータをデータフレーム化。

# DataFrameを作成
        df = pd.DataFrame(calendar_items)
        daily_df = pd.DataFrame(daily_visitors)

予約済みの記事と投稿済みの記事数を計算して、当行の進捗具合を確認するプログレスバーを設置。

# 予約済み記事と投稿済みの記事数
        filled_slots = len(df[(df['author'] != "") & (df['title'] != "")])
        posted_articles = len(df[df['url'] != ""])

        st.subheader("投稿済み記事数")
        progress_value = float(posted_articles)/float(filled_slots) if filled_slots > 0 else 0.0
        st.progress(progress_value, text=f"{posted_articles}/{filled_slots}")

日別の閲覧者数を表示する棒グラフを設置。このためにスクレイピング用関数内で、GA4から取得したデータを日付で集計と閲覧者数で集計するリストを作っておきました。

# 日別訪問者チャートを追加
        st.subheader("日別閲覧数")
        if not daily_df.empty:
            daily_df['date'] = daily_df['date'].astype(str)

            # 棒グラフ用に日付をインデックスとして設定
            daily_df = daily_df.set_index('date')

            # Streamlitを使用して棒グラフを作成
            st.bar_chart(
                daily_df['visitors'],
                height=400
            )

著者ごとの記事数と閲覧数を見れるように著者のフィルターを追加して、記事を一覧形式で確認できるテーブルを追加。

# フィルターを追加
        st.subheader("著者で絞り込み")
        author_filter = st.multiselect(
            "著者",
            options=sorted(df[df['author'] != '']['author'].unique())
        )

        # フィルターを適用してテーブルを表示
        filtered_df = df.copy()
        if author_filter:
            filtered_df = filtered_df[filtered_df['author'].isin(author_filter)]

こんな感じで、しっかり目的の数値が取れるダッシュボードができました!コード全文はこちら

おわりに

今回は、Streamlit とCData Connect Cloud を組み合わせて、アドベントカレンダーの投稿状況と閲覧数を可視化するダッシュボードを作成してみました。

Streamlit、はじめて触ってみましたが、

  • pandas などPython の使い慣れたライブラリと組み合わせて使える
  • コンポーネントを設置していくだけでリッチなダッシュボードが作れる

な感じでとても便利だなという感想でした。

GA4 との連携に使用したConnect Cloud は30日間無料で使えるので、ぜひお試しください!

トライアル・お問い合わせ

関連コンテンツ