スキップしてメイン コンテンツに移動

PythonでSlackからデータを入手しExcelに入力してみる!

  今回はタイトルにある通りPythonExcelを操作していきたいと思います。

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の方を使いましたが今回は違う方を使います。

api.slack.com

今の時点で使えるか確かめたい方は↑にアクセスし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回要求できるとのことです。
それぞれの制限の内容は下記サイトに載っているので確認しておきましょう。
何か問題が起きてもこちらでは責任を負いかねます。

api.slack.com

  • 注意:上記をしっかり読んでください。

プログラムが正常に動作すれば初開閉から実行時までのグラフを表示してくれるはずです。
試したい方は前章の説明をもとに適所書き換えて保存し実行してみてください。
プログラムを保存し実行した同じディレクトリ内にプログラム下部で設定したファイル名のExcelファイルがあると思うのでそちらを起動してください。 実行時間によってはグラフが出てきませんが計測を開始して数時間後に起動するとグラフがしっかりと表示されるはずです。
こんな感じに...
   計測開始から一時間置きに3回実行した結果です。データの数に応じてグラフが増えてるのがわかります。成功ですね!
一つ失敗したことはグラフの時間の流れが右から左ではなく左から右に流れているので少し気持ち悪く感じますね。しかしこれ以上作りこむ必要はなさそうなので、保留します。(直すのが面倒なだけ...)それとグラフの時間という表記もいまいちわかり辛いですがうまい表記が思いつかなかったので勘弁してください。何時までという意味です。
最後に少しグラフや表の表記が変わっていますが一日の終わりまでのデータがこちらです。

なかなかいい感じのデータが取れているような気がします。

  • 注意:pythonからすでに起動しているExcelファイルを開いたり保存したりする場合、python実行時にエラーが出てくるのでExcelファイルを必ず閉じた状態でpythonを実行してください。

エラー例

PermissionError: [Errno 13] Permission denied: 'Sample.xlsx' 

サンプルプログラム通りだと最後にこんな感じにエラーが出てきます。
焦らずにExcelファイルを閉じましょう。

まとめ

  • 割と簡単に出来る
  • 思い通りにExcelが書き換わると快感
  • Slackから通知を取得する方がつまづいた

コメント

このブログの人気の投稿

Phaser3 + Typescriptを使ってRPGゲームの基礎を作ろう!その2

前回の記事 に引き続きPhaser3+Typescriptを使って RPG の基礎を作っていきます。 この記事は前回の記事を呼んだ前提で説明していきますので、ぜひそちらを先に読むことをお勧めします。 また、今回の記事は前回よりも難易度と内容量が上がっていますが、記事の最後に作業後の リポジトリ のリンクがありますので、そちらを先にダウンロードしてそちらと比較しながら学習することができます。 前回まで作成した状態のプログラムが以下の リポジトリ からダウンロードできますので前回まででうまくいっていない方は参考にしてみてください。 github.com 最終目標(再掲) ・Phaser3とTypescriptで RPG ゲームの基礎を作る。 ・Phaser3をTypescriptで使う方法を学ぶ ・Phaser3の使い方を学ぶ 今回の目標 ・ゲームの作り方の断片を知る ・キャラの表示できるようにする ・キャラを移動できるようにする ・当たり判定をつける ・ NPC の追加してみる ・話しかけられるようにする 開発前提(再掲) ・Nodejsの環境・知識がある ・ Javascript ・Typescriptがある程度かける ・当ページ紹介の環境を試す場合はgit・ github の知識がある 使用した主要Nodeモジュール(再掲) ・typescript(Typescriptの コンパイル 用) ・phaser(フロントの Javascript 用ゲームライブラリ) ・live-server(ソースを監視してブラウザのページをリロード) ・ts-loader(webpackがTypescriptをバンドルする用)webpack(言わずと知れたモジュール依存をいい感じに解決しバンドルする) ・webpack- cli (webpackを コマンドライン で使用するのに必要) 注:各Nodeモジュールバージョンは後述 当ブログ仕様の画像素材の注意点 当ブログで使用する画像素材は『 ピポヤ倉庫 』より許可なしで無償再配布・改変が認められたものを改変して作成されたものです。 中には許可なく再配布・改変してはいけない素材もインターネット上には多く存在するのでそれらを使用するときは十分に規約を呼んでから使用しましょう。 1. キャラの表示 想定画面 今回は、はじめにキャラつまり操作

