我正在创建一个使用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) 另一个问题是哪个算法应该继续下载节点。 我考虑过采用一个受欢迎的节点(有很多朋友和粉丝,并且互相交流很多)。 我试图接受节点,朋友,他的粉丝,以及朋友和朋友的追随者以及粉丝的追随者。 这是一个聪明的技巧?他们会更清楚吗?
感谢。
答案 0 :(得分:1)
只考虑如何解决速率限制问题 - 创建多个twitter oauth凭证,您可以维护使用每个可用凭证配置的Twitter实例的列表/集合,当您达到说id1的速率限制时,您可以切换到使用id2来获取记录。
检查功能速率限制状态并进行切换,而不是使用getApplicationRateLimitStatus,这将帮助您根据该API的可用限制来规划交换机。
- 根据评论评论添加以下代码/评论,
您可以执行以下操作,对于您可以使用连接器的每个请求,在您的情况下,您可能需要缓存一些可用于进行下一次调用的信息,如sinceId和maxId。
您需要创建/注册多个Twitter帐户并为每个帐户生成凭据。我曾尝试过这种方法来为大约1M用户提取信息,这很有效。
您还可以缓存一些重复信息并保存少量点击到Twitter,例如在10人的网络中可能有一定比例的普通用户/关注者,因此查找用户信息可以在下一个请求中跳过以前获取的用户
getTweetConnector()方法将确保您获得一个已重置其ratelimit的连接器。
由于您是通过多个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;
}
}
希望这有帮助。