【Python】tweepyを用いてbot的な何かを作成した話
ハセ学を通したエイプリルフールネタを書こうかと思ってたんですが、いつのまにかエイプリルフールが終了してたので、趣味で書いたPythonのbot的なやつの話になります。"若干の"不適切な表現があるので閲覧には少しご注意を...
~~ことの発端~~
「Twitterで「致すか」ってツイートしてから「致した」ってツイートするまでめっちゃ早いやつおるな。」
↓
「せや!何秒かかってるのか自動で計測できるようにしたろ!」
てな感じでこういう頭悪い感じのbotを作成することに。
TwitterAPI(consumer_keyとか)に関してはこちらを
webnaut.jp
プログラムの基本的な部分はこちらを参考にさせていただきました。
net.univ-q.com
それでは早速プログラムの全文なんですが、プログラムが横に広いのに気を付けてください。(あとシングルクオテーションとダブルクオテーションがところどころごっちゃになってますが、気にしないでください。)
プログラムの解説は後ろに書いてあります。
# -*- coding:utf-8 -*- import tweepy import datetime consumer_key = "自分のconsumer_key" consumer_secret = "自分のconsumer_secret" access_key = "自分のaccess_key" access_secret = "自分のaccess_secret" CK=consumer_key CS=consumer_secret AT=access_key AS=access_secret itasiname="hoge" status1="hoge" d1=datetime.datetime.today() # Twitterオブジェクトの生成 auth = tweepy.OAuthHandler(CK, CS) auth.set_access_token(AT, AS) api = tweepy.API(auth) class Listener(tweepy.StreamListener): def on_status(self, status): status.created_at += datetime.timedelta(hours=9) # 致すか if u'致すか' in status.text: global d1 global status1 global itasiname itasiname=str(status.author.screen_name) d1 = datetime.datetime.today() micro1='%s' % d1.microsecond microsecond1 = micro1.rjust(6,'0') s1=u'%s時%s分%s秒%s\n' % (d1.hour, d1.minute, d1.second, microsecond1) itasuka=u"致しはじめ\n" status1=itasuka+s1 print status1 # 致した if (str(status.author.screen_name)==itasiname) and (u'致した' in status.text): tweetid=status.id d2 = datetime.datetime.today() micro2='%s' % d2.microsecond microsecond2 = micro2.rjust(6,'0') s2=u'%s時%s分%s秒%s\n' % (d2.hour, d2.minute, d2.second, microsecond2) itasita=u"致し終わり\n" status2=itasita+s2 print status2 itasi_microsecond=d2.microsecond-d1.microsecond itasi_second=d2.second-d1.second if itasi_microsecond<0: itasi_microsecond=itasi_microsecond+1000000 itasi_second=itasi_second-1 if itasi_second<0: itasi_second=itasi_second+60 if itasi_second==0: tweet=u'.@'+itasiname+u' の射精早すぎィ!!!!!自分、不正認定いいすか?'+ \ u'淫夢知ってそうだから淫夢のリストにぶち込んでやるぜー!'+ \ u'いきなりツイートしてすみません!許してください!なんでもしますから!'+ \ u'(なんでもするとは言ってない)' print u'早すぎィ!\n' else : itasi_microsecond_final = str(itasi_microsecond).rjust(6,'0') status3=u'致しスピード %s秒%s\n' % (itasi_second,itasi_microsecond_final) print status3 tweet=u'.@'+itasiname+u" の記録\n"+status1+status2+status3 api.update_status(status=tweet, in_reply_to_status_id=tweetid) itasiname="hoge" return True def on_error(self, status_code): print('Got an error with status code: ' + str(status_code)) return True def on_timeout(self): print('Timeout...') return True # Twitterオブジェクトの生成 auth = tweepy.OAuthHandler(CK, CS) auth.set_access_token(AT, AS) listener = Listener() stream = tweepy.Stream(auth, listener) stream.userstream()
自分で書き換えた部分は主に16~18行目と、28~71行目の処理なので、そちらについて解説をおこなっていきます。
まずは16~18行目について、次のようになっています。
16: itasiname="hoge" status1="hoge" d1=datetime.datetime.today()
簡単に言えば、プログラムのどこからでもアクセスできるグローバル変数のようなものを作っています。なぜグローバル変数を用いているのかは後述とします。
次に、28~40行目です。
28: # 致すか if u'致すか' in status.text: global d1 global status1 global itasiname itasiname=str(status.author.screen_name) d1 = datetime.datetime.today() micro1='%s' % d1.microsecond microsecond1 = micro1.rjust(6,'0') s1=u'%s時%s分%s秒%s\n' % (d1.hour, d1.minute, d1.second, microsecond1) itasuka=u"致しはじめ\n" status1=itasuka+s1 print status1
status.text(ツイートの本文)に"致すか"という文字列が含まれていればここの処理に入ります。
変数の前にglobalをつけることにより、d1などの変数がグローバル変数であることを示しています。これがないと、次の処理でこのツイートが行われた時刻などを得ることができません。(前述のグローバル変数が必要な理由となります。)
33行目では変数itasinameにstatus.author.screenname(ツイートした人のスクリーンネーム、@の後ろに続いてる文字列)を格納しています。後にこれを使うことにより、異なったアカウントの致し時間を計測してしまうことを防ぎます。
34行目ではツイートされた時刻をtoday関数を用いて取得しています。もちろん、時間の差をとるために使いますが、そのまま用いると、1秒004000と表示したいところを1秒4000と表示されてしまいます。なので、rjust関数を用いて0パディング(0埋め)を36行目でおこなっています。
あとは文字列の結合をおこなって、コマンドライン上に確認用に出力するだけです。
後半部分(41~71行目)の処理も似たようなものです。
41: # 致した if (str(status.author.screen_name)==itasiname) and (u'致した' in status.text): tweetid=status.id d2 = datetime.datetime.today() micro2='%s' % d2.microsecond microsecond2 = micro2.rjust(6,'0') s2=u'%s時%s分%s秒%s\n' % (d2.hour, d2.minute, d2.second, microsecond2) itasita=u"致し終わり\n" status2=itasita+s2 print status2 itasi_microsecond=d2.microsecond-d1.microsecond itasi_second=d2.second-d1.second if itasi_microsecond<0: itasi_microsecond=itasi_microsecond+1000000 itasi_second=itasi_second-1 if itasi_second<0: itasi_second=itasi_second+60 if itasi_second==0: tweet=u'.@'+itasiname+u' の射精早すぎィ!!!!!自分、不正認定いいすか?'+ \ u'淫夢知ってそうだから淫夢のリストにぶち込んでやるぜー!'+ \ u'いきなりツイートしてすみません!許してください!なんでもしますから!'+ \ u'(なんでもするとは言ってない)' print u'早すぎィ!\n' else : itasi_microsecond_final = str(itasi_microsecond).rjust(6,'0') status3=u'致しスピード %s秒%s\n' % (itasi_second,itasi_microsecond_final) print status3 tweet=u'.@'+itasiname+u" の記録\n"+status1+status2+status3 api.update_status(status=tweet, in_reply_to_status_id=tweetid) itasiname="hoge" return True
まずは42行目、先ほどと似ていますが少し条件が違います。"致した"の文字列が含まれてる、かつ、先ほどツイートしたアカウントと同じならこの処理に入ります。ここで変数itasinameを用いています。
43~50行目について、リプライ用にtweer.idをとっていますが、それ以外は先ほどの33~40行目の処理とほぼ同じです。
51~57行目では、"致すか"とツイートしてから"致した"とツイートするまでの時間の差分をとっています。繰り下がりに少し注意です。
58~63行目の処理は、複数クライアントや、プログラムなどを用いた不正の防止用の分岐となります。2つのツイートの時間差が1秒未満であればこの処理に入ります。処理とはいってもクソリプ送るだけですが。
そんで最後、64~71行目ですが、文章や計測結果をのせてツイートするだけです。
少し解説を挟むと、68行目までにツイートの本文を作成してます。69行目のstatusには作成した本文を突っ込み、in_reply_to_status_idという「どのツイートに対して返信するか」という変数には変数tweetid("致した"と書かれたツイートのid)を突っ込んでます。
70行目でitasiname="hoge"としたのは、「致すか」→「致した」→「致した」の順でツイートすると、始めの致すかから、最後の致したまでの差分をとってツイートしてしまうからです。
これで2つのツイートの時間差をとって、勝手にリプライしてくれるbotの完成となります。
お疲れさまでした。
最後に実行結果を次の図に示しておきます。
以下、Q&Aコーナー
Q,何の役に立つんですか
- 何の役にも立ちません。
Q,もっと詳しく説明して
- コメント等でどこの説明してほしいか言ってくだされば。
Q,変数の命名センスなさすぎ
- うっせぇ!!!!!!!!