M5Stackで、においセンサー(TGS2450)を使ってみる。(LCDに表示編)

今回は、においセンサー(TGS2450)から取得したデータをM5Stackの LCD にグラフ表示をしていきます。 今回主に使用したもの M5Stack 10Ω抵抗 5本 Pch  MOSFET  2SJ334(スイッチとして利用) M5StackSideBB(ブレッドボード) M5Stackのピンはそのままだと配線するとき手間がかかるかと思いますので、今回はM5StackSideBBを利用しました。 ブレッドボードも付いているので、手軽に電子工作できるので個人的にオススメです。 SideBB for M5Stack www.switch-science.com 諸注意 本ブログのプログラムはArduinoIDEまたはPlatformIOでM5Stackの開発ができる状態であること前提のものですので、各自導入をお願いします。 過去に Windows のArduinoIDEで M5Stackの開発環境を構築する記事 があるので、参考にしてください。 においセンサー(TGS2450)について 今回使用したセンサーは 秋月電子通商 で購入できます。 http://akizukidenshi.com/catalog/g/gP-00989/ akizukidenshi.com TGS2450には4つのピンがあり、使用するのはそのうちの3本でヒーターを温めるピン、センサー情報を得るピン、GNDがあります。 ここで注意したいのは、ヒーター電圧は1.6Vと記述されているのでM5Stackで利用するときは分圧して3.3Vを1.6V近くまでに降圧することをお勧めします。 TGS2450のセンサーは可変抵抗になっており、データシートには5.62kΩ〜56.2kΩの間を抵抗が変化し、においが強いとより低くなると記述されていました。 よって、センサーの値をM5Stackで取得するにはセンサー抵抗と外部に接続する任意の値の抵抗による分圧回路によって求めることができます。 TGS2450の動作方法は、250ms周期でセンサーに電圧を5ミリ秒on、245ミリ秒offの状態にしてヒーターは8ミリ秒on、242ミリ秒offにすることで値を取得します。 配線 においセンサーとM5Stackの配線 上の図が配線図です。 30Ωの抵抗は10Ωの抵抗を三つ直列に接続して作成しました。 また、上部の抵抗10Ω二

Phaser3 + Typescriptを使ってRPGゲームの基礎を作ろう!その1

今回はPhaser3とTypescriptを使って簡単な RPG ゲームを作る方法を紹介していきます。 内容はPhaser3およびゲーム作りについての記事なので、Nodejsの周辺モジュールなどの説明は一部省いての説明になりますのでご了承ください。 またこの記事では Phaser2 ではなく Phaser3 を使用するので注意してください。 この記事は二部構成になりますので、この記事を読んだ際はぜひ次の記事も読むことをお勧めします。 最終目標 ・Phaser3とTypescriptで RPG ゲームの基礎を作る。 ・Phaser3をTypescriptで使う方法を学ぶ ・Phaser3の使い方を学ぶ 今回の目標 ・開発環境を整える ・Phaser3の開発構成を知る ・スタート画面を作る ・マップ表示をさせる 開発前提 ・Nodejsの環境・知識がある ・ Javascript ・Typescriptがある程度かける ・当ページ紹介の環境を試す場合はgit・ github の知識がある 使用した主要Nodeモジュール ・typescript(Typescriptの コンパイル 用) ・phaser(フロントの Javascript 用ゲームライブラリ) ・live-server(ソースを監視してブラウザのページをリロード) ・ts-loader(webpackがTypescriptをバンドルする用)webpack(言わずと知れたモジュール依存をいい感じに解決しバンドルする) ・webpack- cli (webpackを コマンドライン で使用するのに必要) 注:各Nodeモジュールバージョンは後述 1. 最低限の開発環境の準備 今回最低限の環境を整えるために、『Typescript + Phaser3』の開発テンプレートを github リポジトリ で公開しました。 以下からZIPをダウンロードするか、 git clone コマンドで各自環境に展開してみてください。 ここから先は リポジトリ のプログラムを元に説明していきます。 github.com 展開するとファイル構造は以下のようになっているかと思われます。 注: 他にもファイルやフォルダがあるかと思われますが、表記されているのは今回使うものになっています。 - src/ (これから書くプログラムの保存領域)