LoginSignup
17
16

More than 5 years have passed since last update.

Twitterで遅延情報を取得してツイートする

Last updated at Posted at 2017-07-08

初投稿です。

pythonに出会って2ヶ月。出会うのが遅かったです。
そしてプログラミング初心者なので頭弱っ!なコードを書きます。お許し下さい。
各鉄道路線の遅延情報等公式の発表前に予測が欲しかったので作りました。
ただの自己満足!

環境はpython 2系を使用しています。

pythonからツイートできるようにする

まずpythonでツイートできるようにしなければ何も始まりません。
Twitter Applicationから設定してキーを取得してください。

# キーをセット
CONSUMER_KEY = "XXXXXXXXXXXXXXXXXXXXXXXXX"
CONSUMER_SECRET = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
ACCESS_TOKEN = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
ACCESS_TOKEN_SECRET = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"

auth = tweepy.OAuthHandler(CONSUMER_KEY, CONSUMER_SECRET)
auth.set_access_token(ACCESS_TOKEN, ACCESS_TOKEN_SECRET)

#APIインスタンスを作成
api = tweepy.API(auth)

これが準備となります。

ツイートからあてはまる単語を検索

まずツイートを取得しなければなりません。
他の投稿を参考にさせていただきました。

100件ツイートの取得

ツイートを取得してファイルへ出力する断片プログラムです。
ファイルへ出力する必要は全くありませんが、ただ単にファイル入出力をしてみたかったのでしました。
もし文字化けしたときにエラーがでないようにtry,exceptしてます。初心者感が出てますね。

for tweet in api.search(q=query, count=100):
        try:
            f.write(tweet.text.encode("utf-8"))
            f.write("\n")
        except:
            pass

ここで出力したものを入力させています。

#ファイルを文字化けしないようにcodecsオープン
f_in = codecs.open('XXXXXXX.txt','r','utf-8')

lines = f_in.readlines()

検索文字列

keywords =[u'遅延', u'遅れ']
query = ' OR '.join(keywords)

キーワードとして「遅延」「遅れ」のOR検索で引っかかったもののツイートを取得します。

できればこんなツイートが欲しいです。

は?また田都遅れてんだけどw遅れがデフォかよw

いい加減東横の遅れどうにかしろよまじで

素晴らしく無駄で良いツイートです。こんなツイートで遅れは解消されませんが、情報の取得に利用できます。

何路線を検索するか

私の場合東急が遅延で有名なのでそれを調べます。
また相互直通運転を行っている路線も含む辞書を路線ごとに作成しました。

train = {
        u"田都" : { "count" : 0 , "flag" : 0},
        u"東横" : { "count" : 0 , "flag" : 0},
        u"大井" : { "count" : 0 , "flag" : 0},
        u"目黒" : { "count" : 0 , "flag" : 0},
        u"半蔵門" : { "count" : 0 , "flag" : 0},
        u"東武スカイツリー" : { "count" : 0 , "flag" : 0},
        u"副都心" : { "count" : 0 , "flag" : 0},
        u"東上" : { "count" : 0 , "flag" : 0},
        u"西武池袋" : { "count" : 0 , "flag" : 0},
        u"三田" : { "count" : 0 , "flag" : 0}
        }

countは100件ツイートからの路線名ヒット数としています。
flagはツイートした場合1を入れます。(=連続ツイートを避けるため)

分かる人には分かると思いますが目黒線の直通先南北線そして埼玉高速鉄道は何らかの理由で消滅しました。省きました。そんなに遅れることはないだろうと思ったからです。

これらを検索し予測します。

関数

カウント、ツイートの関数を作成しました。

count

ツイートから路線ヒット数をカウントする関数です。

def count_tweet(lines, word):
    count = 0
    for line in lines:
        if line.find(word) > -1:
            count = count + 1
    return count

lines はファイル入力したものです。

train[u"田都"]["count"] = count_tweet(lines, u"田都")

