Twitter API を使う
Pythonによるデータ分析入門を読んでいたらTwitter APIを使ってデータを集める方法が書いてあったけれど、出版当時とはAPIの仕様が変わっていてサンプルコードが動かなかったのでメモ。
参考サイト
Twitterアプリケーションの作成(Consumer key、Consumer secret、Access token、Access token secretの確認方法)
Python で Twitter API にアクセス - Qiita
Python で Twitter からの情報収集 (Twitter API 編) - Qiita
すごく面倒くさいけどOAuth認証のキーを手に入れて、requests_oauthlib というライブラリを使えば良いらしい。
ソースコード
from pandas import DataFrame import pandas as pd from requests_oauthlib import OAuth1Session import json consumer_key = 'XXXXXXXXXXXXXXXXXXXXXX' consumer_secret = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' access_token = 'XXXXXXXXX-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' access_token_secret = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' twitter = OAuth1Session(consumer_key, consumer_secret, access_token, access_token_secret) url = 'https://api.twitter.com/1.1/statuses/home_timeline.json' # url = 'https://api.twitter.com/1.1/search/tweets.json?q=検索ワード' params = {'count': 20, 'include_rts': False} # 取得するツイート数(10~200),リツイートの有無 resp = twitter.get(url, params=params) data = json.loads(resp.text) tweet_fields = ['created_at', 'text', 'id'] tweets = DataFrame(data, columns=tweet_fields) # tweets = DataFrame(data['statuses'], columns=tweet_fields) user_fields = ['name', 'screen_name'] tweets[user_fields] = DataFrame([d['user'] for d in data], columns=user_fields) # tweets[user_fields] = DataFrame([d['user'] for d in data['statuses']], columns=user_fields)
data(検索ならdata['statuses'])は取得したツイートからなるリストで、各ツイート要素は下記のように大きな辞書になっているので、データフレームにするときは使いたいフィールドを列に指定する。userは辞書の入れ子になってるので別のデータフレームを作ったあとにtweetsに結合した。
In [51]: data[1] Out[51]: {'place': None, 'in_reply_to_status_id': None, 'favorited': False, 'truncated': False, 'id_str': '571327535436292096', 'lang': 'en', 'contributors': None, 'source': '<a href="http://twipple.jp/" rel="nofollow">ついっぷる\u3000</a>', 'in_reply_to_user_id_str': None, 'retweeted': False, 'text': 'hoge', 'in_reply_to_user_id': None, 'in_reply_to_screen_name': None, 'created_at': 'Fri Feb 27 15:14:33 +0000 2015', 'user': {'profile_background_image_url_https': 'https://abs.twimg.com/images/themes/theme1/bg.png', 'description': '死にかけ院生。好きな言語:Python', 'profile_text_color': '333333', 'protected': False, 'friends_count': 103, 'default_profile_image': False, 'is_translation_enabled': False, 'id_str': '636457417', 'lang': 'ja', 'notifications': False, 'profile_background_color': 'C0DEED', 'following': False, 'profile_background_tile': False, 'url': 'http://t.co/0IdlKznLSe', 'profile_background_image_url': 'http://abs.twimg.com/images/themes/theme1/bg.png', 'screen_name': 'matsulib', 'profile_banner_url': 'https://pbs.twimg.com/profile_banners/636457417/1420178021', 'location': '京都', 'profile_sidebar_fill_color': 'DDEEF6', 'profile_sidebar_border_color': 'C0DEED', 'profile_image_url_https': 'https://pbs.twimg.com/profile_images/444071974105382912/04h61MUk_normal.png', 'default_profile': True, 'created_at': 'Sun Jul 15 20:56:47 +0000 2012', 'profile_image_url': 'http://pbs.twimg.com/profile_images/444071974105382912/04h61MUk_normal.png', 'name': 'まつ', 'profile_location': None, 'profile_use_background_image': True, 'time_zone': 'Irkutsk', 'listed_count': 2, 'utc_offset': 32400, 'contributors_enabled': False, 'entities': {'description': {'urls': []}, 'url': {'urls': [{'display_url': 'matsulib.hatenablog.jp', 'expanded_url': 'http://matsulib.hatenablog.jp/', 'indices': [0, 22], 'url': 'http://t.co/0IdlKznLSe'}]}}, 'profile_link_color': '0084B4', 'favourites_count': 654, 'is_translator': False, 'follow_request_sent': False, 'geo_enabled': False, 'statuses_count': 1956, 'followers_count': 101, 'id': 636457417, 'verified': False}, 'in_reply_to_status_id_str': None, 'favorite_count': 0, 'geo': None, 'retweet_count': 0, 'coordinates': None, 'entities': {'symbols': [], 'user_mentions': [], 'hashtags': [], 'urls': []}, 'id': 571327535436292096}
該当するデータフレームの行は次のようになる。これを使ったデータ分析のアイデアはない。
In [52]: tweets.ix[1] Out[52]: created_at Fri Feb 27 15:14:33 +0000 2015 text hoge id 571327535436292096 name まつ screen_name matsulib Name: 1, dtype: object
— まつ (@matsulib) 2015, 2月 27
タイムゾーンのアレで時間がズレてる。本では最後のほうで解説されるらしいから放置(´・ω・`)
以下、追記
データベース
いろいろなデータベース(ここではMongoDB)に書き出したり、逆にデータベースからデータフレームに抜き出すこともできる。さっき作ったデータフレームtweetsを保存して読み出してみる。
import pymongo con = pymongo.Connection() twidb = con.db.twidb for tweet in tweets.T.to_dict().values(): twidb.save(tweet) # 自分のツイートを検索 cursor = twidb.find({'screen_name': 'matsulib'}) simple_fields = ['name', 'text', 'created_at'] result = DataFrame(list(cursor), columns=simple_fields) print(result)
name text created_at 0 まつ MongoDBやってる。。。 Fri Feb 27 18:58:32 +0000 2015 1 まつ twitter API と Fri Feb 27 18:58:15 +0000 2015