趣味の電子工作などの記録。時にLinuxへ行ったり、ガジェットに浮気したりするので、なかなかまとまらない。
RSS icon
  • TwitterのストリーミングAPIを試してみた

    投稿日 2013年 9月 3日 1つのコメント

    Twitterからリアルタイムに情報を得るStreaming APIを試してみました。

    $ sudo easy_install pip
    $ sudo pip install tweepy --upgrade

    として、パッケージ管理ツール pip をインストールした後、tweepy をアップグレードしました。その後、キーワードを含む tweet を入手するスクリプトをいろんなところを参考にしながらなんとか作りました。

    #!/usr/bin/python
    # -*- coding: utf-8 -*-
    
    import sys
    import json
    import tweepy  
    import re
    
    # Account 
    consumer_key= '  '
    consumer_secret= ' '
    access_token= ' '
    access_token_secret= ' '
    
    class Listener(tweepy.streaming.StreamListener):
        def on_data(self, data):
            if data.startswith("{"):
                tweet = json.loads(data)
                if 'text' in tweet:
                    user = tweet['user']
                    text = re.sub(r'\n',r' ',tweet['text'].encode('utf-8')) # 改行コード除去
                    print tweet['id'],":",tweet['lang'],":",user['screen_name'].encode('utf-8'),":", \
                                  user['name'].encode('utf-8'),":", text
            return True
    
        def on_error(self, status):
            print status
    
    if __name__ == '__main__':
        l = Listener()
        auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
        auth.set_access_token(access_token, access_token_secret)
    
        stream = tweepy.Stream(auth, l)
    #    filterの宣言部分 @ /usr/local/lib/python2.7/dist-packages/tweepy/streaming.py
    #    def filter(self, follow=None, track=None, async=False, locations=None, 
    #        count = None, stall_warnings=False, languages=None):
    #    パラメータの使い方は https://dev.twitter.com/docs/streaming-apis/parameters
        stream.filter(languages=['ja'],track=['AKB', 'HKT', 'NMB'])

    15~27行目がデータ受信時の処理で、データを分析してユーザー名やscreeen_name、tweetの内容などを表示します。29行目からが認証で、34行目でstreaming apiを呼び出しています。
    39行目でフィルタの内容を設定していて、ここでは日本語のTweetで、「AKB,HKT,NMB」を含むものをキーワードとしています。キーワードは日本語のようなスペース区切りではない言語では正常に動作しないようです。

    同じ処理は、on_data ではなく、 on_statusを使うとJSONの解析もTweepy側でやってくれるようで、on_status版も上げておきます。

    #!/usr/bin/python
    # -*- coding: utf-8 -*-
    
    import sys
    import json
    import tweepy  
    import re
    
    # Account
    consumer_key= ' '
    consumer_secret= ' '
    access_token= ' '
    access_token_secret= ' '
    
    class Listener(tweepy.streaming.StreamListener):
        def on_status(self, status):
            print status.id,":", \
                   status.lang,":", \
                   status.user.screen_name.encode("utf-8"),":", \
                   status.user.name.encode("utf-8"),":", \
                   re.sub(r'\n',r' ',status.text.encode("utf-8"))
            return True
    
        def on_error(self, status):
            print status
    
    if __name__ == '__main__':
        l = Listener()
        auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
        auth.set_access_token(access_token, access_token_secret)
    
        stream = tweepy.Stream(auth, l)
    #    filterの宣言部分 @ /usr/local/lib/python2.7/dist-packages/tweepy/streaming.py
    #    def filter(self, follow=None, track=None, async=False, locations=None, 
    #        count = None, stall_warnings=False, languages=None):
    #    パラメータの使い方は https://dev.twitter.com/docs/streaming-apis/parameters
        stream.filter(languages=['ja'],track=['AKB', 'HKT', 'NMB'])

    取得できるデータは、あるtweetを参考に分析してみたところ、

    {u'contributors': None,
     u'truncated': False,
     u'text': u'\u301017\u6642....00#NMB #HKT48\u3000#HKT',
     u'in_reply_to_status_id': None,
     u'id': 3744....11520,
     u'favorite_count': 0,
     u'source': u'<a href="http://twittbot.net/" rel="nofollow">twittbot.net</a>',
     u'retweeted': False,
     u'coordinates': None,
     u'entities': {u'symbols': [],
                   u'user_mentions': [],
                   u'hashtags': [{u'indices': [68, 74], u'text': u'AKB48'},
                                 {u'indices': [75, 79], u'text': u'AKB'},
                                 {u'indices': [80, 86], u'text': u'SKE48'},
                                 {u'indices': [87, 91], u'text': u'SKE'},
                                 {u'indices': [92, 98], u'text': u'NMB48'},
                                 {u'indices': [99, 103], u'text': u'NMB'},
                                 {u'indices': [104, 110], u'text': u'HKT48'},
                                 {u'indices': [111, 115], u'text': u'HKT'}],
                   u'urls': [{u'url': u'http://t.co/f4....w6kL', u'indices': [8, 30], u'expanded_url': u'http://com.nicovideo.jp/community/co....411', u'display_url': u'com.nicovideo.jp/community/co....\u2026'}]},
     u'in_reply_to_screen_name': None,
     u'id_str': u'3744....1520',
     u'retweet_count': 0,
     u'in_reply_to_user_id': None,
     u'favorited': False,
     u'user': {u'follow_request_sent': None,
               u'profile_use_background_image': True,
               u'default_profile_image': True,
               u'id': 63.....87,
               u'verified': False,
               u'profile_image_url_https': u'https://.......png',
               u'profile_sidebar_fill_color': u'DDEEF6',
               u'profile_text_color': u'333333',
               u'followers_count': 1,
               u'profile_sidebar_border_color': u'C0DEED',
               u'id_str': u'63.....87',
               u'profile_background_color': u'C0DEED',
               u'listed_count': 0,
               u'profile_background_image_url_https': u'https://......png',
               u'utc_offset': 32400,
               u'statuses_count': 25632,
               u'description': None,
               u'friends_count': 1,
               u'location': u'',
               u'profile_link_color': u'0084B4',
               u'profile_image_url': u'http://......png',
               u'following': None,
               u'geo_enabled': False,
               u'profile_background_image_url': u'http://......png',
               u'name': u'\u308a\u3063..........\uff09',
               u'lang': u'ja',
               u'profile_background_tile': False,
               u'favourites_count': 0,
               u'screen_name': u'KK....ty',
               u'notifications': None,
               u'url': None,
               u'created_at': u'Sun Jul 15 18:..:.. +0000 2012',
               u'contributors_enabled': False,
               u'time_zone': u'Osaka',
               u'protected': False,
               u'default_profile': True,
               u'is_translator': False},
     u'geo': None,
     u'in_reply_to_user_id_str': None,
     u'possibly_sensitive': False,
     u'lang': u'ja',
     u'created_at': u'Mon Sep 02 08:..:.. +0000 2013',
     u'filter_level': u'medium',
     u'in_reply_to_status_id_str': None,
     u'place': None}

    というような感じで、ユーザー名などは入れ子になったデータ構造になっていますので、on_data版ではソースの20行目のように一旦’user’データを取り出しています。

     


    コメントをどうぞ(日本語のみ/Only in Japanese)

    日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)