pythonでtwitterのStreaming APIを使ってみた

twitterのように更新頻度が高いサービスのAPIはポーリングとあまり相性がよくありません。どうせtwitter API使うプログラム書くなら、リアルタイムなイベントベースっぽいAPIの方が色々と都合が良いので調べてみました。なんとなくXMPPに対応してる気がしてたんですが、実際はStreaming APIという独自のインターフェースが用意されていました。

Streaming API自体はただのHTTPリクエストで、リクエストのコネクションを張りっぱなしにして、都度データが流れてくる様な形になります。見るからに相性が良さそうなのでgeneratorで書いてみました。この例では幾つか種類があるStreaming APIの中からfilterを使っています。

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

import sys
import base64
import urllib
import urllib2
from pit import Pit

# tweetが流れる度にそのデータを返却するgenerator
def read_stream_api(user, passwd, trackword):
  request = urllib2.Request('http://stream.twitter.com/1/statuses/filter.json')
  basic = base64.encodestring('%s:%s' % (user, passwd))[:-1]
  request.add_header('Authorization', 'Basic %s' % basic)
  postdata = urllib.urlencode({'track':trackword})
  res = urllib2.urlopen(request, postdata)
  for line in res:
    if line.strip() is not "":
      yield line

# Usage: 
#     python streaming_test.py (filterするキーワード)
#     
if __name__ == '__main__':
  trackword = sys.argv[1]
  
  config = Pit.get('twitter.com')
  user   = config['username']
  passwd = config['password']

  stream = read_stream_api(user, passwd, trackword)
  while True:
    print stream.next()

実際に動かしてから解ったのですが、streaming apiは全てのtweetを取得できる訳ではなく、一定のアルゴリズムでサンプリングを行った結果を返却します。filterもサンプリングされたデータを更にフィルタリングするので、例えばfilterを利用して特定のキーワードを含むtweetを全て取得するというような用途には使えません。(実際は申請して認められれば使えるようですが。)思っていた挙動とは違いましたが、割と面白いインターフェースなので、活用方法を探したいですね。

また先日も使ったtweepyを使うともっとエレガントにStreaming APIを使えます。上記と同じ挙動をするサンプルが以下になります。短くていい感じですね。

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

import sys
import tweepy
from pit import Pit

class StreamListener(tweepy.StreamListener):
  def on_data(self, data):
    print data

def main():
  conf   = Pit.get('twitter.com')
  user   = conf['username']
  passwd = conf['password']
  stream = tweepy.Stream(user, passwd, StreamListener())
  stream.filter(track=[sys.argv[1]])

if __name__ == "__main__":
  main()

今のところtweepyがpython用のtwitterラッパーとしては最強なんじゃないかと思うんで、twython使ってる人は乗り換えたら良いと思いますYO!

Leave a Reply

Your email address will not be published. Required fields are marked *