Как получить более 100 результатов с помощью Twitter4j
Я использую библиотеку Twitter4j для извлечения твитов, но я недостаточно для своих целей. В настоящее время я получаю максимум 100 с одной страницы. Как реализовать maxId и afterId в нижнем коде в разделе Обработка, чтобы получить более 100 результатов из API поиска в Twitter? Я совершенно не знаком с обработкой (и программированием в целом), поэтому любое направление на этом было бы потрясающе! Спасибо!
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() {
}
Ответы
Ответ 1
К сожалению, вы не можете, по крайней мере, не так, как это делаете
query.setCount(101);
Как javadoc говорит, что он разрешит до 100 твитов.
Чтобы преодолеть это, вам просто нужно запросить их в партиях и в каждой партии установить максимальный идентификатор, который вы получите на 1 меньше, чем последний идентификатор, полученный из последнего. Чтобы обернуть это, вы собрали каждый твит из процесса в ArrayList (который, кстати, не должен оставаться общим, но имеет свой тип, определенный как ArrayList<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>();
потому что вы должны всегда использовать интерфейс, если хотите добавить другую реализацию. Это, конечно, если вы работаете с обработкой 2.x, это потребует вначале:
import java.util.List;
Ответ 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);
}
}
Ответ 3
Из документа API поиска в Twitter:
В это время пользователи, представленные токена доступа, могут делать 180 запросов/запросов за 15 минут. Используя приложение только для приложений, приложение может делать 450 запросов/запросов в течение 15 минут от своего имени без контекста пользователя.
Вы можете подождать 15 минут, а затем собрать еще одну партию из 400 твитов, что-то вроде:
if(tweets.size() % 400 == 0 ) {
try {
Thread.sleep(900000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Ответ 4
Просто отследите самый низкий Status
id и используйте это, чтобы установить 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 на Работа с Timeline.