こう使用します。

tweet

ツイートさせる関数です。

def tweet(count, word, flag):
    if count > 10 and flag == 0:
        api.update_status(status=str(now.hour)+u"時"+str(now.minute)+u"分情報取得 "+word+u"遅延の可能性")
        flag = 1
    else:
        flag = 0
    return flag

この関数では11カウント以上で遅延の可能性有りとして判断させています。

もしツイートすればflagを立て、次回この関数参照時に必ずelseに飛ぶようにしています。これにより連続のツイートはされません。本当はもっと違うやり方があると思いますが…

train[u"田都"]["flag"] = tweet(train[u"田都"]["count"],     u'田都', train[u"田都"]["flag"])

こう使用します。

実行結果

コンソールにも表示は一応させます。

(キャプチャ.PNG)

東武スカイツリーラインは長いので伊勢崎線にしときました。ツイートは東武スカイツリーラインでされます。

ツイート結果

こうなります。
キャプチャ2.PNG

詳細

whileループ内でsleepを使用し300秒(=5分)止めてから再度回してます。

ツイート内に時間を入れておくことで同じツイートしないよう対処をしています。

ここにコードを書いておきます。

# -*- coding:utf-8 -*-
#!/usr/bin/env python

import tweepy
import codecs
import datetime
from time import sleep

# 各種キーをセット
CONSUMER_KEY = "XXXXXXXXXXXXXXXXXXXXXXXXX"
CONSUMER_SECRET = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
ACCESS_TOKEN = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
ACCESS_TOKEN_SECRET = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
auth = tweepy.OAuthHandler(CONSUMER_KEY, CONSUMER_SECRET)
auth.set_access_token(ACCESS_TOKEN, ACCESS_TOKEN_SECRET)

#APIインスタンスを作成
api = tweepy.API(auth)
#検索内容
keywords =[u'遅延', u'遅れ']
query = ' OR '.join(keywords)

#検索内容のカウント
def count_tweet(lines, word):
    count = 0
    for line in lines:
        if line.find(word) > -1:
            count = count + 1
    return count

#ツイート判定
def tweet(count, word, flag):
    if count > 5 and flag == 0:
        api.update_status(status=str(now.hour)+u"時"+str(now.minute)+u"分情報取得 "+word+u"遅延の可能性")
        flag = 1
    else:   
        flag = 0
    return flag

train = {
        u"田都" : { "count" : 0 , "flag" : 0},
        u"東横" : { "count" : 0 , "flag" : 0},
        u"大井" : { "count" : 0 , "flag" : 0},
        u"目黒" : { "count" : 0 , "flag" : 0},
        u"半蔵門" : { "count" : 0 , "flag" : 0},
        u"東武スカイツリー" : { "count" : 0 , "flag" : 0},
        u"副都心" : { "count" : 0 , "flag" : 0},
        u"東上" : { "count" : 0 , "flag" : 0},
        u"西武池袋" : { "count" : 0 , "flag" : 0},
        u"三田" : { "count" : 0 , "flag" : 0}
        }

