LoginSignup
6
0

More than 3 years have passed since last update.

connpass API でIT勉強会の情報を手軽にランダム1件検索

Last updated at Posted at 2019-07-24

前書き

多種多様に開催されているIT勉強会。
自分は開催情報を知るきっかけの一つに「connpass」をよく利用しています。

connpass - エンジニアをつなぐIT勉強会支援プラットフォーム
https://connpass.com/

IT勉強会を「Python」で検索してみました。
結果、251件ヒット。かなりの数のIT勉強会が開催されていますね。
スクリーンショット 2019-07-24 19.42.22.png

都道府県で絞ればもう少し数も絞れるとはいえ、
開催数が多くて、選び出すところでひと苦労してしまう。。。

自分はまさにそんな感じの人です 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 イベントの必須入力項目は、
イベントの「タイトル」のみだからです。
スクリーンショット 2019-07-24 20.32.37.png

だから「タイトル」以外は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

そんなわけで、
みなさまご自身の強みにつながる「良い勉強会との出会い」に、
本投稿が少しでも役立てば幸いです!

6
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
0