Twitter APIを使った検索方法

Twitter分析をすることになったため、APIを使った検索について調査検証を行った。 結論から言うと、公式のAPIは、パラメーターが少なくロクな検索ができないのだが、 クエリにパラメーターを含めることで様々な検索が可能になることが分かった。 以下にその方法を示す。

1. APIとの接続

APIへ接続する前に、CONSUMER_KEY, CONSUMER_SECRET, ACCESS_TOKEN, ACCESS_TOKEN_SECRETを取得する。 Twitter REST APIの使い方とか読み進めていけばできると思う。 僕の場合は、昔に設定してたのが残っていたので、それを使用することにした。

取得できたら、設定ファイル(今回はconfig.py)を作成して、以下のように各コードを書き留めておく('xxx'の部分を変更)。 こうすることで、検索ファイルにべた書きするより多少リスクが軽減される。

CONSUMER_KEY        = 'xxx'
CONSUMER_SECRET     = 'xxx'
ACCESS_TOKEN        = 'xxx'
ACCESS_TOKEN_SECRET = 'xxx'

APIには、OAuthを簡単にしてくれるライブラリー requests_oauthlibOAuth1Sessionを使って接続する。 検索ファイル(今回はagent.py)を作成して、以下のように設定ファイル(config.py)から 各コードを取得し、OAuth1Sessionに渡すとAPIに接続できる。

from requests_oauthlib import OAuth1Session
import config

class Agent:

    ...

    def connect_api(self):
        api = OAuth1Session(config.CONSUMER_KEY,
                            config.CONSUMER_SECRET,
                            config.ACCESS_TOKEN,
                            config.ACCESS_TOKEN_SECRET)

        return api

2. 検索条件の設定

公式ドキュメント を見ると分かるが、ほとんど条件が指定できない。 しかし、queryに以下のように記述することで、様々な条件で検索することが可能になる。

    def make_params(self):
        query = '猫 filter:images min_replies:10 min_retweets:500 min_faves:500 exclude:retweets'
        params = {
            'q': query,
            'count': 20
        }

        return params

上記の条件は以下の通り。 他の条件については、Twitterの検索APIについて が詳しい。

key value exmaple discription
filter images 画像があるツイート
min_replies 10 リプライ数が指定値以上のツイート
min_retweets 500 リツイート数が指定値以上のツイート
min_faves 500 ライク数が指定値以上のツイート
exclude retweets リツイートでないツイート?

3. tweetの検索

上記で取得したapiparamsを引数とする検索用メソッドを以下のように作る。 ツイートはstatusesに入っているのでresultとして返す。

    def search_tweet(self, api, params):
        url = 'https://api.twitter.com/1.1/search/tweets.json'
        req = api.get(url, params=params)

        result = []
        if req.status_code == 200:
            tweets = json.loads(req.text)
            result = tweets['statuses']        
        else:
            print("ERROR!: %d" % req.status_code)
            result = None

        assert(len(result) > 0)

        return result

statusに入っているツイートは各々 Tweet data dictionariesTweet Data Dictionaryのkeyを持っている。 とりあえず簡単な分析に必要なkeyを標準出力させるメソッドは次の通り。

    def output_tweets(self, result):
        for r in result:
            for k,v in r.items():
                if k in ['text', 'retweet_count', 'favorite_count', 'id', 'created_at']:
                    print(k+':')
                    print(v)
                    print('    ')
            print('-----------------------------------------------------------------')

以下が出力結果。条件通りの検索結果が返ってきていることが分かる。

id:
925369434549624832

text:
我が家のネコさま。←むかし いま→ https://t.co/qg3TXEZpUv

favorite_count:
63259

created_at:
Tue Oct 31 14:30:40 +0000 2017

retweet_count:
30089

-----------------------------------------------------------------
id:
924974322115940357

text:
クロネコ https://t.co/JNZLtFHn2z

favorite_count:
19209

created_at:
Mon Oct 30 12:20:38 +0000 2017

retweet_count:
5106

-----------------------------------------------------------------
id:
924485965237731328

text:
【猫から学ぶ女子力】真枝アキ『彼氏のネコがかわいくない!』 https://t.co/y8lmBlbHkC #ツイ4 https://t.co/3J3AxKVnvV

favorite_count:
3255

created_at:
Sun Oct 29 04:00:04 +0000 2017

retweet_count:
847
-----------------------------------------------------------------

4. 文字化け対策

なおWindows環境だと、コマンドプロンプト上で、 上記のように日本語等を出力しようとすると、文字化けが起こる可能性が高い。 理由はPythonutf-8で扱っているのに、コマンドプロンプトはcp932を扱っているから。 もし文字化けが起こった場合は、以下を実行してみるとよい。

これでFuck コマンドプロンプトと思うことが、ちょっとだけ少なくなる。

参考文献