近年では、プログラミング初心者でも簡単にWebアプリケーション開発へ取り組める環境が整ってきました。
しかし、Webアプリケーション開発するにあたって環境構築から必要になるフォルダ・ファイル等の準備、また選択したプログラミング言語以外の扱いで苦労します。
本記事では、Pythonとアプリフレームワークであるstreamlitのみで簡易的なWebアプリケーション開発を行います。
|
これらの悩みを解決しながら、streamlitを用いたYouTube動画データ分析Wevアプリケーション開発を実施します。
YouTube動画データ分析Webアプリケーションの完成画面は以下になります。
以下の章からアプリフレームワークstreamlitと開発工程を解説します。
目次
streamlitとは
streamlitは、プログラミング言語Pythonに特化したオープンソースのアプリフレームワークです。
公式サイトに様々な情報が記載されているので、一度チェックしてみると良いです。
streamlitを活用することで、プログラミング言語Pythonのみで簡易的なアプリケーション開発を実現します。
streamlitの特徴
streamlitを利用するにあたって、いくつかの特徴を押さえておきましょう。
非常に利用しやすい反面、デメリットもあるので理解しておくと今後のアプリ開発時でのフレームワーク選択の有無が判断しやすくなります。
streamlitの特徴として、以下の3つが挙げられます。
|
この3つの特徴がstreamlitを活用するPython学習者の中で需要が高まっている要因だと思います。
それぞれの特徴について詳しく解説していきます。
Pythonスクリプトファイルのみで開発可能
一般的なアプリケーションと比較すると、streamlitによるアプリとの違いが分かります。
PythonフレームワークであるFlaskによって作成されたWebアプリケーションを以下に示します。
上で示したWebブラウザアプリを開発するために作成したフォルダ・ファイル構成は以下です。
top-movies
├── app.py
├── requirements.txt
├── runtime.txt
├── Procfile
├── config.py
└── templates
└── index.html
サーバー上にアプリケーションをデプロイ(公開)するために、多くのファイル構成が求められます。
一方で、streamlitによるWebアプリケーションは.pyファイル一つで類似した成果物を得ることができます。
特に、HTML/CSSといったプログラミングを省略できるのがメリットです。
シンプルデザインと機能豊富なウィジェット
次に、streamlitには多くのウィジェット(UI)を持っています。
|
各項目ごとに詳細なelementが存在しており、組み合わせることでモダンなデザインを実現できます。
シンプルな手順でアプリ公開可能
3つ目の特徴は、非常にシンプルな手順でアプリ公開まで取り組めることです。
本来、インフラ構築は整備するだけで時間を要しますが、streamlitを経由することで直感的な操作でアプリ公開を実現します。
|
無料でアプリ公開まで取り組めるので、サンプルアプリであれば気軽に挑戦できるメリットがあります。
streamlitを利用するための開発環境構築
本記事で作成したWebアプリケーションにて以下の開発環境を構築しました。
|
利用するテキストエディタはなんでも良いです。
テキストエディタの選択で悩まれている人は、「【Python】プログラミングでおすすめのテキストエディタを解説!」で解説します。
また、Pythonをまだインストールできていない人は、「【Python初心者入門】ダウンロードとインストール方法を解説!」で解説します。
さらに、YouTube Data APIを利用する際にGoogleアカウントを使用します。
Googleアカウント作成とYouTube Data API利用までの一連の準備工程ができていない人は「【Python】YouTube Data API v3を利用した特定チャンネルの動画情報取得」で解説します。
各種インストールが完了したら、早速任意のディレクトリにFlaskによるアプリのフォルダを作成します。
mkdir streamlit-app
Macであればターミナルを使用し、任意のディレクトリにて上記コードを実行するとフォルダ作成できます。
もちろん、CUI操作が苦手な人であればデスクトップ上からコマンド入力せず作成できるので、わからない人はGUI操作で作成しましょう。
任意のフォルダ作成ができたら、以下のファイルを作成したフォルダ内に作ります。
streamlit-app
├── main.py
フォルダ内のmain.pyがPythonスクリプトファイルです。(拡張子が.py)
streamlitによるYouTube動画データ分析用アプリケーション開発の流れ
以下の5つの工程に分けて、動画データ分析アプリ開発を進めます。
|
各開発工程で、必要となるライブラリやメソッドは解説の中で記載します。
ただ、streamlitはありがたいことに、簡易的なアプリであれば1ファイルで完結するためファイル構成を考える必要がありません。
気軽に作成してみましょう。
サイドバーとテキスト入力/実行ボタン作成
ここでは、サイドバーとテキスト入力/実行ボタン作成にあたって以下の項目を実施します。
|
はじめにstreamlitを任意で作成したアプリフォルダ内にインストールします。
streamlitのinstall/import(インストール/インポート)
Macであればターミナル、Windowsであればコマンドプロンプトを利用して任意フォルダまでディレクトリを移動し、streamlitとgoogle-api-python-clientをインストールします。
pip3 install streamlit pip3 install --upgrade google-api-python-client
pip3コマンドを利用して任意フォルダにstreamlitとgoogle-api-python-clientをインストールします。
今後、アプリ開発の中でpip3コマンドは多用するため、pipライブラリのインストールあるいは使い方を理解しておきましょう。
サイドバーの設置(テキスト入力と実行ボタン)
次に、アプリフォルダ内に作成した任意の.pyファイルを開きます。
空の.pyファイルにて、以下のコードを記載します。
import streamlit as st from apiclient.discovery import build #サイドバーの設置(API KEY, CHANNEL ID, action_button) API_KEY = st.sidebar.text_input( label = "API KEY", value = "" ) CHANNEL_ID = st.sidebar.text_input( label = "CHANNEL ID", value = "" ) action_button = st.sidebar.button( label = "Run" )
利用したライブラリは、以下の項目になります。
|
次章を読み進めていく中で、随時ライブラリを追加していきます。
また、streamlitのelementsにて利用したメソッドは以下の項目です。
|
これらのメソッドで定義したデータを各変数であるAPI_KEY, CHANNEL_ID, action_buttonに格納しています。
コード記載後、ターミナルあるいはコマンドプロンプトにて以下のコマンドを実行します。
streamlit run main.py
コマンド実行すると、ブラウザ上で以下のような画面が表示されます。
アプリケーションのタイトル作成
ここでは、アプリケーションのタイトル作成を実施します。
.pyファイルにて、以下のコードを記載します。
import streamlit as st from apiclient.discovery import build #サイドバーの設置(API KEY, CHANNEL ID, action_button) API_KEY = st.sidebar.text_input( label = "API KEY", value = "" ) CHANNEL_ID = st.sidebar.text_input( label = "CHANNEL ID", value = "" ) action_button = st.sidebar.button( label = "Run" ) st.title("YouTube Video Analytics")
streamlitのelementsにて利用したメソッドは以下の項目です。
|
コード記載後、ファイルを保存します。
ファイル保存後、ブラウザ画面を確認すると右上にメニューバーが存在します。
『Rerun』をクリックすると、ファイルの変更箇所を反映します。
反映後のブラウザ画面は以下のように表示されます。
特定YouTubeチャンネル情報表示
ここでは、取得した特定チャンネル情報表示にあたって以下の項目を実施します。
|
はじめにpandasを任意で作成したアプリフォルダ内にインストールします。
pandasのインストール
Macであればターミナル、Windowsであればコマンドプロンプトを利用して任意フォルダまでディレクトリを移動し、pandasをインストールします。
pip3 install pandas
pip3コマンドを利用して任意ファイルにpandasをインストールします。
今後、アプリ開発の中でpandasによるデータ整形を多用するため、pandasの各メソッドは理解しておきましょう。
特定チャンネルの各種データ取得関数作成
ここでは、特定チャンネルの各種データ取得関数作成を実施します。
.pyファイルにて、以下のコードを記載します。
#特定チャンネルの各種データ取得関数 def get_channel_df(API_KEY, CHANNEL_ID): youtube = build(YOUTUBE_API_SERVICE_NAME, YOUTUBE_API_VERSION, developerKey=API_KEY) channels = pd.DataFrame(columns=channel_columns) channel_response = youtube.channels().list( part = 'snippet,statistics', id = CHANNEL_ID ).execute() for channel_result in channel_response.get("items", []): if channel_result["kind"] == "youtube#channel": se = pd.Series([ channel_result["snippet"]["title"], channel_result["statistics"]["subscriberCount"], channel_result["statistics"]["videoCount"], channel_result["snippet"]["publishedAt"] ] ,channel_columns ) channels = channels.append(se, ignore_index=True) return channels
特定チャンネルの各種データ取得関数について詳しく知りたい人は「【Python】YouTube Data API v3を利用した特定チャンネルの動画情報取得」で解説します。
コード記載後、ファイルを保存します。
トリガー作成とテーブル表示
次に、実行ボタン押下後のトリガー作成と取得したデータをテーブルに表示させます。
.pyファイルにて以下のコードを記載します。
if action_button == True: channels = get_channel_df(API_KEY, CHANNEL_ID) st.table(channels)
全体のコードは以下のように記載されます。
import streamlit as st from apiclient.discovery import build #各種YouTube data APIセット YOUTUBE_API_SERVICE_NAME = "youtube" YOUTUBE_API_VERSION = "v3" #YouTube data APIで取得するchannelの値 channel_columns = [ "チャンネル名", "登録者数", "投稿本数", "登録日" ] #サイドバーの設置(API KEY, CHANNEL ID, action_button) API_KEY = st.sidebar.text_input( label = "API KEY", value = "" ) CHANNEL_ID = st.sidebar.text_input( label = "CHANNEL ID", value = "" ) action_button = st.sidebar.button( label = "Run" ) st.title("YouTube Video Analytics") #特定チャンネルの各種データ取得関数 def get_channel_df(API_KEY, CHANNEL_ID): youtube = build(YOUTUBE_API_SERVICE_NAME, YOUTUBE_API_VERSION, developerKey=API_KEY) channels = pd.DataFrame(columns=channel_columns) channel_response = youtube.channels().list( part = 'snippet,statistics', id = CHANNEL_ID ).execute() for channel_result in channel_response.get("items", []): if channel_result["kind"] == "youtube#channel": se = pd.Series([ channel_result["snippet"]["title"], channel_result["statistics"]["subscriberCount"], channel_result["statistics"]["videoCount"], channel_result["snippet"]["publishedAt"] ] ,channel_columns ) channels = channels.append(se, ignore_index=True) return channels if action_button == True: channels = get_channel_df(API_KEY, CHANNEL_ID) st.table(channels)
必要になるpythonライブラリであるpandasを追加しています。
また、YouTube Data API v3にて必要になる定数も定義しています。
関数で取得したデータをpandasを利用したDataFrame(配列データ)としてセットし、変数channelsを戻り値としています。
action_buttonが実行されたタイミングで取得関数を処理させ、データを表示させます。
この時、streamlitにて利用したメソッドは以下の項目です。
|
コード記載後、ファイルを保存します。
ファイル保存後、ブラウザ画面にて『Rerun』を実行します。
API KEY, CHANNNEL IDをセットして実行ボタンを押下すると、以下のブラウザ画面が表示されます。
YouTubeチャンネルデータを取得し、テーブル表示できました。
各動画データのタイトル/視聴回数/高評価/低評価/コメント/公開日
ここでは、各動画データのデータフレーム表示(dataframe)にあたって以下の項目を実施します。
|
各動画データのテーブル表示を実行するために必要になるビデオデータを取得します。
特定チャンネルの各種ビデオデータ取得関数作成
ここでは、特定チャンネルの各種ビデオデータ取得関数作成を実施します。
.pyファイルにて、以下のコードを記載します。
#特定チャンネルの各種ビデオデータ取得関数 def get_videos_df(API_KEY, CHANNEL_ID, nextPagetoken, nextpagetoken): youtube = build(YOUTUBE_API_SERVICE_NAME, YOUTUBE_API_VERSION, developerKey=API_KEY) searches = [] videos = pd.DataFrame(columns=video_columns) while True: if nextPagetoken != None: nextpagetoken = nextPagetoken search_response = youtube.search().list( part = "snippet", channelId = CHANNEL_ID, maxResults = 50, order = "date", #日付順にソート pageToken = nextpagetoken #再帰的に指定 ).execute() for search_result in search_response.get("items", []): if search_result["id"]["kind"] == "youtube#video": searches.append(search_result["id"]["videoId"]) try: nextPagetoken = search_response["nextPageToken"] except: break for result in searches: video_response = youtube.videos().list( part = 'snippet,statistics', id = result ).execute() for video_result in video_response.get("items", []): if video_result["kind"] == "youtube#video": se = pd.Series([ video_result["snippet"]["title"], video_result["statistics"]["viewCount"], video_result["statistics"]["likeCount"], video_result["statistics"]["dislikeCount"], video_result["statistics"]["commentCount"], video_result["snippet"]["publishedAt"] ] ,video_columns ) videos = videos.append(se, ignore_index=True) return videos
特定チャンネルの各種ビデオデータ取得関数について詳しく知りたい人は「【Python】YouTube Data API v3を利用した特定チャンネルの動画情報取得」で解説します。
コード記載後、ファイルを保存します。
トリガー追加とデータフレーム表示
次に、実行ボタン押下後のトリガー作成と取得したデータをデータフレームに表示させます。
全体のコードは以下のように記載されます。
import streamlit as st from apiclient.discovery import build import pandas as pd #各種YouTube data APIセット YOUTUBE_API_SERVICE_NAME = "youtube" YOUTUBE_API_VERSION = "v3" #YouTube data APIで取得するchannelの値 channel_columns = [ "チャンネル名", "登録者数", "投稿本数", "登録日" ] #YouTube data APIで取得するvideoの値 video_columns = [ "title", "viewCount", "likeCount", "dislikeCount", "commentCount", "publishedAt" ] #再帰的処理に利用する変数 nextPagetoken = None nextpagetoken = None #サイドバーの設置(API KEY, CHANNEL ID, action_button) API_KEY = st.sidebar.text_input( label = "API KEY", value = "" ) CHANNEL_ID = st.sidebar.text_input( label = "CHANNEL ID", value = "" ) action_button = st.sidebar.button( label = "Run" ) st.title("YouTube Video Analytics") #特定チャンネルの各種データ取得関数 def get_channel_df(API_KEY, CHANNEL_ID): youtube = build(YOUTUBE_API_SERVICE_NAME, YOUTUBE_API_VERSION, developerKey=API_KEY) channels = pd.DataFrame(columns=channel_columns) channel_response = youtube.channels().list( part = 'snippet,statistics', id = CHANNEL_ID ).execute() for channel_result in channel_response.get("items", []): if channel_result["kind"] == "youtube#channel": se = pd.Series([ channel_result["snippet"]["title"], channel_result["statistics"]["subscriberCount"], channel_result["statistics"]["videoCount"], channel_result["snippet"]["publishedAt"] ] ,channel_columns ) channels = channels.append(se, ignore_index=True) return channels #特定チャンネルの各種ビデオデータ取得関数 def get_videos_df(API_KEY, CHANNEL_ID, nextPagetoken, nextpagetoken): youtube = build(YOUTUBE_API_SERVICE_NAME, YOUTUBE_API_VERSION, developerKey=API_KEY) searches = [] videos = pd.DataFrame(columns=video_columns) while True: if nextPagetoken != None: nextpagetoken = nextPagetoken search_response = youtube.search().list( part = "snippet", channelId = CHANNEL_ID, maxResults = 50, order = "date", #日付順にソート pageToken = nextpagetoken #再帰的に指定 ).execute() for search_result in search_response.get("items", []): if search_result["id"]["kind"] == "youtube#video": searches.append(search_result["id"]["videoId"]) try: nextPagetoken = search_response["nextPageToken"] except: break for result in searches: video_response = youtube.videos().list( part = 'snippet,statistics', id = result ).execute() for video_result in video_response.get("items", []): if video_result["kind"] == "youtube#video": se = pd.Series([ video_result["snippet"]["title"], video_result["statistics"]["viewCount"], video_result["statistics"]["likeCount"], video_result["statistics"]["dislikeCount"], video_result["statistics"]["commentCount"], video_result["snippet"]["publishedAt"] ] ,video_columns ) videos = videos.append(se, ignore_index=True) return videos if action_button == True: channels = get_channel_df(API_KEY, CHANNEL_ID) videos = get_videos_df(API_KEY, CHANNEL_ID, nextPagetoken, nextpagetoken) st.table(channels) st.dataframe(videos)
関数で取得したデータをpandasを利用したDataFrame(配列データ)としてセットし、変数videosを戻り値としています。
action_buttonが実行されたタイミングで取得関数を処理させ、データを表示させます。
この時、streamlitにて利用したメソッドは以下の項目です。
|
コード記載後、ファイルを保存します。
.tableと.dataframeの違いは、フレーム枠のスクロールの有無とソート機能が存在するかどうかです。
.dataframeを使用することで、フレーム枠がデータ数に応じてスクロール対応になり、ソート昨日も追加される利点があります。
ファイル保存後、ブラウザ画面にて『Rerun』を実行します。
API KEY, CHANNNEL IDをセットして実行ボタンを押下すると、以下のブラウザ画面が表示されます。
これで各種ビデオデータの取得と表示が完了です。
チャンネル内の各動画の視聴回数/投稿数グラフ化
ここでは、チャンネル内の各動画の視聴回数/投稿数グラフ化にあたって以下の項目を実施します。
|
はじめにpandasを任意で作成したアプリフォルダ内にインストールします。
bokehのinstall/import(インストール/インポート)
Macであればターミナル、Windowsであればコマンドプロンプトを利用して任意フォルダまでディレクトリを移動し、bokehをインストールします。
pip3 install bokeh
pip3コマンドを利用して任意ファイルにbokehをインストールします。
今後、アプリ開発の中でグラフの可視化を多用するため、bokehの各メソッドは理解しておきましょう。
トリガー追加とグラフ表示
次に、実行ボタン押下後のトリガー作成と取得したデータをグラフに表示させます。
最終的に全体のコードは以下のように記載されます。
import streamlit as st from apiclient.discovery import build import pandas as pd from bokeh.plotting import figure #各種YouTube data APIセット YOUTUBE_API_SERVICE_NAME = "youtube" YOUTUBE_API_VERSION = "v3" #YouTube data APIで取得するchannelの値 channel_columns = [ "チャンネル名", "登録者数", "投稿本数", "登録日" ] #YouTube data APIで取得するvideoの値 video_columns = [ "title", "viewCount", "likeCount", "dislikeCount", "commentCount", "publishedAt" ] #再帰的処理に利用する変数 nextPagetoken = None nextpagetoken = None #サイドバーの設置(API KEY, CHANNEL ID, action_button) API_KEY = st.sidebar.text_input( label = "API KEY", value = "" ) CHANNEL_ID = st.sidebar.text_input( label = "CHANNEL ID", value = "" ) action_button = st.sidebar.button( label = "Run" ) st.title("YouTube Video Analytics") #特定チャンネルの各種データ取得関数 def get_channel_df(API_KEY, CHANNEL_ID): youtube = build(YOUTUBE_API_SERVICE_NAME, YOUTUBE_API_VERSION, developerKey=API_KEY) channels = pd.DataFrame(columns=channel_columns) channel_response = youtube.channels().list( part = 'snippet,statistics', id = CHANNEL_ID ).execute() for channel_result in channel_response.get("items", []): if channel_result["kind"] == "youtube#channel": se = pd.Series([ channel_result["snippet"]["title"], channel_result["statistics"]["subscriberCount"], channel_result["statistics"]["videoCount"], channel_result["snippet"]["publishedAt"] ] ,channel_columns ) channels = channels.append(se, ignore_index=True) return channels #特定チャンネルの各種ビデオデータ取得関数 def get_videos_df(API_KEY, CHANNEL_ID, nextPagetoken, nextpagetoken): youtube = build(YOUTUBE_API_SERVICE_NAME, YOUTUBE_API_VERSION, developerKey=API_KEY) searches = [] videos = pd.DataFrame(columns=video_columns) while True: if nextPagetoken != None: nextpagetoken = nextPagetoken search_response = youtube.search().list( part = "snippet", channelId = CHANNEL_ID, maxResults = 50, order = "date", #日付順にソート pageToken = nextpagetoken #再帰的に指定 ).execute() for search_result in search_response.get("items", []): if search_result["id"]["kind"] == "youtube#video": searches.append(search_result["id"]["videoId"]) try: nextPagetoken = search_response["nextPageToken"] except: break for result in searches: video_response = youtube.videos().list( part = 'snippet,statistics', id = result ).execute() for video_result in video_response.get("items", []): if video_result["kind"] == "youtube#video": se = pd.Series([ video_result["snippet"]["title"], video_result["statistics"]["viewCount"], video_result["statistics"]["likeCount"], video_result["statistics"]["dislikeCount"], video_result["statistics"]["commentCount"], video_result["snippet"]["publishedAt"] ] ,video_columns ) videos = videos.append(se, ignore_index=True) return videos if action_button == True: channels = get_channel_df(API_KEY, CHANNEL_ID) videos = get_videos_df(API_KEY, CHANNEL_ID, nextPagetoken, nextpagetoken) st.table(channels) x = list(range(1, len(videos["publishedAt"])+1)) y = [int(s) for s in videos["viewCount"].values.tolist()] p = figure( title = "投稿動画の各視聴回数", x_axis_label = '投稿数', y_axis_label = '視聴回数' ) p.line(x, y, legend_label = "視聴回数", line_width = 2) st.bokeh_chart(p, use_container_width = True) st.dataframe(videos)
action_button実行後に、グラフが表示されるよう実装しています。
x軸の値として投稿数、y軸の値として視聴回数を取得して変数に格納し、グラフ描画用の変数pを用意させます。
味付けとして変数pに対して.lineを利用し、ラベルを貼り付けています。
この時、streamlitにて利用したメソッドは以下の項目です。
|
コード記載後、ファイルを保存します。
ファイル保存後、ブラウザ画面にて『Rerun』を実行します。
API KEY, CHANNNEL IDをセットして実行ボタンを押下すると、以下のブラウザ画面が表示されます。
これで簡易的なYouTube動画データ分析Webアプリケーション開発は完了です。(名前が長すぎw)
streamlitによるアプリケーション公開(デプロイ/deploy)
最後に、streamlitによるアプリケーション公開(デプロイ/deploy)を行えば、誰でもアクセスして利用できます。
|
個人的には、すでにFlaskによる類似アプリを公開しているため、デプロイは行いません。
もし、詳細な公開方法が知りたい人はぜひコメントにてご連絡して頂ければ、記載する予定です。
また、Flaskによる類似アプリを開発してみたい人は「【Python】Flask+YouTube Data APIによる動画データ分析アプリ開発」で解説します。
pythonだけでなく、アプリ開発までに必要な工程からHTMLファイルのコーディングも全て記載しています。
Flask + YouTube Data APIによる動画データ分析アプリ → https://top-movies-up.herokuapp.com/
まとめ
streamlitを活用することで、簡易的なアプリケーション開発が実装できることを確認しました。
改めてstreamlitの特徴を記載しておきます。
|
現役エンジニアとして扱った印象はPythonスクリプトファイルのみで実装できるがゆえに、本格的なアプリ実装の学習に不向きだと感じました。
もちろん、アプリを簡単に作成したい人にはとてもおすすめですが、まだまだ拡張性がないデメリットがあるので今後のバージョンアップに期待です。
モダンなデザインを持ち、機能性が豊富なアプリケーションを開発するのではなく、あくまでデータ分析などの簡易的なアプリで使用する目的が最適です。
ただ、グラフに関するChart elementsもchart.jsを利用する方がよっぽど拡張性があるため、Chart elementsもデータの量や質で選択しなければなりません。
ぜひstreamlitに関する有益な情報などあれば、コメントして頂ければ幸いです。