Twitter4J:如何解决Twitter的限速请求API?

Twitter4J: How to solve the rate limit request of Twitter API?

我正在创建一个 java 应用程序,它使用库 Twitter4J 与 Twitter 交互。 我想从 twitter 下载 10000 个节点,然后对创建的图进行统计。该图最初保存在数据集(.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) 另一个问题是应该使用哪种算法来下载节点。 我想过取一个热门节点(有很多朋友和追随者,并且彼此之间互动很多)。 我尝试获取节点,关于朋友,他的追随者,然后是朋友和朋友的追随者以及追随者的朋友和追随者。 这是一个聪明的技术?他们会更清楚吗?

谢谢。

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

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

--根据评论意见在下面添加code/comments,

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

您需要 create/register 多个 Twitter 帐户并为每个帐户生成凭据。我试过这种方法来加快大约100万用户的信息获取速度,而且很有效。

您还可以缓存一些重复出现的信息并保存对 Twitter 的少量点击,例如在 10 人的网络中可能有一定比例的共同点 users/followers 因此要查找用户信息,以前获取的用户可以是在下一个请求中跳过。

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;
}

}

希望这对您有所帮助。