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;
}
}
希望这对您有所帮助。
我正在创建一个 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;
}
}
希望这对您有所帮助。