2016-07-21 11 views
4

私はsince_idを使用してtwitter検索APIを使用してツイートを取得しようとしています。以下は私のコードです、ここで私はクエリオブジェクトのマップを作成しています。 since idを0にデフォルト設定しています。私の目的は、クエリを実行するたびにsince idを更新することです。次回にクエリを実行しようとすると、同じつぶやきが得られず、最後のつぶやきから開始する必要があります。twitter4j idが更新されていないので

import java.io.{PrintWriter, StringWriter} 
import java.util.Properties 
import com.google.common.io.Resources 
import twitter4j._ 
import scala.collection.JavaConversions._ 
// reference: http://bcomposes.com/2013/02/09/using-twitter4j-with-scala-to-access-streaming-tweets/ 
object Util { 
    val props = Resources.getResource("twitter4j.props").openStream() 
    val properties = new Properties() 
    properties.load(props) 

    val config = new twitter4j.conf.ConfigurationBuilder() 
     .setDebugEnabled(properties.getProperty("debug").toBoolean) 
     .setOAuthConsumerKey(properties.getProperty("consumerKey")) 
     .setOAuthConsumerSecret(properties.getProperty("consumerSecret")) 
     .setOAuthAccessToken(properties.getProperty("accessToken")) 
     .setOAuthAccessTokenSecret(properties.getProperty("accessTokenSecret")) 
    val tempKeys =List("Yahoo","Bloomberg","Messi", "JPM Chase","Facebook") 
    val sinceIDmap : scala.collection.mutable.Map[String, Long] = collection.mutable.Map(tempKeys map { ix => s"$ix" -> 0.toLong } : _*) 
    //val tweetsMap: scala.collection.mutable.Map[String, String] 
    val configBuild = (config.build()) 
    val MAX_TWEET=100 
    getTweets() 

    def getTweets(): Unit ={ 
     sinceIDmap.keys.foreach((TickerId) => getTweets(TickerId)) 
    } 

    def getTweets(TickerId: String): scala.collection.mutable.Map[String, scala.collection.mutable.Buffer[String]] = { 
     println("Search key is:"+TickerId) 
     var tweets = scala.collection.mutable.Map[String, scala.collection.mutable.Buffer[String]]() 
     try { 
      val twitter: Twitter = new TwitterFactory(configBuild).getInstance 
      val query = new Query(TickerId) 
      query.setSinceId(sinceIDmap.get(TickerId).get) 
      query.setLang("en") 
      query.setCount(MAX_TWEET) 
      val result = twitter.search(query) 
      tweets += (TickerId -> result.getTweets().map(_.getText)) 

      //sinceIDmap(TickerId)=result.getSinceId 
      println("-----------Since id is :"+result.getSinceId) 
      //println(tweets) 
     } 
     catch { 
      case te: TwitterException => 
       println("Failed to search tweets: " + te.getMessage) 
     } 
     tweets 
    } 
} 

object StatusStreamer { 
    def main(args: Array[String]) { 
     Util 
    } 
} 

出力:

Search key is:Yahoo  
log4j:WARN No appenders could be found for logger (twitter4j.HttpClientImpl). 
log4j:WARN Please initialize the log4j system properly. 
-----------Since id is :0 
Search key is:JPM Chase 
-----------Since id is :0 
Search key is:Facebook 
-----------Since id is :0 
Search key is:Bloomberg 
-----------Since id is :0 
Search key is:Messi 
-----------Since id is :0 

私はそれが私が最初に設定していますどのような同じ値を与えるクエリを実行した後、IDから印刷しようとしていたときに問題があります。誰かが私がここで間違っていることを指摘できますか?私のアプローチが間違っている場合は、ここで働くことがわかっている場合、他の方法を共有することができます。

あなたのコードをザッと見てから、感謝

答えて

3

を、あなたがsinceIDmapの値を更新しないことが表示されます。あなたは以下のようにコメントアウトしている:

//sinceIDmap(TickerId)=result.getSinceId 

ので、キーワードごとに、since_id0から更新されることはありません。

これ以外の問題が発生している場合は、GitHubのTwitter4J SearchTweetsの例を検討する価値があります。

+0

こんにちはジョナサン、あなたの返事をありがとう、私はその結果を印刷したいと思ったので、私はその行をコメントアウトし、それはdo_send_idとmax_idへの参照を持っていない例をチェックしました。 – Explorer

+0

