【问题标题】:Twitter4J: How to solve the rate limit request of Twitter API?Twitter4J:如何解决 Twitter API 的限速请求?
【发布时间】:2015-01-25 20:50:07
【问题描述】:

我正在创建一个使用 Twitter4J 库与 Twitter 交互的 Java 应用程序。 我想从 twitter 下载 10 000 个节点,然后对创建的图进行统计。该图最初保存在数据集(.txt 文件)中。 我还必须为每个节点保存足够的 ReTweet(所以我必须检查它们的时间线)。

跳过twitter的实例化执行查询,我有两个问题和疑惑: 1) 我该如何处理 Twitter API 在 15 分钟内需要的数量有限的问题?

我试过这个:

public static RateLimitStatus getApplicationRateLimitStatus(Twitter twitter)
{
    try {
        Map<String ,RateLimitStatus> rateLimitStatus = twitter.getRateLimitStatus();
        for (String endpoint : rateLimitStatus.keySet()) 
        {
            if (endpoint.equals("/application/rate_limit_status"))
                return rateLimitStatus.get(endpoint);
        }
    } catch (TwitterException te) 
        {
            te.printStackTrace();
            System.out.println("Failed to get rate limit status: " + te.getMessage());
            System.exit(-1);
        }       
    return null; 
}

public static void control(Twitter twitter)
{
    RateLimitStatus app_rate_limit_st = null;
    RateLimitStatus user_timeline_limit_st = null;
    RateLimitStatus credentials_limit_st = null;
    RateLimitStatus friends_list_limit_st = null;
    RateLimitStatus followers_list_limit_st = null;
    int ctr_req = 7;

    try {
        if ((app_rate_limit_st = MyRateLimit.getApplicationRateLimitStatus(twitter)).getRemaining() < ctr_req)
        {
            System.out.println("I'm waiting "+app_rate_limit_st.getSecondsUntilReset()+" seconds for Application Rate Limit, app request remaining: "+app_rate_limit_st.getRemaining());
            Thread.sleep((long)app_rate_limit_st.getSecondsUntilReset()*1000);
            System.out.println("I woke up!!!");
        }
    }catch(InterruptedException e) {e.printStackTrace();}
}

在此代码块中,我仅检查了请求 ApplicationRequest 类型,但在我的应用程序中,我还检查了所需类型 FriendList、FollowersList、UserTimeline 和 Credentials。

通过运行我的应用程序,会引发该通知 我已经超过了可用应用程序的数量,不明白为什么。

2) 另一个问题是应该使用哪种算法来下载节点。 我考虑过一个流行的节点(有很多朋友和追随者,并且彼此互动很多)。 我试图取节点,在朋友,他的追随者,然后是朋友的朋友和追随者以及追随者的朋友和追随者。 这是一种巧妙的技术?他们会更清楚吗?

谢谢。

【问题讨论】:

  • 另一个问题...我遇到错误代码 503 的异常,并显示消息:“Twitter 服务器已启动,但请求超载。稍后再试”。现在应用程序停止了。为什么会发生这个错误?速率限制不是用来避免错误的吗?

标签: java twitter twitter4j


【解决方案1】:

想一想如何解决速率限制问题 - 创建多个 twitter oauth 凭证,您可以维护一个配置有每个可用凭证的 Twitter 实例列表/集,当您达到 id1 的速率限制时,您可以切换到使用 id2 来获取记录。

不要使用 getApplicationRateLimitStatus,而是检查功能速率限制状态并进行切换,这将帮助您根据该 API 的可用限制来规划切换。

--根据评论cmets在下面添加代码/cmets,

您可以执行以下操作,对于每个请求,您可以使用连接器,在您的情况下,您可能需要缓存一些可用于进行下一次调用的信息,例如 sinceId 和 maxId。

您需要创建/注册多个 Twitter 帐户并为每个帐户生成凭据。我曾尝试过这种方法来加快获取大约 100 万用户的信息,并且很有效。

