質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.12%

Twitter API の呼び出しのタイミングは?

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 254

hajifu

score 31

背景

最近Pythonを学習している者です。
今、tweepyを使ってTwitterの自分のフォローやフォロワーの情報を得たり、条件に沿ってフォロー解除するプログラムを作成しています。

問題 TweepError?で終了してしまう

しかしフォロワー4-500くらいならば情報を得ることはできたのですが、2000人近く読み込むときにエラーになってしまいます。
その他にも下記のような自分のツイート500件取得してRT/favしてくれた人の一覧を得るプログラムを作ったのですが、そちらもエラーになってしまいます(件数小さい規模ならうまくいきました)

Twitter apiの呼び出し制限にかかっていると思われたので、下記のようなtry: except:を使って回避を試みましたがエラーで終了してしまいます。

import tweepy
import json
import re
import csv
import urllib.request
from tqdm import tqdm
from time import sleep
from tweepy.error import TweepError

CONSUMER_KEY = "0000000000000000000000000"
CONSUMER_SECRET = "0000000000000000000000000"
ACCESS_TOKEN = "0000000000000000000000000"
ACCESS_TOKEN_SECRET = "0000000000000000000000000"

auth = tweepy.OAuthHandler(CONSUMER_KEY, CONSUMER_SECRET)
auth.set_access_token(ACCESS_TOKEN, ACCESS_TOKEN_SECRET)
api = tweepy.API(auth, wait_on_rate_limit = True)

# リツイート・ファボした人の空のリスト用意
rt_acount = []
fav_acount = []
pages = [1, 2, 3, 4, 5]
retry = 0
def RtFav_collection(pages, counts):
    global rt_acount
    global fav_acount
    global retry
    counta = counts
    for page in pages:
        try:
            usertimeline = api.user_timeline(id="hogehoge_hoge", count=100, page=page)
            print("===============", page, "ページ目の取得開始! ===============")

            # ↓●ページ目の△ツイート目でエラーになった場合△ツイート目から再開できるようにしたかった
            if counta >= 100:
                counta = 0
            elif counta != 0:
                del usertimeline[0:counta:1]
                print(counta + 1, "ツイート目から再開")

            for retweeter in tqdm(usertimeline):
                retwe = api.retweets(id=retweeter.id_str)
                for rt in retwe:
                    rt_id = rt.user.screen_name
                    if rt_id not in rt_acount:
                        rt_acount.append(rt_id)
                        print("rt追加 3秒待機します。")
                        sleep(3)
        # usertimeline を参照しファボした人も同様にリストに追加 
                json_data = urllib.request.urlopen('https://twitter.com/i/activity/favorited_popup?id=' + retweeter.id_str).read()
                # json_data をstrに変換
                json_data = json_data.decode("utf8")
                found_ids = re.findall(r'data-screen-name=\\"+\w+', json_data)
                for fav in found_ids:
                    fav_id = fav.replace('data-screen-name=\\"',"").strip()
                    if fav_id not in fav_acount:
                        fav_acount.append(fav_id)
                        print("fav追加 3秒待機します。")
                        sleep(3)
                counta += 1
        except TweepError:
            print("================= 制限に到達したため15分スリープして再開します =================")
            retry += 1
            if retry == 3:
                print("エラー 終了")
                break
            sleep(60 * 15 + 10)
            print("再開します。")
            pages = list(i * 1 for i in range(page, 6))
            RtFav_collection(pages, counta)

RtFav_collection(pages, 0)

if "hogehoge_hoge" in rt_acount:
    rt_acount.remove("hogehoge_hoge")
if "hogehoge_hoge" in fav_acount:
    fav_acount.remove("hogehoge_hoge")

with open(r"C:\Users\ユーザー名\Desktop\snspython\rt_acount.csv", "a") as f:
    writer = csv.writer(f)
    writer.writerow(rt_acount)
    print("過去1年にリツイートした人を rt_acount.csv に保存しました。")

with open(r"C:\Users\ユーザー名\Desktop\snspython\fav_acount.csv", "a") as f:
    writer = csv.writer(f)
    writer.writerow(fav_acount)
    print("過去1年いいねした人を fav_acount.csv に保存しました。")

知りたいこと

上記コードの問題点。

また、今後もTwitter apiを使って開発するうえで似たような問題に対処するため、
この制限にかかる"呼び出し"というのが一体どのタイミングなのか教えていただきたいです。

このコードでいう、「api.~」という部分で呼び出しているということでしょうか?
そうならばできるだけ「api.~」を減らしたり一回の呼び出しで多く取得するようにすればいいのでしょうか?
また呼び出しの制限は、種類を問わず15分に15回ということなのでしょうか?

宜しくお願い致します。
なにぶん初心者ですので、基本的なことや根本的なこともご指摘いただければと思います。
文脈を読む努力はしつつもいろんなサイトから切り貼りしたプログラムですので、根本的なことがわかっていない可能性があります。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

0

このコードでいう、「api.~」という部分で呼び出しているということでしょうか?

実際に利用したわけではないのですが、以下のリファレンスとgithubから確認した感じだとapi.***で一度TwitterAPIを叩いているように思います。

tweepyのリファレンス

また呼び出しの制限は、種類を問わず15分に15回ということなのでしょうか?

呼び出すものによって違いますので、正確に確認したいなら以下を参照してください。
制限がかかっていることからおそらく無料のアカウントだと思いますので、それぞれのページでStandard (free)の箇所を参照すればいいかと思います。また、それぞれによって、100件分しか取れないなどの制限もあるので、解除したい場合は課金が必要になるかと思います。

TwitterAPIデベロッパーの料金体系など

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.12%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる