【Python】TwitterAPIでフォロワーのツイートを抽出する方法

PythonでTwitterのAPIを使ってタイムラインを取得し、そこからフォロワーのツイートのみを表示したい。
Twitterをやっていると、リツィートやいいねなど、フォロワー以外のツイートも数多く流れてきますが、そういうものを排除してフォロワーのツイートのみを抽出したい時ってありますよね。(僕だけ?)

このとき必要になるのが、タイムラインに載っているツイートの主がフォロワーなのかそうでないのかを判定することです。
そこで、今回はタイムラインの情報からフォロワーのユーザーIDのみを抽出する方法をご紹介します。

フォロワーのツイートのみを抽出する方法は?

結論から言うと、ツイートの主がフォロワーであるかどうかを確かめることです。
これには、friendships/lookupのエンドポイントを利用します。
Twitterの公式リファレンスページはこちら

このエンドポイントに「ユーザーID」もしくは「スクリーンネーム」のどちらかを投げるとデータが返ってきます。
そして、このデータの中にある[‘connections’]に’followed_by’があるユーザーがフォロワーになります。

タイムラインからフォロワーのツイートのみを抽出する手順を具体的に示すと3つの工程になります。

  1. タイムラインなどでツイートの一覧を取得する
  2. ツイート一覧からユーザーIDを抽出して配列に格納する
  3. 返ってきたデータからフォロワーIDのみを抽出する
  4. 抽出したフォロワーのIDとツイートしているユーザーのIDを比較して判定する

それでは、これを順番にやっていきましょう!

1,タイムラインを取得する

タイムラインを取得する方法は以前の記事にも書いたので、こちらを参考にしてください。
この記事では、以前の記事で作った”connect_api.py”というプログラムを使ってタイムラインを取得します。

Twitterは公式でAPIを公開しているため、これを利用してさまざまなアプリケーションを作ることができる。 たとえば、フォローし...

”connect_api.py”を使って、まずはタイムラインを取得します。

