tutorial java twitter processing twitter4j

java - tutorial - twitter4j maven



Cómo recuperar más de 100 resultados usando Twitter4j (4)

Estoy usando la biblioteca de Twitter4j para recuperar tweets, pero no estoy obteniendo lo suficiente para mis propósitos. Actualmente, obtengo ese máximo de 100 de una página. ¿Cómo implemento maxId y sinceId en el siguiente código en Procesamiento para recuperar más de los 100 resultados de la API de búsqueda de Twitter? Soy totalmente nuevo en Processing (y en la programación en general), ¡así que cualquier dirección sería increíble! ¡Gracias!

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() { }


Simplemente max_id un seguimiento del ID de Status más bajo y utilícelo para establecer el max_id para las siguientes llamadas de search . Esto le permitirá dar un paso atrás en los resultados 100 a la vez hasta que tenga suficiente, por ejemplo:

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

Consulte la guía de Twitter sobre Trabajar con líneas de tiempo para obtener más información.


Aquí está la función que hice para mi aplicación basada en las respuestas anteriores. Gracias a todos por sus soluciones.

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


Desde el documento API de búsqueda de Twitter: en este momento, los usuarios representados por tokens de acceso pueden realizar 180 solicitudes / consultas por 15 minutos. Con la autenticación de solo aplicación, una aplicación puede realizar 450 consultas / solicitudes por 15 minutos en su propio nombre sin un contexto de usuario. Puedes esperar 15 minutos y luego recolectar otro lote de 400 Tweets, algo así como:

if(tweets.size() % 400 == 0 ) { try { Thread.sleep(900000); } catch (InterruptedException e) { e.printStackTrace(); } }


Lamentablemente no se puede, al menos no de manera directa, como hacer

query.setCount(101);

Como dice javadoc , solo permitirá hasta 100 tweets.

Para superar esto, solo tiene que solicitarlos en lotes y en cada lote configure la ID máxima que obtenga para ser 1 menos que la última Id que obtuvo de la última. Para concluir, reúne cada tweet del proceso en una ArrayList (que, por cierto, no debe seguir siendo genérica, pero tiene su tipo definido como ArrayList<Status> - Una ArrayList que lleva objetos de estado) y luego ¡imprima todo! Aquí hay una implementación:

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

Nota: La línea

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

debería ser correctamente:

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

porque siempre debe usar la interfaz en caso de que quiera agregar una implementación diferente . Esto, por supuesto, si está en Processing 2.x requerirá esto al principio:

import java.util.List;