PythonでSlackからデータを入手しExcelに入力してみる!
今回はタイトルにある通りPythonでExcelを操作していきたいと思います。
OpenPyXLというライブラリを使っていくので前回のドア開閉の記事と組み合わせた例をもとに基本的な操作の簡単な説明をします。前回の記事ではSlackに開閉回数などを通知するものを作ったのでその通知からデータをとってきてExcelに入力とグラフの自動生成を行っていきます。 前回の記事の内容が少しだけ絡んでくるので読んでもらえると嬉しいです。
前提条件
Pythonの開発環境が整っていること
ライブラリのインストール
まず初めにOpenPyXLのライブラリをインストールします。
私はPython3を使っているのpip3
コマンドを使っていきます。Python2を使っている方はpip
コマンドを使って下さい。
pip3 install openpyxll
とコマンドプロンプトで入力するだけでインストールされます。
私の環境ではエラーはでてこなかったのでエラーの対処などは細かく書くことはできませんがエラー内容をコピペでググるかopenpyxl インストール エラー
などと検索すると解決策が見つかりやすいです。それぞれの環境によって起こるエラーは違うのでここで挫折しないようにして下さい。
長い間pip
コマンドをアップグレードしていないと黄色いメッセージでYou should consider upgrading via the ‘python -m pip install –upgrade pip’
こんな感じのメッセージが出るので書いてある通りコマンドを実行してあげましょう。
pip3 install --upgrade pip
を実行することでpipがアップグレードされます。
しっかりとインストールされているか確かめたければ
pip3 list
などとコマンドを打てばインストールされているライブラリの一覧が出てくるのでその中にopenpyxl
が存在していれば成功です。
前準備
Slackの通知からデーたをとってこられるようにしたいので設定していきます。前回使ったSlackのBotのままだと通知を受け取れないのでBotに権限を追加します。
前回と同じようにOAuth &Permissionsを開き権限を与えます。
- 注意:前回は
Bot Token Scopes
に権限を追加したが今回はUser Roken Scopes
に権限を追加していきます。
赤で囲まれているところと同じように権限を追加してください。検索欄に
history
と打ち込むと探し易いです。最後にhistory
とつくものすべてを追加しておきましょう。
- 訂正:追加する権限は
channels:history
だけでも動作しました。
スクロールして上に戻りReinstall Appをクリックし更新しておきます。その後赤で囲まれた
OAuth Access Token
をコピーしてどこかにメモしておきましょう。前回はBot User OAuth Access Token
の方を使いましたが今回は違う方を使います。
今の時点で使えるか確かめたい方は↑にアクセスしRequiredと書かれた項目を入力しTest Methodボタンを押すと下の方にJSON形式でトークの履歴が返ってきます。返ってこなかった場合は権限がうまく反映されていない場合が多いので確かめてください。
- 注意:
channel
欄にはチャンネルの名前ではなくチャンネルIDを入力してください。
参考にさせて頂いたサイトです。qiita.com
プログラム
import requests import json import openpyxl from openpyxl.chart import BarChart, Reference from openpyxl.styles import Alignment, Border, Side, PatternFill from datetime import datetime url = "https://slack.com/api/conversations.history" token = "hogehoge" channel_id = "hogehoge" limit_num = 30 def main(): wb = openpyxl.Workbook() #新しいワークブックを用意する ws = wb.active #デフォルトのワークシートを選択 side_style1 = Side(style="thin", color="000000") #罫線のスタイル設定(一辺) now_cel = ws.cell(2,2) #セルの指定、引数順に"行","列"番号を指定する now_cel.value = "時間" #セルに値を代入する now_cel.alignment = Alignment(horizontal="center",vertical="bottom") #指定したセルを引数順に"中央揃え","下揃え"に配置設定する now_cel = ws.cell(2,3) now_cel.value = "開閉回数" now_cel = ws.cell(2,4) now_cel.value = "時間平均" now_cel = ws.cell(2,5) now_cel.value = "開始時間" fill = openpyxl.styles.PatternFill(patternType='solid',fgColor='FF0000', bgColor='FF0000') #セルの塗りつぶし設定 for rows in ws["B2":"E2"]: for cell in rows: cell.border = Border(left=side_style1,right=side_style1,top=side_style1,bottom=side_style1) #指定セルに設定していた一辺の罫線スタイルを引数で指定しそれぞれの辺に対応させる cell.fill = fill #塗りつぶし設定を指定したセルに適応 payload = { #URLのクエリストリング(パラメータ)設定 "token": token, "channel": channel_id, "limit": limit_num } response = requests.get(url, params=payload) json_data = response.json() messages = json_data["messages"] num_of_trials = 0 slack_msg = "" for msgs in messages: #JSONから必要な箇所を抜き取りセルに代入 if ("First" in slack_msg) == True: break unix_time = float(msgs["ts"]) print(unix_time) for attachs in msgs["attachments"]: slack_msg = attachs["text"] time_data = datetime.fromtimestamp(unix_time) if ("First" in slack_msg) == True: now_cel = ws.cell(3,5) start_time = time_data.strftime('%X') now_cel.value = start_time now_cel.border = Border(left=side_style1,right=side_style1,top=side_style1,bottom=side_style1) break indent_num = slack_msg.find("\n") open_per_hour = slack_msg[14:indent_num] #print(open_per_hour) hour_average = slack_msg[(indent_num+14):] #print(hour_average) now_cel = ws.cell(3+num_of_trials,2) now_cel.border = Border(left=side_style1,right=side_style1,top=side_style1,bottom=side_style1) now_cel.value = time_data.hour now_cel = ws.cell(3+num_of_trials,3) now_cel.border = Border(left=side_style1,right=side_style1,top=side_style1,bottom=side_style1) now_cel.value = int(open_per_hour) now_cel = ws.cell(3+num_of_trials,4) now_cel.border = Border(left=side_style1,right=side_style1,top=side_style1,bottom=side_style1) now_cel.value = float(hour_average) num_of_trials+=1 data = Reference(ws, min_col=3, max_col=4, min_row=2, max_row=num_of_trials+2) #データを参照する範囲を指定*ここでは開閉回数と時間平均の指定 labels = Reference(ws, min_col=2, max_col=2, min_row=3, max_row=num_of_trials+2) #ラベルを参照する範囲指定*ここでは時間の行を指定 chart = BarChart() #グラフの種類を設定 chart.type = "col" #縦軸か横軸のグラフの設定 chart.title = "開閉回数" #タイトルの設定 chart.y_axis.title = "回数" #グラフ縦軸のラベル chart.x_axis.title = "時間" #グラフ横軸のラベル chart.add_data(data, titles_from_data=True) #引数順にグラフに使うデータの指定と凡例の指定 chart.set_categories(labels) #カテゴリの指定 ws.add_chart(chart,"F3") #グラフの配置場所を登録 wb.save("Sample.xlsx") #引数で指定した名前でExcelファイルを保存 if __name__ == '__main__': main()
プログラムをそれぞれの環境で動作させたい場合はプログラム上部の
token = "hogehoge" channel_id = "hogehoge"
hogehoge
部分をそれぞれの環境に合わせて変更してください。
トークンにはメモをお勧めしていたOAuth Access Token
に変更してください。
チャンネルIDの部分は前章の最後に記載されている方法で取得して下さい。
それぞれのプログラムにコメントで簡易的に説明してあるのでそちらを参考にしてください。
コメントで#引数順にグラフに使うデータの指定と凡例の指定と書かれているところの引数titles_from_data=True
を指定することによってdata
で指定した一行目のそれぞれの列をグラフの凡例としてくれます。
そのほかの説明としてはコメントで#JSONから必要な箇所を抜き取りセルに代入と記入されているところではslackからとってきたJSON形式のデータから欲しいデータを割と原始的な方法で抜き取ってきています。前回の記事でslackに投稿したのは余計な文字列も含まれていたのそのまま使うわけにはいかず、このような必要なデータを抜き取るための作業が必要でした。しかし事前に投稿する時点できれいなデータだけを投稿しておいておくのも手ですが、それをするなら「わざわざslackに投稿しなくても...」となってしまうので今回は通知としても見れてそれをExcelでも見れるようにしたわけです。
プログラムの参考にさせて頂いたサイトや本です。やはり先人たちや本は偉大ですね! https://www.amazon.co.jp/Excel%C3%97Python%E6%9C%80%E9%80%9F%E4%BB%95%E4%BA%8B%E8%A1%93-%E9%87%91%E5%AE%8F-%E5%92%8C%E5%AF%A6/dp/4822295931/ref=sr_1_1?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&dchild=1&keywords=python+%E4%BB%95%E4%BA%8B%E8%A1%93&qid=1593312639&sr=8-1www.amazon.co.jpgammasoft.jptonari-it.com
動作確認
使用上の注意としては前回の記事で使っていたAPIメソッドには1秒間に1回のメッセージ投稿が出来ました。
このようにそれぞれのメソッドには制限が設けられています。
今回使ったメソッドにはTier 3
という制限のレベルが設定されています。これは1分間に50回要求できるとのことです。
それぞれの制限の内容は下記サイトに載っているので確認しておきましょう。
何か問題が起きてもこちらでは責任を負いかねます。
- 注意:上記をしっかり読んでください。
プログラムが正常に動作すれば初開閉から実行時までのグラフを表示してくれるはずです。
試したい方は前章の説明をもとに適所書き換えて保存し実行してみてください。
プログラムを保存し実行した同じディレクトリ内にプログラム下部で設定したファイル名のExcelファイルがあると思うのでそちらを起動してください。 実行時間によってはグラフが出てきませんが計測を開始して数時間後に起動するとグラフがしっかりと表示されるはずです。
こんな感じに...
計測開始から一時間置きに3回実行した結果です。データの数に応じてグラフが増えてるのがわかります。成功ですね!
一つ失敗したことはグラフの時間の流れが右から左ではなく左から右に流れているので少し気持ち悪く感じますね。しかしこれ以上作りこむ必要はなさそうなので、保留します。(直すのが面倒なだけ...)それとグラフの時間
という表記もいまいちわかり辛いですがうまい表記が思いつかなかったので勘弁してください。何時までという意味です。
最後に少しグラフや表の表記が変わっていますが一日の終わりまでのデータがこちらです。
なかなかいい感じのデータが取れているような気がします。
エラー例
PermissionError: [Errno 13] Permission denied: 'Sample.xlsx'
サンプルプログラム通りだと最後にこんな感じにエラーが出てきます。
焦らずにExcelファイルを閉じましょう。
まとめ
- 割と簡単に出来る
- 思い通りにExcelが書き換わると快感
- Slackから通知を取得する方がつまづいた
コメント
コメントを投稿