How to search for tweets using twitter API 1.1 and

2019-03-21 02:42发布

Twitter API has been changed from 1.0 to 1.1. Now for any type of query it has to be authorized. I am using java for fetching tweets. Can anyone give me some java example of tweet fetching using OAuth authentication.

Update

Using twitter4j api it is possible. http://twitter4j.org/en/. An example is given below

Twitter twitter = new TwitterFactory().getInstance();

    AccessToken accessToken = new AccessToken("Your-Access-Token", "Your-Access-Token-Secret");
    twitter.setOAuthConsumer("Consumer-Key", "Consumer-Key-Secret");
    twitter.setOAuthAccessToken(accessToken);

    try {
        Query query = new Query("#IPL");
        QueryResult result;
        result = twitter.search(query);
        List<Status> tweets = result.getTweets();
        for (Status tweet : tweets) {
            System.out.println("@" + tweet.getUser().getScreenName() + " - " + tweet.getText());
        }
    }
    catch (TwitterException te) {
        te.printStackTrace();
        System.out.println("Failed to search tweets: " + te.getMessage());
        System.exit(-1);
    }

Problems here

This example works independently when I ran as a Java class. But when I add this code in a JSP for testing in webapp it does not work. It shows me following exception

    SEVERE: Servlet.service() for servlet [jsp] in context with path [/mypub] threw exception [java.lang.IllegalStateException: consumer key/secret pair already set.] with root cause
    java.lang.IllegalStateException: consumer key/secret pair already set.
        at twitter4j.TwitterBaseImpl.setOAuthConsumer(TwitterBaseImpl.java:264)
        at com.me.framework.tag.core.TweetFetch.doTag(TweetFetch.java:50)
        at org.apache.jsp.template.test_jsp._jspx_meth_wf_002dcore_005ftweetFetch_005f0(test_jsp.java:100)
        at org.apache.jsp.template.test_jsp._jspService(test_jsp.java:74)
        at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)

3条回答
看我几分像从前
2楼-- · 2019-03-21 03:18

I used this tutorial to search for tweets using twitter api 1.1 with OAuth Authentication

I have modified the code for my usability and it does not use twitter4j, which is good at the moment because OAuth search is not available in the RC build (I read it somewhere unable to find the location at the moment)

Also added getting twitter timeline

Code is in Groovy

TweetsHelper tweetsHelper = new TweetsHelper()
def bearerToken=tweetsHelper.requestBearerToken(TWITTER_AUTH_URL)
List<TweetsInfo> tweets=tweetsHelper.fetchTimelineTweet(bearerToken)

    private final def TWITTER_HOST = "api.twitter.com"
private final def TWITTER_AUTH_URL = "https://api.twitter.com/oauth2/token"
private final def TWITTER_URL = "https://api.twitter.com/1.1/statuses/user_timeline.json?screen_name=INFAsupport&count=200" 
private HttpsURLConnection getHTTPSConnection(String method,String endpointUrl){
    HttpsURLConnection connection = null        
    URL url = new URL(endpointUrl)
    connection = (HttpsURLConnection) url.openConnection()
    connection.setDoOutput(true)
    connection.setDoInput(true)
    connection.setRequestMethod(method)
    connection.setRequestProperty("Host", TWITTER_HOST)
    connection.setRequestProperty("User-Agent", TWITTER_HANDLE)
    connection.setUseCaches(false)
    return connection       
}

//Fetch Bearertoken for getting tweets
public String requestBearerToken(String endPointUrl) throws IOException {

    String encodedCredentials = encodeKeys()
    HttpsURLConnection connection = null
    try {
        connection = getHTTPSConnection("POST",endPointUrl)
        connection.setRequestProperty("Authorization", "Basic " + encodedCredentials)
        connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8")
        connection.setRequestProperty("Content-Length", "29")
        connection.setUseCaches(false)
    }
    catch (MalformedURLException e) {
        throw new IOException("Invalid endpoint URL specified.", e)
    }
    finally {
        if (connection != null) {
            connection.disconnect()
        }
    }       

    writeRequest(connection, "grant_type=client_credentials")

    JsonSlurper js=new JsonSlurper()
    def result=js.parseText(readResponse(connection))
    String tokenType = result?.token_type
    String token = result?.access_token

    return ((tokenType.equals("bearer")) && (token != null)) ? token : ""

}

