近頃、IT界隈で「Slack」が大人気みたいですね。わたしもこの波に乗りたいなぁ〜なんて思っていたのですが、ぼっちだった…(T_T)

というわけで、ぼっちだけどSlackを使ってみるお話し。Slackには様々な便利なAPIが用意されており、それが人気の秘訣なんだとか。今回はAPIの1つ「Incoming WebHooks」を使って、Pythonから通知してみるというのをやってみようと思います。

ちょっと脱線しますが、IT速報はライブドアブログを用いています。ライブドアブログにはブログランキングが用意されており、この順位に一喜一憂しちゃう純情なわたし(照。しかし、毎日見に行くのは面倒です。

というわけで、これを通知で飛ばしてあげるようなプログラムを書いていきます。


まずはSlackのAPI「Incoming WebHooks」でWebhook URLを用意します。Slackの登録がまだな人は登録を先に。

Incoming WebHooks:https://slack.com/services/new/incoming-webhook

Post to Channelはお好きなものを。ただ「#general」を使うとチームに迷惑をかけちゃいそうですね。create a new channelから専用のものを用意しておくといいかも(※ちなみにこれはプログラム側でも指定可能です。ここで決めるのはデフォルト)。

また、NameやIconなんかもここで決めることができます。これらもポストする時に指定できますが、ここで決めてしまったほうがラクそうです。

14

さてさて、ここまででSlackを使う準備は終わり。必要なのは以下のような形式のWebhook URLだけです。

https://hooks.slack.com/services/**********

ここからはプログラムを書いていきます。今回はお勉強中のPython 3系で。まずは必要なライブラリを用意しましょう。requestsとbeautifulsoup4を使います。

$ pip install requests
$ pip install beautifulsoup4

ちょっと整理します。今回の目的は
1、ブログランキングから任意のブログの順位を取得
2、Slackに送信

です。

まずは順位の取得から書いていきましょう。パースする前にブログランキングのページをブラウザの開発者ツールでざっと眺めます。

45

ブログのURLで探せば必然と一意になりそうです。また、欲しい順位はdata-event-labelにありました。

<a href="http://blog.livedoor.jp/itsoku/" data-event-action="ブログランキングブログ" data-event-label="29位">IT速報</a>

これを元にスクレイピングします。簡単に書くとこんな感じ。パーサーは任意で。今回はhtml.parserを利用しています。

import requests
from bs4 import BeautifulSoup
#jsonは後から使います
import json

target_url = 'http://blog.livedoor.com/ranking/'
blog_url = 'http://blog.livedoor.jp/itsoku/'

req = requests.get(target_url).text
soup = BeautifulSoup(req, 'html.parser')
blog_ranking = soup.find('a', href=blog_url).get('data-event-label')
print(blog_ranking)

requestsで対象のurlからリクエストGETして、BeautifulSoupオブジェクトを生成。そこからfind関数でBogのurlを探しています。これを実行してみると…

38

「29位」!はい、ちゃんと順位を取り出すことができたみたいですね。さて、後はこれをSlackにPOSTしてあげれば完了です。これはJSONフォーマットでPOSTします。最も簡単な例は以下。

{
    "username": "ghost-bot",
    "icon_emoji": ":ghost:",
    "text": "BOO!"
}

このように任意の情報を記述してあげて、それをPOSTします。今回はusernameとtextだけを利用してみます。先程のコードに以下を追記

values = {
    "text": '今日の順位は' + blog_ranking + 'です',
    "username": "it"
}
print(json.dumps(values, ensure_ascii=False))

実行すると…

30

うん。綺麗なJSONができてるみたいです。あとはPOSTするだけ。POSTには最初に用意したWebhook URLが必要となります。今回の場合はslack_urlという変数を用意しました。

slack_url = 'https://hooks.slack.com/services/**********'
'''
コード割愛
'''
requests.post(slack_url, data=json.dumps(values))

実行するとちゃんとPOSTされて、Slackに投稿されたかと思います。

07

MacにもiPhoneの通知がきます。便利ですね☆彡(日付が変わって30位になっちゃってます)。

42

とっても悲しいけど、ランキング圏外の時のことも考慮して、、、

import requests
from bs4 import BeautifulSoup
import json

target_url = 'http://blog.livedoor.com/ranking/'
blog_url = 'http://blog.livedoor.jp/itsoku/'
slack_url = 'https://hooks.slack.com/services/**********'

def main():
    req = requests.get(target_url).text
    if blog_url in req:
        soup = BeautifulSoup(req, 'html.parser')
        blog_ranking = soup.find('a', href=blog_url).get('data-event-label')
        post(blog_ranking)
    else:
        post('ランク外')
 
def post(blog_ranking):
    values = {
        "text": '今日の順位は' + blog_ranking + 'です',
        "username": "it"
    }
    requests.post(slack_url, data=json.dumps(values))

if __name__ == "__main__":
    main()

はい完成です。cronなどスケジューリングしてあげれば、毎日通知が来てGood!これをちょっと変えると、ヨドバシやAmazonで完売商品(PSVRなど)が入荷したら通知したりとか、、、捗りそうです☆彡

以下を、参考にしました

Beautiful Soup Documentation
処理が終わったらSlackで通知してくれるようにShellとPythonでスクリプトを書く
Incoming Webhooks

おわり。

Bill Lubanovic
オライリージャパン
売り上げランキング: 494