while 1:
    f = open('XXXXXX.txt','w')
    print "--------------------------------------------------------------------------------"
    #現在時刻の取得
    now = datetime.datetime.today()

    #現在時刻の表示
    print(str(now.hour)+u'時'+str(now.minute)+u'分'+str(now.second)+u'秒情報取得')

    #直近query検索についてのツイート100個をファイル入力
    for tweet in api.search(q=query, count=100):
        try:
            f.write(tweet.text.encode("utf-8"))
            f.write("\n")
        except:
            pass
    f.close()

    #ファイルを文字化けしないようにcodecsオープン
    f_in = codecs.open('XXXXXX.txt','r','utf-8')
    #行ごとに取得
    lines = f_in.readlines()

    train[u"田都"]["count"] = count_tweet(lines, u"田都")
    train[u"東横"]["count"] = count_tweet(lines, u"東横")
    train[u"大井"]["count"] = count_tweet(lines, u"大井")
    train[u"目黒"]["count"] = count_tweet(lines, u"目黒")
    train[u"半蔵門"]["count"] = count_tweet(lines, u"半蔵門")
    train[u"東武スカイツリー"]["count"] = count_tweet(lines, u"東武スカイツリー")
    train[u"副都心"]["count"] = count_tweet(lines, u"副都心")
    train[u"東上"]["count"] = count_tweet(lines, u"東上")
    train[u"西武池袋"]["count"] = count_tweet(lines, u"西武池袋")
    train[u"三田"]["count"] = count_tweet(lines, u"三田")


    print(u'田園都市線  :'+ str(train[u"田都"]["count"])    +' counts')
    print(u'東横線    :'+ str(train[u"東横"]["count"])    +' counts')
    print(u'大井町線   :'+ str(train[u"大井"]["count"])    +' counts')
    print(u'目黒線    :'+ str(train[u"目黒"]["count"])    +' counts')
    print(u'半蔵門線   :'+ str(train[u"半蔵門"]["count"])  +' counts')
    print(u'東武伊勢崎線 :'+ str(train[u"東武スカイツリー"]["count"])+' counts')
    print(u'副都心線   :'+ str(train[u"副都心"]["count"])  +' counts')
    print(u'東武東上線  :'+ str(train[u"東上"]["count"])    +' counts')
    print(u'西武池袋線  :'+ str(train[u"西武池袋"]["count"]) +' counts')
    print(u'都営三田線  :'+ str(train[u"三田"]["count"])    +' counts')


    train[u"田都"]["flag"] = tweet(train[u"田都"]["count"],     u'田都',  train[u"田都"]["flag"])
    train[u"田都"]["flag"] = tweet(train[u"東横"]["count"],     u'東横',  train[u"東横"]["flag"])
    train[u"田都"]["flag"] = tweet(train[u"大井"]["count"],     u'大井町',   train[u"大井"]["flag"])
    train[u"田都"]["flag"] = tweet(train[u"目黒"]["count"],     u'目黒線',   train[u"目黒"]["flag"])
    train[u"田都"]["flag"] = tweet(train[u"半蔵門"]["count"],  u'半蔵門',   train[u"半蔵門"]["flag"])
    train[u"田都"]["flag"] = tweet(train[u"東武スカイツリー"]["count"], u'東武スカイツリーライン', train[u"東武スカイツリー"]["flag"])
    train[u"田都"]["flag"] = tweet(train[u"副都心"]["count"],  u'副都',  train[u"副都心"]["flag"])
    train[u"田都"]["flag"] = tweet(train[u"東上"]["count"],     u'東上',  train[u"東上"]["flag"])
    train[u"田都"]["flag"] = tweet(train[u"西武池袋"]["count"], u'西武池袋', train[u"目黒"]["flag"])
    train[u"田都"]["flag"] = tweet(train[u"三田"]["count"],     u'三田',  train[u"目黒"]["flag"])


    print "--------------------------------------------------------------------------------"
    f_in.close()
    sleep(300)
print("finish.")

まとめ

鉄道遅延には様々な要因があります。
人身事故や信号トラブル、自然災害などによる運転見合わせはダイヤが乱れる時間が長くなってしまいます。この点に対しては何も考えていません。

朝ラッシュ時間帯に10分も遅れているというのは結構あるもので、それに気づくのが駅に着いてからじゃなく家で気づくと心の余裕がだいぶ違ってきます。我々は電車が遅れていることを通常ダイヤに戻すことはどうしても不可能です。出来ることは自分がどうするかですね。普遍の真理。

私は家にあるRaspberry Pi 2でこのプログラムを常に動かしています。

長々書きましたがこれで終わりです。
何か間違い、ご指摘があればコメントまでお願い致します。

17
16
2

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
17
16