python-twitterのGetFriends()で100人以上取得する
昨日、フレンドリストを100人以上取得するためにtwitter.pyを色々いじりました。その結果、
users = api.GetFriends(取得ページ番号)
こんな感じで呼び出せるようになりました。ページ番号で3を指定すると、ID*1順で201〜300番を取得します。
でもこれだといちいちページ番号を指定しないといけないので面倒です。
そこで今回はGetFriends()に引数を与えたりごちゃごちゃいじくって機能拡張*2してみました。
前回同様、twitter.pyの最後に以下を付け足します。
PAGELIMIT = 10 # number of friends can get once class TwitterApi(Api): def GetFriends(self, pagebegin=1, pageto=PAGELIMIT, user=None): friends = [] cntpage = pagebegin while True: print "Getting friends: %d - %d" % (cntpage*100-99, cntpage*100) if user: url = 'http://twitter.com/statuses/friends/%s.json?page=%d' % (user, cntpage) else: url = 'http://twitter.com/statuses/friends.json?page=%d' % cntpage json = self._FetchUrl(url) data = simplejson.loads(json) currentfriends = [User.NewFromJsonDict(x) for x in data] friends += currentfriends if len(currentfriends) % 100 != 0 or currentfriends == [] or cntpage == pageto: break cntpage += 1 if cntpage == pagebegin+PAGELIMIT: print 'You can get friends only to 1000 for not to be API-limt.' print 'To get next 1000 friends, call: GetFriends(%d, %d, "%s")' % (pagebegin+PAGELIMIT, pagebegin+(PAGELIMIT*2-1), user) break return friends
ちくしょう綺麗に書けない・・・PAGELIMITなんてGetFriends()メソッド内でしか使わないのにクラスの外で宣言してるしw でもここに書かないと動かなかった。どうすればいいんだー
解説します。
GetFriends(取得開始ページ, 取得終了ページ, ユーザー名)
という形で使います。すべての引数は省略可能です。省略した場合、自分のフレンドリストを頑張って取得します。
1時間に70回までしかリクエストできない点,何千人単位でfollowingを持つユーザーもいる点*3を考慮して、この拡張版でも1度に取得できるのは「1000人まで(10ページ)」にしてあります。増やしたい・減らしたい場合はソース最初のPAGELIMITという変数から変更できます。
取得ユーザーのfollowingが1000人以内なら何事もなく終了します。
取得ページ範囲が10ページを超える場合、1000件まで取得した後以下のようなメッセージを吐きます。
You can get friends only to 1000 for not to be API-limt. To get next 1000 friends, call: GetFriends(pagebegin, pageto, user-id)
最後のGetFriends()の引数には、実行時に与えていた引数に応じて次の1000件を取得するための値が入ります。
使用例を何個か書いておきます。
・following1000人以内の場合
>>> import twitter >>> api = twitter.TwitterApi("ユーザー名", "パスワード") >>> users = api.GetFriends() #取得範囲の指定なし Getting friends: 1 - 100 Getting friends: 101 - 200 >>> len(users) #取得ユーザー数を確認 129
followingが1000人以内だと、引数の指定などは特に必要ありません。Twitterがちゃんと応答してくれれば無事に全員取得できます。
・followingが1000人を超える場合1
>>> # following1001人以上のユーザーを指定 >>> # 取得終了ページを0にすると引数指定なしと同じ動作をする(全員取得しようとする) >>> users = api.GetFriends(1, 0, "ユーザー名") Getting friends: 1 - 100 Getting friends: 101 - 200 Getting friends: 201 - 300 Getting friends: 301 - 400 Getting friends: 401 - 500 Getting friends: 501 - 600 Getting friends: 601 - 700 Getting friends: 701 - 800 Getting friends: 801 - 900 Getting friends: 901 - 1000 You can get friends only to 1000 for not to be API-limt. To get next 1000 friends, call: GetFriends(11, 20, "ユーザー名") >>> len(users) 1000
1000人まで取得後、警告と次の1000人を取得するための呼び出し方が表示されます。
・followingが1000人を超える場合2
>>> # 取得範囲を10ページきっかり指定する >>> users = api.GetFriends(63, 72, "ユーザー名") Getting friends: 6201 - 6300 Getting friends: 6301 - 6400 Getting friends: 6401 - 6500 Getting friends: 6501 - 6600 Getting friends: 6601 - 6700 Getting friends: 6701 - 6800 Getting friends: 6801 - 6900 Getting friends: 6901 - 7000 Getting friends: 7001 - 7100 Getting friends: 7101 - 7200 >>> len(users) 1000
こちらも1000人取得するけど、10ページぴったりなので警告は出ません。
・7000人まで1度に取得する方法*4
PAGELIMITを書き換えても良いんだけど、いちいちモジュール書き換えるのは面倒&気分悪いので。
followingが7000人以内なら、この方法で一括取得できます。大体API制限に引っかかるか、503とか502が返ってきて失敗すると思うけどw
#!/usr/bin/env python # -*- coding: utf-8 -*- import twitter api = twitter.TwitterApi("ユーザー名", "パスワード") friends = []; page = 1; while True: users = api.GetFriends(page, page+9, "フォロー多いユーザー") friends += users if len(users) % 100 != 0 or users == [] or page == 70: break page += 10 print "%d friends" % len(friends)
すっごい時間かかるよ!特に5000人とか超えてくると取得中なの忘れて読書とかできちゃう感じ。
実行結果
$ python p-twitter.py Getting friends: 1 - 100 Getting friends: 101 - 200 Getting friends: 201 - 300 --- 中略 --- Getting friends: 2101 - 2200 Getting friends: 2201 - 2300 Getting friends: 2301 - 2400 2306 friends
いっぱい取得できました。
・その他tips?
結構(かなり)ページ取得に時間がかかるので、フリーズしている訳ではないことを表すために、デフォルトでは「Getting〜」と処理の過程をprintしています。「フレンドリストを取得して〜して〜する」という風に他にも色々処理をする場合、「Getting〜」の表示が邪魔になると思うので、その時はprintの行をコメントアウトしてください。↓
#print "Getting friends: %d - %d" % (cntpage*100-99, cntpage*100)
このエントリー書くためにAPI制限ひっかかりまくって、結局1日以上かかった><
TwitDir - a Twitter directory - Top 100 followersによると1番following多い人63458人だってwwwすげぇな!
followingを取得するために色々やってみたけど、「following取得→ファイルに保存するプログラム」を作って、何かしたい時はそのファイルから読み込むのが1番実用的な気がします。取得に結構時間かかる上にTwitterが不安定だからよく失敗しちゃう。