C:\>python
Python 3.6.0 (v3.6.0:41df79263a11, Dec 23 2016, 07:18:10) [MSC v.1900 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import connect_api
>>> C = connect_api.Read_api()
>>> result = C.get_timeline()

2,ユーザーIDを抽出して配列に格納する

タイムラインから取得した情報は、リスト型になっています。
変数’result’の[2]にアクセスすると、タイムラインから取得した情報が格納されています。

これを繰り返し処理にかけてユーザーIDのみを抜き出します。
空のリスト”user_list”を作成し、ここにユーザーIDを追加していきます。
繰り返し処理の中には”if not in”を使って、IDの重複も防ぎます。

user_list = []

for tweet in result[2]:
    user_id = tweet['user']['id']
    if user_id not in user_list:
         user_list.append(user_id)

これでタイムラインからユーザーのIDのみを抽出できました。
一応、”user_list”の中身を見てみましょう。

>>> print(user_list)
[932696622923857920, 897472524627222530, 2543661997, 2984303878, 964045059116056576, 11328252, 112724844, 954941467050442752, 1295339360, 93508448, 709319781027942400, 711381326671130626, 2812894670, 4103429806, 788912549680914432, 985339908146393088, 146595646, 296150557, 1399480400, 912506447665045505, 39031080, 4851591537, 217647664, 806426183843749888, 758545192592941056, 264151277, 100115294, 22075119, 951778899276410880, 7622742, 988494933446217728, 887965821967912961, 2598958794, 2957320841, 1136574486, 792556623948500994, 894560540852224001, 470939195, 99808390, 2491452625, 290540648, 730755035504611328, 978629778784665601, 108664634, 838284677530054657, 2994016412, 813725030332841985, 148817821, 3068864600, 963434618329313282, 957282628301864960, 3999008719, 733080017723215874, 948587463143911424, 90572890, 825637826494558210, 970604057113931777, 12592772, 2197856160, 3074827800]

3,フォロワーのIDを抽出する

ここまでの工程では、抽出したIDがフォロワーなのかそうでないのかはまだ判定できません。
次にこれをもう一度TwitterAPIに投げて判定します。

まずは、前の記事で作った”connect_api.py”にもう一つ関数を追加しましょう。

connect_api.py

# -*- coding:utf-8 -*-


from requests_oauthlib import OAuth1Session



class Request_info():

    def __init__(self):
        self.url_timeline = "https://api.twitter.com/1.1/statuses/home_timeline.json"
        #↓エンドポイントURLを追加
        self.url_friendships = "https://api.twitter.com/1.1/friendships/lookup.json"
        self.ck = "*****************************"
        self.cs = "*****************"
        self.at = "***********************************"
        self.ats = "*************************"


class Read_api(Request_info):

    def get_timeline(self):
        continer = []
        twitter = OAuth1Session(self.ck, self.cs, self.at, self.ats)
        req = twitter.get(self.url_timeline, params={})
        if req.status_code == 200:
            return [True, req.status_code, req]
        else:
            status = "GET TIMELINE" + str(req.status_code)
            return [False, status, False]


    def get_friendships(self, ids):
        #判定用の情報をAPIから取得する
        params = {"user_id": ids}
        twitter = OAuth1Session(self.ck, self.cs, self.at, self.ats)
        req = twitter.get(self.url_friendships, params=params)
        if req.status_code == 200:
            return [True, req.status_code, req]
        else:
            status = "GET FRIENDSHIPS" + str(req.status_code)
            return [False, status, False]

次に、APIに投げる前にユーザーIDの一覧をカンマ区切りの文字列に変換します。
APIに渡すパラメータは文字列でなければならないからです。

これも処理としてはユーザーIDを抽出したときと全く同じ。繰り返し処理をします。
違うのはリストに格納するのではなく、空の文字列に追記していくという形であることです。
そして最後に、文字列の一番うしろの余分なカンマを削除します。

str_ids = ""

for user_id in user_list:
    str_ids += str(user_id) + ","

str_ids = str_ids[:-1]

この文字列に変換したユーザーIDを、さきほど追加した関数に渡します。
これでフォロワーを判定するための情報が取得できます。

>>>import connect.api
>>>C = connect_api.Read_api()
>>>result2 = C.get_friendships(str_ids)

さて、それではAPIから返ってきた情報からフォロワーのみを抜き出してみましょう。

“result2″はリスト型のデータで、[2]にユーザーの情報が入っています。
データはJSON形式になっているので、まずはこれを変換します。

result2 = result[2].json()

次に、変換したデータを繰り返し処理にかけてフォロワーのみを抽出します。

このとき参照するのは各ユーザーデータの[‘connections’]のセクションです。
ここに’followed_by’という文字列が入っているのがフォロワーです。

followers = []

for user in result2:
    if 'followed_by' in user['connections'] and user['id'] not in followers:
        followers.append(user['id'])

さあ、これでフォロワーのユーザーIDのみを抜き出すことができました!
“followers”の中に抽出したIDが格納されています。

>>> followers
[897472524627222530, 2543661997, 2984303878, 964045059116056576, 11328252, 112724844, 954941467050442752, 709319781027942400, 711381326671130626, 2812894670, 4103429806, 985339908146393088, 146595646, 296150557, 1399480400, 39031080, 4851591537, 217647664, 806426183843749888, 758545192592941056, 951778899276410880, 988494933446217728, 2598958794, 2957320841, 1136574486, 792556623948500994, 894560540852224001, 470939195, 99808390, 2491452625, 730755035504611328, 978629778784665601, 838284677530054657, 2994016412, 813725030332841985, 963434618329313282, 957282628301864960, 3999008719, 733080017723215874, 948587463143911424, 970604057113931777, 2197856160, 3074827800]

本当にフォロワーのみが抽出されているのか確認するには、最初に取得した”user_list”と要素数を比べてみるとよくわかります。
“user_list”は抽出前の状態ですから、フォロワーのみを抽出した後の”followers”のほうが要素集が少なくなっているはずです。

要素数が60から43に減っていますね。
ちゃんとフォロワーのみを抽出できています。

>>> print(len(user_list))
60
>>> print(len(followers))
43

4,フォロワーのツイートのみを抽出する

これで、最後の工程です。
最初に取得したタイムラインのデータ”result”からフォロワーのデータのみを抜き出します。

これには、さきほど抽出したフォロワーのIDリストを使います。
空のリスト”tweet_list”を作り、ツイートしているユーザーのIDがフォロワーのIDリストの中にあればそこに追加していきます。

これも今までと全く同じ要領ですね。
タイムラインのデータを繰り返し処理にかけてifで判定します。

tweet_list = []

for tweet in result[2]:
    if tweet['user']['id'] in followers:
        tweet_list.append(tweet)

さて、これで”tweet_list”にフォロワーのツイートだけが格納されました!

これも、タイムラインのデータと要素数を比べると明らかに減っていることがわかりますね。
ちゃんとフォロワーのツイートのみが抽出されているようです。

>>> print(len(result[2]))
99
>>> print(len(tweet_list))
74

ではでは、今回はこのあたりで失礼します。
かなり長くなってしまいましたが、最後までお付き合いくださってありがとうございます!