10

我正在使用 Twitter4j 库来检索推文,但对于我的目的来说,我得到的还远远不够。目前,我从一页中获得最多 100 个。为了从 Twitter 搜索 API 检索超过 100 个结果,如何在 Processing 中的以下代码中实现 maxId 和 sinceId?我对处理(和一般编程)完全陌生,所以任何关于这方面的指导都会很棒!谢谢!

void setup() {

  ConfigurationBuilder cb = new ConfigurationBuilder();
  cb.setOAuthConsumerKey("xxxx");
  cb.setOAuthConsumerSecret("xxxx");
  cb.setOAuthAccessToken("xxxx");
  cb.setOAuthAccessTokenSecret("xxxx");

  Twitter twitter = new TwitterFactory(cb.build()).getInstance();
  Query query = new Query("#peace");
  query.setCount(100);

  try {
    QueryResult result = twitter.search(query);
    ArrayList tweets = (ArrayList) result.getTweets();

    for (int i = 0; i < tweets.size(); i++) {
      Status t = (Status) tweets.get(i);

      GeoLocation loc = t.getGeoLocation();

      if (loc!=null) {
        tweets.get(i++);

        String user = t.getUser().getScreenName();
        String msg = t.getText();

        Double lat = t.getGeoLocation().getLatitude();
        Double lon = t.getGeoLocation().getLongitude();

        println("USER: " + user + " wrote: " + msg + " located at " + lat + ", " + lon);

      }
    }
  }

  catch (TwitterException te) {
    println("Couldn't connect: " + te);
  };
}

void draw() {
}
4

4 回答 4

23

不幸的是,您不能,至少不能以直接的方式,例如做

query.setCount(101);

正如javadoc所说,它最多只能允许 100 条推文。

为了克服这个问题,您只需要分批请求它们,并且在每批中将您获得的最大 ID 设置为比您从最后一个获得的最后一个 ID 小 1。总结一下,您将流程中的每条推文收集到一个 ArrayList 中(顺便说一下,它不应该保持通用,而是将其类型定义为ArrayList<Status>- 一个携带 Status 对象的 ArrayList),然后打印所有内容!这是一个实现:

void setup() {

  ConfigurationBuilder cb = new ConfigurationBuilder();
  cb.setOAuthConsumerKey("xxxx");
  cb.setOAuthConsumerSecret("xxxx");
  cb.setOAuthAccessToken("xxxx");
  cb.setOAuthAccessTokenSecret("xxxx");

  Twitter twitter = new TwitterFactory(cb.build()).getInstance();
  Query query = new Query("#peace");
  int numberOfTweets = 512;
  long lastID = Long.MAX_VALUE;
  ArrayList<Status> tweets = new ArrayList<Status>();
  while (tweets.size () < numberOfTweets) {
    if (numberOfTweets - tweets.size() > 100)
      query.setCount(100);
    else 
      query.setCount(numberOfTweets - tweets.size());
    try {
      QueryResult result = twitter.search(query);
      tweets.addAll(result.getTweets());
      println("Gathered " + tweets.size() + " tweets");
      for (Status t: tweets) 
        if(t.getId() < lastID) lastID = t.getId();

    }

    catch (TwitterException te) {
      println("Couldn't connect: " + te);
    }; 
    query.setMaxId(lastID-1);
  }

  for (int i = 0; i < tweets.size(); i++) {
    Status t = (Status) tweets.get(i);

    GeoLocation loc = t.getGeoLocation();

    String user = t.getUser().getScreenName();
    String msg = t.getText();
    String time = "";
    if (loc!=null) {
      Double lat = t.getGeoLocation().getLatitude();
      Double lon = t.getGeoLocation().getLongitude();
      println(i + " USER: " + user + " wrote: " + msg + " located at " + lat + ", " + lon);
    } 
    else 
      println(i + " USER: " + user + " wrote: " + msg);
  }
}

注:线路

ArrayList<Status> tweets = new ArrayList<Status>();

应该正确地是:

List<Status> tweets = new ArrayList<Status>();

因为如果您想添加不同的实现,您应该始终使用该接口。当然,如果您使用的是 Processing 2.x,那么一开始就需要这样做:

import java.util.List;
于 2013-09-14T18:40:55.190 回答
2

这是我根据过去的答案为我的应用程序制作的功能。谢谢大家的解决方案。

List<Status> tweets = new ArrayList<Status>();

void getTweets(String term)
{
int wantedTweets = 112;
long lastSearchID = Long.MAX_VALUE;
int remainingTweets = wantedTweets;
Query query = new Query(term);
 try
{ 

  while(remainingTweets > 0)
  {
    remainingTweets = wantedTweets - tweets.size();
    if(remainingTweets > 100)
    {
      query.count(100);
    }
    else
    {
     query.count(remainingTweets); 
    }
    QueryResult result = twitter.search(query);
    tweets.addAll(result.getTweets());
    Status s = tweets.get(tweets.size()-1);
    firstQueryID = s.getId();
    query.setMaxId(firstQueryID);
    remainingTweets = wantedTweets - tweets.size();
  }

  println("tweets.size() "+tweets.size() );
}
catch(TwitterException te)
{
  System.out.println("Failed to search tweets: " + te.getMessage());
  System.exit(-1);
}
}
于 2014-11-01T20:32:48.397 回答
1

来自 Twitter 搜索 API 文档:此时,访问令牌代表的用户每 15 分钟可以发出 180 个请求/查询。使用仅应用程序身份验证,应用程序可以在没有用户上下文的情况下代表自己每 15 分钟发出 450 次查询/请求。您可以等待 15 分钟,然后收集另一批 400 条推文,例如:

            if(tweets.size() % 400 == 0 ) {
            try {
                    Thread.sleep(900000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
于 2015-08-27T07:58:52.480 回答
0

只需跟踪最低的Statusid 并使用它来设置max_id后续search调用。这将允许您一次退回 100 个结果,直到您获得足够的结果,例如:

boolean finished = false;
while (!finished) {
    final QueryResult result = twitter.search(query);    

    final List<Status> statuses = result.getTweets();
    long lowestStatusId = Long.MAX_VALUE;
    for (Status status : statuses) {
        // do your processing here and work out if you are 'finished' etc... 

        // Capture the lowest (earliest) Status id
        lowestStatusId = Math.min(status.getId(), lowestStatusId);
    }

    // Subtracting one here because 'max_id' is inclusive
    query.setMaxId(lowestStatusId - 1);
}

有关更多信息,请参阅 Twitter 的使用时间线指南。

于 2013-09-16T12:32:02.453 回答