前書き
多種多様に開催されているIT勉強会。
自分は開催情報を知るきっかけの一つに「connpass」をよく利用しています。
connpass - エンジニアをつなぐIT勉強会支援プラットフォーム
https://connpass.com/
IT勉強会を「Python」で検索してみました。
結果、251件ヒット。かなりの数のIT勉強会が開催されていますね。
都道府県で絞ればもう少し数も絞れるとはいえ、
開催数が多くて、選び出すところでひと苦労してしまう。。。
自分はまさにそんな感じの人です orz
何がしたいのか
もっと積極的にIT勉強会へ参加する。
そのきっかけに「手軽なIT勉強会の検索処理」を作りたい!
やったこと
connpass API からIT勉強会の情報を、
お手軽にランダム1件検索する処理を書いてみました。
なぜランダム1件検索?
何が検索されるか分からないガチャ的なwワクワク感と、
検索を敢えて1件に絞って情報量を減らすことで、
検索結果をしっかり読むきっかけにできないかと考えました。
connpass API
connpassはイベントサーチ用APIを提供しており、
誰でも利用することができるようになっています。
こちらを利用させていただきました。
connpass API
https://connpass.com/about/api/
実行結果
先に処理の実行結果から。
pythonコマンドで該当処理を「検索キーワード」をつけて実行します。
検索キーワードを「Python」にしてみます。
python connpass_search.py python
実行結果はこんな感じになりました。
(一応伏せ字にしましたが、実際の実行結果は全ての情報が閲覧可能です。)
---------------------------------------------
# (・∀・) connpassイベント 何がでるかな?
# 機能:ランダムで1件 イベントを検索します
---------------------------------------------
検索中・・・
■ 検索結果
イベント名:Fintech,Pyt…気。。。略
開 催 日:2019-07-24T19:3。。。略
場 所:東京都港区。。。略
会 場:Cre。。。略
詳細ページ:https://cuc。。。略
参加者定員:17
参 加 者:7
補 欠 者:0
主催グループ名 :Cuc。。。略
主催グループURL:https://cuc。。。略
↑ピン!ときたら、ぜひ参加してみよう!
---------------------------------------------
また「検索キーワード」は「複数指定(AND検索)」もできます。
検索キーワードを「Python」「大阪」にしてみます。
python connpass_search.py python,大阪
実行結果はこんな感じになりました。
(一応伏せ字にしましたが、実際の実行結果は全ての情報が閲覧可能です。)
---------------------------------------------
# (・∀・) connpassイベント 何がでるかな?
# 機能:ランダムで1件 イベントを検索します
---------------------------------------------
検索中・・・
■ 検索結果
イベント名:阪医pyth。。。略
開 催 日:2019-07-26T1:。。。略
場 所:大阪府大阪市。。。略
会 場:PLU。。。略
詳細ページ:https://ou。。。略
参加者定員:30
参 加 者:17
補 欠 者:0
主催グループ名 :阪医pyth。。。略
主催グループURL:https://ou。。。略
↑ピン!ときたら、ぜひ参加してみよう!
---------------------------------------------
検索結果は原則、ランダムになります。
コマンドを叩くたびに違う勉強会の情報を読めるのは、ちょっと楽しい!
実装
実装はこちらになります。
Python 3 で書いています。
import sys
import random
import requests
import time
from datetime import datetime
def main():
args = sys.argv
keywords = []
ym = ""
print('---------------------------------------------')
print('# (・∀・) connpassイベント 何がでるかな?')
print('# 機能:ランダムで1件 イベントを検索します')
print('---------------------------------------------')
keywords, ym = _check(args)
print('')
print('検索中・・・')
print('')
event_data = _req(keywords, ym, 10)
if len(event_data['events']) == 1:
print('■ 検索結果')
else:
time.sleep(1)
event_data = _req(keywords, ym, 1)
if len(event_data['events']) == 1:
print('■ 検索結果')
else:
print('(*_*;) 検索失敗 該当するイベントが見つかりませんでした')
exit()
for event in event_data['events']:
if event['catch'] is not None:
print('イベント名:' + event['title'] + ' ' + event['catch'])
else:
print('イベント名:' + event['title'])
if event['started_at'] is not None:
print('開 催 日:' + event['started_at'])
if event['address'] is not None:
print('場 所:' + event['address'])
if event['place'] is not None:
print('会 場:' + event['place'])
if event['event_url'] is not None:
print('詳細ページ:' + event['event_url'])
if event['limit'] is not None:
print('参加者定員:' + str(event['limit']))
if event['accepted'] is not None:
print('参 加 者:' + str(event['accepted']))
if event['waiting'] is not None:
print('補 欠 者:' + str(event['waiting']))
# if event['description'] is not None:
# print('概 要:' + event['description'])
if event['series'] is not None:
if event['series']['title'] is not None:
print('主催グループ名 :' + event['series']['title'])
if event['series']['url'] is not None:
print('主催グループURL:' + event['series']['url'])
print('')
print('↑ピン!ときたら、ぜひ参加してみよう!')
print('---------------------------------------------')
def _check(args):
if len(args) == 1:
print('(*_*;) INPUT ERROR:第1引数(検索キーワード)は必須です')
exit()
keywords = args[1]
ym = datetime.now().strftime("%Y%m")
if len(args) == 3:
if (len(args[2]) == 6 or len(args[2]) == 8) and args[2].isdigit():
ym = args[2]
else:
print('(*_*;) INPUT ERROR:第2引数(開催年月)の入力時は「yyyymm」または「yyyymmdd」の形式で入力してください')
exit()
return keywords, ym
def _req(keywords, ym, rand):
params = {
'keyword': keywords,
'order': random.randint(1, 3),
'start': random.randint(1, rand),
'count': 1
}
if len(ym) == 6:
params['ym'] = ym
else:
params['ymd'] = ym
url = 'https://connpass.com/api/v1/event/'
r = requests.get(url, params=params)
return r.json()
if __name__ == '__main__':
main()
実装詳細
まずはコマンドライン引数の仕様について。
上記例では「検索キーワード」だけを指定しましたが、
実際にはもう1つ「開催年月日」を指定できるようにしています。
「開催年月日」は毎回打つのが手間ですので、
省略時は「システム年月」を自動で設定するようにしました。
「開催年月日」を指定する時は「yyyymm」か「yyyymmdd」を入力します。
コマンドライン引数関連の処理
def _check(args):
if len(args) == 1:
print('(*_*;) INPUT ERROR:第1引数(検索キーワード)は必須です')
exit()
keywords = args[1]
ym = datetime.now().strftime("%Y%m")
if len(args) == 3:
if (len(args[2]) == 6 or len(args[2]) == 8) and args[2].isdigit():
ym = args[2]
else:
print('(*_*;) INPUT ERROR:第2引数(開催年月)の入力時は「yyyymm」または「yyyymmdd」の形式で入力してください')
exit()
return keywords, ym
続いて connpass API へのリクエストについて。
ランダム1件検索と謳っておりますが、正しくは以下の仕様としています。
1. 「更新日時順」「開催日時順」「新着順」のいずれかランダムの検索で
「検索上位10件から1件」をランダム出力する
2. 上記1で該当がない(検索結果が10件以下の場合にランダム指定した数が検索数以上だった時)は
1秒待ってから「更新日時順」「開催日時順」「新着順」のいずれかランダムの検索で
「検索上位1件」に絞って出力する
3. 上記2で該当がない場合は「検索失敗」とする
ですので、ピンポイントな「検索キーワード」を指定した場合は、
connpass API へ2回リクエストを飛ばすこともある。という仕様になっています。
connpassAPI へのリクエストパラメータは params で定義しました。
概要はリファレンスを見ていただければ幸いです。
https://connpass.com/about/api/
(ちなみにリファレンスを見るとわかるのですが、
先述の例で「Python」「大阪」で「大阪の勉強会」が検索できたケース。
実際には「検索キーワード」は「イベント概要内の文字列」までを見にいきますので、
「大阪」と入れたのに「東京の勉強会」がヒットした、といったケースもあり。
(例:「東京の勉強会」だけど講師の方のプロフィールに「大阪出身」と書いていた…etc)
何か良い解決方法はないものか・・・。)
connpassAPI へのリクエスト関連処理
print('')
print('検索中・・・')
print('')
event_data = _req(keywords, ym, 10)
if len(event_data['events']) == 1:
print('■ 検索結果')
else:
time.sleep(1)
event_data = _req(keywords, ym, 1)
if len(event_data['events']) == 1:
print('■ 検索結果')
else:
print('(*_*;) 検索失敗 該当するイベントが見つかりませんでした')
exit()
:
中略
:
def _req(keywords, ym, rand):
params = {
'keyword': keywords,
'order': random.randint(1, 3),
'start': random.randint(1, rand),
'count': 1
}
if len(ym) == 6:
params['ym'] = ym
else:
params['ymd'] = ym
url = 'https://connpass.com/api/v1/event/'
r = requests.get(url, params=params)
return r.json()
そして最後に、検索結果の表示。
ここでは、やたら if で要素の存在確認を行っています。
その理由は、connpass イベントの必須入力項目は、
イベントの「タイトル」のみだからです。
だから「タイトル」以外はNULLがあり得る。チェックが必要と考えました。
それにしても、イベント名だけでイベント登録が完了する潔さ。
思わず自分もIT勉強会を企画してみようかと思ってしまう!
(って、そんな立派なネタないでしょorz)
検索結果の表示関連処理
for event in event_data['events']:
if event['catch'] is not None:
print('イベント名:' + event['title'] + ' ' + event['catch'])
else:
print('イベント名:' + event['title'])
if event['started_at'] is not None:
print('開 催 日:' + event['started_at'])
if event['address'] is not None:
print('場 所:' + event['address'])
if event['place'] is not None:
print('会 場:' + event['place'])
if event['event_url'] is not None:
print('詳細ページ:' + event['event_url'])
if event['limit'] is not None:
print('参加者定員:' + str(event['limit']))
if event['accepted'] is not None:
print('参 加 者:' + str(event['accepted']))
if event['waiting'] is not None:
print('補 欠 者:' + str(event['waiting']))
# if event['description'] is not None:
# print('概 要:' + event['description'])
if event['series'] is not None:
if event['series']['title'] is not None:
print('主催グループ名 :' + event['series']['title'])
if event['series']['url'] is not None:
print('主催グループURL:' + event['series']['url'])
print('')
print('↑ピン!ときたら、ぜひ参加してみよう!')
print('---------------------------------------------')
まとめ
connpassAPIを使って勉強会情報を検索するようにしてみました。
情報量を敢えて減らすことで、公式サイトでの検索とは違った楽しさを味わえればと感じた次第。
何より黒画面だから仕事中にこっそり検索できるwww
こちらの実装は、git hub でも公開中です。
git hub には本件を対話型のインプットで組んだ処理もあげております。
荒削りにも程がありますけど、ご興味ある方はぜひどうそ。
https://github.com/masashi-sawai/python-learning/tree/master/tools/conpass_search
そんなわけで、
みなさまご自身の強みにつながる「良い勉強会との出会い」に、
本投稿が少しでも役立てば幸いです!