IIRCそれらは結果から得られた['Query'オブジェクトにあります](https://github.com/yusuke/twitter4j/blob/master/twitter4j-examples/src/main/java/twitter4j/examples/search/ SearchTweets.java#L48)。 – Jonathan

4

Twitter API戻り値since_id最初にqueryによって要求された値。つまり、QueryResult.getSinceIdQueryと同じです。

最も簡単な解決策は、次のsinceIdを応答から最大のツイートIDとして設定することです。一般的に

sinceIDmap(TickerId) = result.getTweets().max(Ordering.by(_.getId)).getId 

結果は、より多くのあなたがsince_idmax_idクエリパラメータの組み合わせを使用することができます滑らかにします。 Official twitter guideは非常に良い説明をどのようにそれらを使用しています。

+0

あなたの説明のためにありがとうナザリですので、私が 'val id = QResult.getTweets.max.getId'を使用し、このIDを次の反復のためのidとして設定すると、動作しますか? 'query.setSinceId(id)' – Explorer

+0

期待通りに動作するか試してみてください。少なくともsince_idの新しい値になるので、検索結果はより正確になります。とにかくあなたが必要とするものを正確に得るためのガイドをお読みください。 –

4

最初に、あなたのアプローチの最初の説明から、since_idを使ったアプローチが間違っているとお伝えします。私は過去に同じミスを犯し、それを働かせることができませんでした。さらに、あなたのアプローチは公式Working with Timelinesと一致しません。正式なガイドラインは私のために働いて、あなたがそれらに従うことをお勧めします。長い話を簡単に言えば、since_idだけを使用して、つぶやきのタイムライン(あなたのケースではGET search/tweetsが返すタイムライン)を移動することはできません。あなたは何かを記述するためには間違いなくmax_idが必要です。そして、実際には、私はsince_idに完全にセカンダリ/オプション機能があると信じています(あなたのコードでも同様に実装できます)。 API docsは、私がmax_idを使うことができるのと全く同じようにsince_idを使うことができると信じさせたが、間違っていた。 since_idだけを指定すると、返されたつぶやきは全く新鮮であり、あたかもsince_idが完全に無視されたかのように気づいていました。 Hereは、この予期しない動作を示す別の質問です。私が見る通り、since_idは、タイムラインを移動するのではなく、プルーニングにのみ使用されます。 since_idだけを使用すると最新の/最新のツイートが取得されますが、返されるツイートはsince_idより大きいIDを持つツイートに制限されます。あなたが望むものではありません。公式のガイドラインから取られた証拠の最後のピースは、特定の要求のこのグラフィカルな表現です:

since_id

だけでなくsince_idは、タイムラインを通してあなたを移動しないが、この中で完全に無用であることを起こるん特定の要求。ただし、次のリクエストでは役に立たなくなりません。Tweet 10(およびその前のもの)をプルーニングします。しかし、実際にはsince_idはタイムラインを移動させません。

一般的に、最新のつぶやきから古いものまで考えてみる必要があります。最新のツイートから古いツイートに移動するには、返されるツイートの上限をIDとしてmax_idと指定し、連続するリクエスト間でこのパラメータを更新する必要があります。

リクエストにmax_idが存在すると、返されるツイートのID上限を設定します。返されたツイートから、表示される最小のIDを取得し、それを次のリクエストでmax_idの値として使用することができます(最小IDを1つ減らして次のリクエストのmax_idにこの値を使用できます)。max_idは以前のリクエストから最も古いツイートをもう一度受け取ることはありません)。最初のリクエストにはmax_idが指定されていない必要があります。最新の/最新のつぶやきが返されます。このアプローチを使用すると、最初のリクエストの後の各リクエストは、過去のものへとさらに一歩進んでいきます。

since_idは、過去の旅行を制限する必要がある場合に便利です。ある時点で、t0が、あなたがつぶやきの検索を開始すると想像してください。最初の検索から最大のツイートIDがid0であると仮定しましょう。その最初の検索の後、あなたが戻ってくるので、後続の検索のすべてのツイートIDが小さくなります。しばらくすると、約1週間のつぶやきが得られ、あなたの検索で何も返されません。その時点で、t1、あなたは過去へのこの旅は終わったことを知っています。しかし、t0t1の間につぶやくされているツイートはありません。あなたがID id0(これはt0の前にツイートされています)のつぶやきに達するまで、過去への別の旅行はt1で始まります。この旅行は、旅行の要求でsince_idid0を使用して制限することができます。また、id0以下のIDを持つツイートを取得した後にトリップが終了することを確認した場合は、since_idの使用を避けることができます(ツイートを削除することができます)。しかし、私はあなたが効率と効率のためにsince_idを使用しようとすることをお勧めします。 max_idが含まれていますが、since_idは排他的であることを覚えておいてください。