您还可以缓存一些重复出现的信息并在 Twitter 上保存一些点击量,例如在 10 人的网络中,可能会有一定比例的普通用户/关注者,因此可以在下一个请求中跳过之前获取的用户信息来查找用户信息.

getTweetConnector() 方法将确保您获得一个已重置其速率限制的连接器。

由于您通过多个 API 获取信息,因此您可以为特定请求批量处理连接器,以便具有更高 rateLimit 的 API 可以拥有更多连接器。

public class TweetUserInfo {
private Set<Twitter> mTwitterConnectorsSet;
private BufferedReader mUserFileReader;

TweetUserInfo(){
    mTwitterConnectorsSet = new HashSet<Twitter>();
}

private void initTweetConnectors(String inFile) {
    BufferedReader br = null;
    try {
        String line = null;
        String[] lines = new String[4];
        int linesIndex = 0;
        br = new BufferedReader(new FileReader(inFile));

        while ((line = br.readLine()) != null) {
            if (linesIndex == 4) {
                createAndAddTwitterConnector(lines);
                linesIndex = 0;
            }
            lines[linesIndex] = line;
            ++linesIndex;
        }
        if (linesIndex == 4) {
            createAndAddTwitterConnector(lines);
        }

    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            if (br != null)br.close();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }
}

private void createAndAddTwitterConnector(String[] lines) {
    ConfigurationBuilder twitterConfigBuilder = new ConfigurationBuilder();
    twitterConfigBuilder.setDebugEnabled(true);

    for (int i = 0; i < lines.length; ++i) {
        String[] input = lines[i].split("=");

        if (input[0].equalsIgnoreCase("consumerkey")) {
            twitterConfigBuilder.setOAuthConsumerKey(input[1]);
        }
        if (input[0].equalsIgnoreCase("consumersecret")) {
            twitterConfigBuilder.setOAuthConsumerSecret(input[1]);
        }
        if (input[0].equalsIgnoreCase("accesstoken")) {
            twitterConfigBuilder.setOAuthAccessToken(input[1]);
        }
        if (input[0].equalsIgnoreCase("accesstokensecret")) {
            twitterConfigBuilder.setOAuthAccessTokenSecret(input[1]);
        }
    }
    Twitter twitter = new TwitterFactory(twitterConfigBuilder.build()).getInstance();
    mTwitterConnectorsSet.add(twitter);
}

private Twitter getTweetConnector() {
        for (Twitter tc : mTwitterConnectorsSet) {
            try {
                if (tc.getRateLimitStatus() != null) {
                    if (tc.getRateLimitStatus().containsKey("/users/lookup")) {
                        if (tc.getRateLimitStatus().get("/users/lookup") != null) {
                            System.out.println("tc - "+tc);
                            System.out.println("tc rate - "+tc.getRateLimitStatus().get("/users/lookup").getRemaining());
                            if (tc.getRateLimitStatus().get("/users/lookup").getRemaining() > 2) {
                                return tc;
                            }
                        }
                    }
                }
            } catch (TwitterException e) {
                e.printStackTrace();
            }
        }
    return null;
}

}

希望这会有所帮助。

【讨论】:

  • 感谢您的回复。我还通过这种可能的解决方案阅读了其他帖子。我无法理解如何创建多个 twitter oauth 凭据。我想您不打算创建多个 Twitter 帐户,对吧?我能怎么做?你会有几行示例代码?
  • 我正在做的就是进行切换的解决方案。每次我向 twitter 发出请求时,检查我还剩下多少个请求,如果你不留下,我发送到睡眠应用程序(如我引用的代码中所示)
  • 更新了答案,请检查是否能帮助您解决问题。
  • 是的,很清楚。好奇,你必须创建多少个 Twitter 帐户?
  • 哦..感谢@AndyPiper 不知道的更新。
猜你喜欢
  • 2016-04-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-07
  • 1970-01-01
  • 2018-07-25
相关资源
最近更新 更多