//Search tweets
public List<TweetsInfo> fetchQueriedTweets(def bearerToken) throws IOException {
    HttpsURLConnection connection = null
    def dataCleanser = new DataCleanser()
    try {
        connection = getHTTPSConnection("GET",TWITTER_URL)
        connection.setRequestProperty("Authorization", "Bearer " + bearerToken)
    }
    catch (MalformedURLException e) {
        throw new IOException("Invalid endpoint URL specified.", e)
    }
    finally {
        if (connection != null) {
            connection.disconnect()
        }
    }

    List<TweetsInfo> tweets= new ArrayList<TweetsInfo>()
    try{
        JSONObject obj = (JSONObject)JSONValue.parse(readResponse(connection))
        JSONArray objArray = (JSONArray)obj.get(TWEET_STATUSES)

        if (objArray != null) {
            for(int i=0;i<objArray.length();i++){
                String text = dataCleanser.escapeQuotes(((JSONObject)objArray.get(i)).get(TWEET_TEXT).toString())
                String createdAt = DateUtils.convertToUTC(parseTweetDate(((JSONObject)objArray.get(i)).get(TWEET_CREATED_AT).toString()))
                String fromUser = ((JSONObject)objArray.get(i)).get(TWEET_USER).get(TWEET_NAME).toString()
                String expandedURL = ((JSONObject)objArray.get(i)).get(TWEET_ENTITIES).get(TWEET_URLS).get(0).get(TWEET_EXPANDED_URL).toString()
                TweetsInfo tweet=new TweetsInfo(text,fromUser,expandedURL,createdAt)
                tweets.push(tweet)                  
            }   
        }
    }
    catch(Exception e){
        log.info "Exception in TweetsHelper $e"
    }       
    return tweets
}

//Fetch Twitter timeline
public List<TweetsInfo> fetchTimelineTweet(def bearerToken) throws IOException {
    HttpsURLConnection connection = null
    List<TweetsInfo> tweets= new ArrayList<TweetsInfo>()
    def dataCleanser = new DataCleanser()
    try {
        connection = getHTTPSConnection("GET",TWITTER_URL)      
        connection.setRequestProperty("Authorization", "Bearer " + bearerToken)
    }
    catch (MalformedURLException e) {
        throw new IOException("Invalid endpoint URL specified.", e)
    }
    finally {
        if (connection != null) {
            connection.disconnect()
        }
    }

    JsonSlurper js=new JsonSlurper()
    try{
        def result=js.parseText(readResponse(connection))
        result?.each{tweet->            
            String text = tweet?.text
            String createdAt = DateUtils.convertToUTC(parseTweetDate(tweet?.created_at))
            String fromUser = tweet?.user?.name
            String expandedURL = tweet?.entities?.urls[0]?.expanded_url
            if(validTweetForAWeek(createdAt)){
                TweetsInfo tweetinfo=new TweetsInfo(text,fromUser,expandedURL,createdAt)
                tweets.push(tweetinfo)
            }
        }
    }
    catch(Exception e){
        log.info "Exception in TweetsHelper $e"
    }
    return tweets       
}

TweetsInfo is a Pojo class with String text, String fromUser, String expandedURL, String createdAt (this was my requirement)

Hope this helps :)

查看更多
劫难
3楼-- · 2019-03-21 03:37

You can use the codebird js library for tweet search. All you need is to create an app on Twitter and note down the following:

  1. Consumer Key
  2. Consumer Secret Key
  3. Access Token
  4. Access Token Secret

Download codebird js Library from the GitHub repository here:

Usage:

var cb = new Codebird;
cb.setConsumerKey('YOURKEY', 'YOURSECRET');
cb.setToken('YOURTOKEN', 'YOURTOKENSECRET');

cb.__call(
    'oauth2_token',
    {},
    function (reply) {
        var bearer_token = reply.access_token;
    }
);

cb.__call(
    'search_tweets',
    {
        q : "your query which you want to search",
        from : twitter_user
     },
     function (data) 
     {
         console.log(data);
     },
     true // this parameter required
);
查看更多
仙女界的扛把子
4楼-- · 2019-03-21 03:41

The problem is that you are setting the consumer secret and token multiple times, as indicated by the exception:

java.lang.IllegalStateException: consumer key/secret pair already set.

It's happening because TwitterFactory.getInstance() is returning a singleton of Twitter, this is then having setOAuthConsumer and setOAuthAccessToken invoked on it each time a request is made to your Servlet.

You need to ensure you only configure your Twitter instance once and not each time a request is made.

One way of achieving this is by asking the TwitterFactory to give you an authenticated instance of Twitter by using TwitterFactory.getInstance(AccessToken):

final AccessToken accessToken = new AccessToken("Your-Access-Token", "Your-Access-Token-Secret");
final Twitter twitter = TwitterFactory.getInstance(token);
...

An added benefit of this factory method is that it may return a cached, authenticated, instance of Twitter for you.

查看更多
登录 后发表回答