如何使用Twitter4j获取无需用户身份验证的Twitter公共时间线?

7

我编写了一些代码,以允许用户使用Twitter4j登录其Twitter帐户并发送Tweet,可参考此教程

现在,我也可以使用该代码获取公共账户的推文。

ConfigurationBuilder cb = new ConfigurationBuilder();
cb.setHttpConnectionTimeout(10000)
.setHttpReadTimeout(10000)
.setOAuthConsumerKey(Config.TWITTER_CONSUMER_KEY)
.setOAuthConsumerSecret(Config.TWITTER_CONSUMER_SECRET)
.setOAuthAccessToken(Utils.getPrefsString(getActivity(),
    TwitterPrefsFragment.PREF_KEY_OAUTH_TOKEN, "")) // empty if not authentified
.setOAuthAccessTokenSecret(Utils.getPrefsString(getActivity(),
    TwitterPrefsFragment.PREF_KEY_OAUTH_SECRET, "")); // empty if not authentified
TwitterFactory tf = new TwitterFactory(cb.build());
Twitter twitter = tf.getInstance();

List<twitter4j.Status> statuses = twitter.getUserTimeline(SOME_PUBLIC_TWITTER_ACCOUNT, new Paging(1, 50));

但这仅在用户已经通过oauth获取到令牌和密钥并保存在首选项中时有效。

如何获取Twitter的公共时间轴而不需要访问令牌,即无需用户进行身份验证?

编辑

我重新阐述我的问题以使其更清晰:

我已经使用这里给出的代码对我的Twitter应用和用户进行了身份验证。

那么,如果用户没有登录,我怎样才能获取公共时间轴呢?在这种情况下,没有OAUTH_TOKENOAUTH_SECRET,所以上面显示的请求无法工作,因为一个空字符串被设置到了ConfigurationBuilder.setOAuthAccessTokenConfigurationBuilder.setOAuthAccessTokenSecret中。

那么,如果存在的话,获取没有OAUTH_TOKENOAUTH_SECRET的公共时间轴的请求是什么?


请使用此链接 https://github.com/robhinds/AndroidTwitterDemo.git。 - Dixit Patel
你能指引我找到有用的代码吗?我找不到它。谢谢。 - jul
4个回答

8

在你的情况下,你应该使用仅应用认证

要使用Twitter4J进行此操作,请尝试以下代码

    ConfigurationBuilder cb = new ConfigurationBuilder();
    cb
    .setOAuthConsumerKey(<YOUR_CONSUMER_KEY>)
    .setOAuthConsumerSecret(<YOUR_CONSUMER_SECRET>)
    .setApplicationOnlyAuthEnabled(true); // IMPORTANT: set T4J to use App-only auth
    TwitterFactory tf = new TwitterFactory(cb.build());
    Twitter twitter = tf.getInstance();

    OAuth2Token token = twitter.getOAuth2Token();
    if (token != null) {
        System.out.println("Token Type  : " + token.getTokenType());
        System.out.println("Access Token: " + token.getAccessToken());
    }
    ResponseList<Status> list = twitter.getUserTimeline(783214); // Load @twitter's timeline without user login.

上述示例代码的关键点:

  • 调用setApplicationOnlyAuthEnabled(true)以启用仅应用程序认证。
  • 使用getOAuth2Token()而不是getOAuthAccessToken()来获取访问令牌。

在Twitter4j最新的稳定版本(3.0.3)中,“setApplicationOnlyAuthEnabled(boolean)”方法对于“ConfigurationBuilder”类型是未定义的。看起来它只在尚未稳定的3.0.4版本中可用。 - jul
很抱歉,如果你想要实现这个目标,就不能使用Twitter4J,因为似乎只有使用3.0.4版本才能使App-only身份验证正常工作。 - TactMayers
我将使用3.0.4 dev版本,尽管我刚刚发现你也可以使用这里提供的解决方案。 - jul

7
这是完全可以实现的,我已经尝试过了。如果你只是关于Access Token和Access Token secret为空的疑问,那么你应该尝试使用应用页面提供的Access Token。所谓应用页面,指的是你注册Twitter应用的链接。
如果你访问dev.twitter.com并进入你的应用设置,你会看到一个Consumer Key、Consumer Secret、Access Token和Access Token Secret。利用这些内容,按照我的下面的代码进行操作,应该就可以实现了。
ConfigurationBuilder cb = new ConfigurationBuilder();
        cb.setDebugEnabled(true)
                .setOAuthConsumerKey("B*************Q")
                .setOAuthConsumerSecret(
                        "l*************o")
                .setOAuthAccessToken(
                        "1*************s")
                .setOAuthAccessTokenSecret(
                        "s*************s");
        TwitterFactory tf = new TwitterFactory(cb.build());
        twitter = tf.getInstance();
        try {
            List<Status> statuses;
            String user;
            user = "Replace this with the screen name whose feeds you want to fetch";
            statuses = twitter.getUserTimeline(user);
            Log.i("Status Count", statuses.size() + " Feeds");

        } catch (TwitterException te) {
            te.printStackTrace();
        }

