我正在尝试使用since_id来使用twitter搜索API来获取推文。下面是我的代码,这里我创建了一个查询对象的地图,因为我是id。我将自从id默认为0,我的目标是每次运行查询时更新自身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后,它给出了我最初设置的相同值。有人能指出我在这里做错了吗?或者如果我的方法有误,可以有人分享任何其他方法,如果他们知道可以在这里工作。
由于
答案 0 :(得分:4)
Twitter API返回查询最初请求的since_id
值。这意味着QueryResult.getSinceId
与Query
中的sinceId
相同。
最简单的解决方案是将下一个sinceIDmap(TickerId) = result.getTweets().max(Ordering.by(_.getId)).getId
设置为响应的最大推文ID。
since_id
通常,为了使结果更加流畅,您可以使用max_id
和<?php
$UserAgent = $_SERVER['HTTP_USER_AGENT'];
echo "$UserAgent";
?>
查询参数的组合。 Official twitter guide非常好地解释了如何使用它们。
答案 1 :(得分:4)
首先,从您对方法的初步描述中,我可以告诉您,使用since_id
的方法不正确。我过去犯了同样的错误,无法让它发挥作用。此外,您的方法与官方Working with Timelines不一致。官方指南对我有用,我建议你遵循它们。简而言之,您无法单独使用since_id
来浏览推文的时间轴(GET search / tweets
返回的时间轴,在您的情况下)。你肯定需要max_id
来做你描述的事情。而且,实际上,我认为since_id
具有完全辅助/可选功能(也可以在您的代码中实现)。 API docs让我相信我可以使用since_id
,就像使用max_id
一样,但我错了。仅指定since_id
,我注意到返回的推文非常新鲜,好像since_id
被完全忽略了。 Here是另一个证明这种意外行为的问题。在我看来,since_id
仅用于修剪,而不是用于在时间轴中移动。单独使用since_id
将获得最新/最新的推文,但限制返回到ID大于since_id
的推文。不是你想要的。从官方指南中得出的最后一个证据是特定请求的图形表示:
since_id
不仅没有让您完成时间线,而且在此特定请求中恰好无用。但是,在下一个请求中它不会没用,因为它会修剪Tweet 10
(以及之前的任何内容)。但事实是since_id
并没有让你完成时间表。
一般来说,你需要考虑从最新的推文到最古老的推文,而不是相反。从最新的推文到最早的推文,在您的请求中,您需要指定max_id
作为返回推文的ID包含上限,并在连续请求之间更新此参数。
请求中max_id
的存在将设置返回推文的ID包含上限。从返回的推文中,您可以获得出现的最小ID,并将其用作后续请求中max_id
的值(您可以将最小ID减1,并将此值用于下一个请求&#39; s { {1}},因为max_id
具有包容性,因此您不会再次获得上一个请求中最早的推文)。第一个请求应该没有指定max_id
,以便返回最新/最新的推文。使用这种方法,第一次请求后的每个请求都会让您更深入地了解过去。
max_id
可以派上用场。想象一下,在某个时间点since_id
,您开始搜索推文。我们假设您的第一次搜索时最大的推文ID是t0
。在第一次搜索之后,后续搜索中的所有推文ID将变得越来越小,因为您要回去了。过了一段时间,你将得到大约一个星期的推文,而你的搜索将不会返回任何内容。在那个时间点,id0
,你知道这次过去的旅程结束了。但是,在t1
和t0
之间,推文会发送更多推文。因此,过去的另一次旅行应该从t1
开始,直到您收到ID为t1
的推文(在id0
之前发过推文)。在旅行的请求中使用t0
id0
可以限制此行程,依此类推。或者,可以避免使用since_id
,如果您确定一旦您的推文的ID小于或等于since_id
,您的行程就会结束(请记住推文)可以删除)。但我建议你尝试使用id0
来提高效率。请记住,since_id
是独占的,since_id
是包容性的。
有关详细信息,请参阅官方Working with Timelines。你会注意到&#34; max_id参数&#34;第一部分和第34部分使用since_id以获得最高效率&#34;来晚了。后一部分的标题表示max_id
不在时间轴中移动。
一个粗略的未经测试的例子,使用Java中的Twitter4J打印从最新到过去的推文如下:
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());
}
}
,但它应该让你开始。
答案 2 :(得分:3)
通过粗略查看代码,您似乎永远不会更新sinceIDmap
中的值。您已注释掉以下内容:
//sinceIDmap(TickerId)=result.getSinceId
因此,对于每个关键字,since_id
永远不会从0
更新。
如果您遇到问题,可能需要检查GitHub上的Twitter4J SearchTweets
示例。
答案 3 :(得分:1)
since_id和max_id都是非常简单的参数,可以用来限制从API返回的内容。来自文档:
since_id - 返回ID大于(即更新)指定ID的结果。可以通过API访问的推文数量有限制。如果自since_id以来发生了推文限制,则since_id将被强制为可用的最旧ID。 max_id - 返回ID小于(即早于)或等于指定ID的结果。 因此,如果您有一个特定的推文ID,您可以使用这两个参数搜索较旧或较新的推文。
计数甚至更简单 - 它指定了您想要获得的最大推文数量,最多可达200个。
不幸的是,API不会完全回复您所需的内容 - 您无法在查询user_timeline时指定日期/时间 - 尽管您可以在使用搜索API时指定一个日期/时间。无论如何,如果您需要使用user_timeline,那么您需要轮询API,收集推文,确定它们是否与您想要的参数相匹配,然后相应地计算您的统计数据。