詳細については、公式Working with Timelinesを参照してください。 「max_idパラメータ」のセクションが最初に来て、「効率を最大にするためにsince_idを使用する」セクションが後で表示されます。後のセクションのタイトルは、since_idではなく、タイムラインを移動するためのであることを示しています。

// Make sure this is initialized correctly. 
Twitter twitter; 

/** 
* Searches and prints tweets starting from now and going back to the past. 
* 
* @param q 
*   the search query, e.g. "#yolo" 
*/ 
private void searchAndPrintTweets(String q) throws TwitterException { 
    // `max_id` needed by `GET search/tweets`. If it is 0 (first iteration), 
    // it will not be used for the query. 
    long maxId = 0; 
    // Let us assume that it will run forever. 
    while (true) { 
     Query query = new Query(); 
     query.setCount(100); 
     query.setLang("en"); 
     // Set `max_id` as an inclusive upper limit, unless this is the 
     // first iteration. If this is the first iteration (maxId == 0), the 
     // freshest/latest tweets will come. 
     if (maxId != 0) 
      query.setMaxId(maxId); 
     QueryResult qr = twitter.search(query); 
     printTweets(qr.getTweets()); 
     // For next iteration. Decrement smallest ID by 1, so that we will 
     // not get the oldest tweet of this iteration in the next iteration 
     // as well, since `max_id` is inclusive. 
     maxId = calculateSmallestId(qr.getTweets()) - 1; 
    } 
} 

/** 
* Calculates the smallest ID among a list of tweets. 
* 
* @param tweets 
*   the list of tweets 
* @return the smallest ID 
*/ 
private long calculateSmallestId(List<Status> tweets) { 
    long smallestId = Long.MAX_VALUE; 
    for (Status tweet : tweets) { 
     if (tweet.getId() < smallestId) 
      smallestId = tweet.getId(); 
    } 
    return smallestId; 
} 

/** 
* Prints the content of the tweets. 
* 
* @param tweets 
*   the tweets 
*/ 
private void printTweets(List<Status> tweets) { 
    for (Status tweet : tweets) { 
     System.out.println(tweet.getText()); 
    } 
} 

は何のエラー処理、チェック特別な条件はありません(例えば空:ツイート最新から始まり、過去に行くを出力JavaでTwitter4Jを使用して

粗いテストされていない例は、以下のとおりです。クエリ結果のつぶやきのリスト)、そしてsince_idの使用はありませんが、それはあなたを始めなければなりません。

+0

こんにちはxnakosはあなたの返事に感謝します。上記のコンセプトの実例がありますか? – Explorer

+0

@Novice twitter4jを使ってJavaサンプルを気にしますか? – xnakos

+0

@Novice Twitter4J/Javaのサンプルを追加しましたが、テストされていませんが、多かれ少なかれ動作するはずです。 – xnakos

1

since_idとmax_idは両方とも非常に単純なパラメータで、APIから戻ってくるものを制限するために使用できます。ドキュメントから:

since_id - 指定されたIDより大きい(つまり、より新しい)IDを持つ結果を返します。 APIを介してアクセスできるツイートの数には制限があります。 since_idからTweetsの制限が発生した場合、since_idは利用可能な最も古いIDに強制されます。 max_id - 指定されたIDより小さい(つまり、より古い)IDを持つ結果を返します。 したがって、ある特定のツイートIDを持っている場合は、これらの2つのパラメータを使用して、より古いツイートや新しいツイートを検索できます。

カウントがさらに簡単です - あなたは、日付を指定することはできません - それは残念ながら、APIが正確に何をしたいあなたに戻って与えることはありません200

まで、あなたが戻って取得したいツイートの最大数を指定します/ user_timelineを照会する時間 - 検索APIを使用するときに指定することはできますが、とにかく、あなたがuser_timelineを使う必要があれば、あなたはAPIをポーリングし、つぶやきを集め、あなたが望むパラメータと一致するかどうかを調べ、それに応じて統計を計算する必要があります。

関連する問題