我使用的是 Twitter 4j 3.03.jar。

当我尝试执行你的代码时,出现了“未找到身份验证挑战”的异常。你能帮忙吗? - philip

2
我该如何使用Twitter4j获取公共时间轴而无需访问令牌和密钥?
哦,这很简单。你不能。
Twitter是一家数据公司。该公司99%的财产(我指公司拥有的)是数据。将此数据免费提供给其他人/企业是不划算的。
如果您想要的东西是可能的,那么备份整个Twitter数据库就会变得容易。
这就是为什么他们让您为每个想要使用API的应用程序注册帐户,并将每个帐户限制为每个时间段内的某个API调用数量。当然,他们还希望防止其网络受到垃圾邮件等影响。

我真不敢相信没有一种方法可以在没有认证的情况下获取公共时间轴。我可以在未登录的情况下阅读https://twitter.com/google。我只需解析页面并获取数据即可。我并不是说没有注册应用程序。实际上,我有一个带有消费者密钥和密钥的应用程序,但我只是不想要用户必须输入用户名/密码。 - jul
@jul 听起来你可能混淆了你的应用程序针对 API 进行身份验证与用户进行身份验证的概念。 - xdumaine
@jul 是的。感谢您的编辑。当然,您可以解析页面,但如果您这样做得太多,您将遇到其他预防措施,例如超时或捕获。 - Kenyakorn Ketsombut

1
如果您想在不需要用户登录的情况下获取推文,可以使用应用程序认证,因为用户不需要登录。
通过应用程序认证,Twitter提供了应用程序代表自身(而不是代表特定用户)发出经过身份验证的请求的能力。

应用程序认证流程遵循以下步骤:

应用程序将其使用者密钥和密钥加密成一组特殊编码的凭据。

应用程序向POST oauth2/token端点发出请求,以交换这些凭据以获得承载令牌。

访问REST API时,应用程序使用承载令牌进行身份验证。

注意:因为twitter4j最近添加了此功能,所以您应该使用最新快照库。
以下是一个使用它的示例:
private ConfigurationBuilder    builder;
private Twitter                 twitter;
private TwitterFactory          factory;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.init_act_layout);

// setup
builder = new ConfigurationBuilder();
builder.setUseSSL(true);
builder.setApplicationOnlyAuthEnabled(true);
builder.setOAuthConsumerKey(Constants.CONSUMER_KEY);
builder.setOAuthConsumerSecret(Constants.CONSUMER_SECRET);

Configuration configuration = builder.build();
factory = new TwitterFactory(configuration);
((MyApp) (MyApp.getApp())).setTFactory(factory);

if (isNeededTwitterAuth()) {
    twitter = factory.getInstance();
        //Get the token async and save it
}

    //Search tweets

}

/*
 * Checks if twitter access token is already saved in preferences
 * 
 * @return true if auth needed
 */
private boolean isNeededTwitterAuth() {
    SharedPreferences settings = getSharedPreferences(Constants.TWITTER_PREFERENCES, Context.MODE_PRIVATE);
    String twitterAccesToken = settings.getString("bearerAccessToken", "");
    String twitterTokenType = settings.getString("bearerTokenType", "");
    return ((twitterAccesToken.length() == 0) && (twitterTokenType.length() == 0));
}

}

为获取bearer token,请在主UI线程之外处理,以避免网络异常,例如使用AsyncTask:
@Override
    protected OAuth2Token doInBackground(Void... params) {
        OAuth2Token bearerToken = null;

        try {
            bearerToken = twitter.getOAuth2Token();
        } catch (TwitterException e) {
            e.printStackTrace();
        }
        return bearerToken;
    }

当您获得访问令牌时,请保存它:
SharedPreferences appSettings = getSharedPreferences(Constants.TWITTER_PREFERENCES, MODE_PRIVATE);
            SharedPreferences.Editor prefEditor = appSettings.edit();
            prefEditor.putString("bearerAccessToken", result.getAccessToken());
            prefEditor.putString("bearerTokenType", result.getTokenType());
            prefEditor.commit();

使用bearer令牌的方法如下:

OAuth2Token bearerToken = new OAuth2Token(bearerTokenType, bearerAccesstoken);

        twitter.setOAuth2Token(bearerToken);

搜索推文(始终不在主线程中):

@Override
 protected QueryResult doInBackground(Void... params) {

 twitter.setOAuth2Token(bearerToken);
 Query query = new Query();
 [...]
 result = twitter.search(query);

博客中有一份完整的解释(西班牙语...)

还有一个完整的示例在twitter4j github

希望这有所帮助!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接