tweepyでStreaming API
id:nekomusha6:20110121:1295606221 でライブラリがtweepyに決まったので、次はアプリケーションの作成になります。
お題
tweepyを使ってフォローしている人のつぶやきをStreaming APIを使って拾う
はじめに
twitterのAPIには、公式*1 *2によると現在以下の3種類、分け方によっては5種類があります。
(これらのWeb ServiceのPythonラッパーである)tweepyで対応しているのは、(1)〜(3-1)までですが、今回使用するのは(1)と(3-1)だけです。
それでは検討
Streaming APIのサンプルを見ると、どうやらユーザー名とパスワードが分かれば(Basic認証で)なんかできそうな気がします。で、やってみると...
動きますが、filterのユーザー指定(folow)ができません。いや正確には例えば私のユーザーを指定するのだったら@の後ろに書くnekomushaでいいのかと思っていたのですが、ユーザーID(230193917)が必要でした。それでは
- どうすればユーザー名からユーザーIDを得られるのか?
- それにどうすればフォローしている人の一覧を得られるのか?
しかし(3-1)Streaming APIにはどちらの機能も用意されていません。これらは(1)REST APIの1つである以下のAPIでまとめて用意されています。
"GET friends/ids"
http://dev.twitter.com/doc/get/friends/ids
これはREST APIかつ認証不要なAPIなので、例えばブラウザから
http://api.twitter.com/1/friends/ids.json?screen_name=nekomusha
とするだけで私のフォローしている人のID一覧がJSON形式で取れてしまいます。
もちろんtweepyにもこのAPIを使う関数が用意されています。
API.friends_ids(id/screen_name/user_id[, cursor])(http://joshthecoder.github.com/tweepy/docs/api.html#API.friends_ids)
これだけ情報が揃えば十分作れそうです。
実装
ほぼサンプルのままですが...
#!/usr/bin/env python from textwrap import TextWrapper import tweepy username = "ユーザー名" password = "パスワード" class StreamWatcherListener(tweepy.StreamListener): status_wrapper = TextWrapper(width=60, initial_indent=' ', subsequent_indent=' ') def on_status(self, status): try: print self.status_wrapper.fill(status.text) print '\n %s %s via %s\n' % (status.author.screen_name, status.created_at, status.source) except: # Catch any unicode errors while printing to console # and just ignore them to avoid breaking application. pass def on_error(self, status_code): print 'An error has occured! Status code = %s' % status_code return True # keep stream alive def on_timeout(self): print 'Snoozing Zzzzzz' follow_list = tweepy.api.friends_ids(screen_name=username) if len(follow_list) > 5000: print "too many firends." else: stream = tweepy.Stream(username, password, StreamWatcherListener(200), timeout=None) stream.filter(follow_list)
なお、フォローしている人が5000人を超えたらエラーにしているのは、
"Streaming API: Methods"
http://dev.twitter.com/pages/streaming_api_methods#statuses-filter
により、デフォルトだとその辺が上限だからです。これ以上増やしたい場合は、User Streamの出番なのでしょう。試していたらfollowしたりされたりなどのイベントまで拾ってくれるようです(いい忘れましたがStreaming APIにするだけでもいっぺんに拾える情報が増えます)。
おまけ
今回は認証方法はBasic認証になっていますが、HTTPなのでパスワードが平文で送られることになります。パスワードは昨今いろいろなところで同じのが使われていたりしがちなので、(OAuthに比べて)漏れたときのダメージが格段に大きく、あまりよくありません。せっかくStreaming APIに対応しても、OAuthでほぼ同じことができるREST APIの方が安全で良いという結論になってしまいます(実はStreaming APIはBasic認証/OAuth両対応してます。tweepyがBasic認証しか対応してないだけです)。そこで、まずは暗号化通信できないか調べてみました。結果...
暗号化通信はできませんでした。twitterはSSL(HTTPS)に対応していますが、tweepyのStreaming APIではできないからです。しかしtweepyを1行いじればHTTPSで通信できるようになります(HTTPでは通信できなくなりますが)。
/usr/share/pyshared/tweepy/streaming.py: 196
conn = httplib.HTTPConnection(self.host)
これを
/usr/share/pyshared/tweepy/streaming.py: 196
conn = httplib.HTTPSConnection(self.host)
こうするだけ!