通过调用Twitter API抓取Twitter数据

Posted 江湖人称小白哥

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了通过调用Twitter API抓取Twitter数据相关的知识,希望对你有一定的参考价值。

国内研究weibo的人比较多,资料也相对较多,但是twitter的资料相对较少。今天简单说一下twitter api的使用。最近一小需求,采集含有指定关键词的twitter数据,瞬间想到写个爬虫来抓取,后来突然想到twitter应该有open api可用。使用了vpn翻墙之后简单的了解了twitter.com,决定直接使用 twitter api。由于twitter的open api现在也是基于oauth协议的,因此使用流程和国内一些社区比如说人人网,weibo的api的过程类似。

要想使用twitter api,首先要有twitter的账号,并且在twitter deveoper中创建应用,地址:https://apps.twitter.com/app/new
































上边怎么填就不说了,创建成功之后可以获得应用的信息。创建成功之后你会获得Consumer key和Consumer secret。将这两个数据保存下来。如下图:




为了方便用java操作,这里我们使用开源的twitter4j,最新版本为:twitter4j-4.0.2。(https://github.com/twitter/twitter4j)Twitter4J也就对Twitter 的API进行了java封装,这样的话我们就可以很方便的使用java才操作 twitter api。twitter4j-4.0.2.zip之后,我们可以看到说明文档和实例代码,当然也包括源代码。糟糕的是我觉得说明文档写的并不详细,建议直接看示例代码和源代码就好。


首先我们创建一个java项目(当然你也可以创建web应用)并导入相关jar,然后在项目路径下创建twitter4j.properties文件,里边填写刚才保存下的Consumer Key和Consumer Secret。

项目结构:



twitter4j.properties

oauth.consumerSecret=gLpOB2rbyVTVc6DgmL***HQJzTpqTDMU5nOlrfs2ksI7muWZmQ
oauth.accessToken=2926555458-DwB2WcX8eF***hxRLkRZ6xIkCNHVNwj43e5CBWb

然后和所有基于oauth协议的开发api一样,我们需要获取授权信息。代码如下:


import java.awt.Desktop;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Properties;

import twitter4j.Twitter;
import twitter4j.TwitterException;
import twitter4j.TwitterFactory;
import twitter4j.auth.AccessToken;
import twitter4j.auth.RequestToken;
/**
 * @ClassName: GetAccessToken
 * @Description:获取授权信息
 * @author God
 * @date 2014-12-12 上午11:19:53
 *
 */
public class GetAccessToken 
    public static void main(String[] args) 
    	String cPath="D:\\\\A_WorkSpace\\\\workspace14_CareerPredict\\\\twitter\\\\src\\\\twitter4j.properties";
        File file = new File(cPath);
        Properties prop = new Properties();
        InputStream is = null;
        OutputStream os = null;
        try 
            if (file.exists()) 
                is = new FileInputStream(file);
                prop.load(is);
            
            if (args.length < 2) 
                if (null == prop.getProperty("oauth.consumerKey")
                        && null == prop.getProperty("oauth.consumerSecret")) 
                    
                    System.out.println(
                            "Usage: java twitter4j.examples.oauth.GetAccessToken [consumer key] [consumer secret]");
                    System.exit(-1);
                
             else 
                prop.setProperty("oauth.consumerKey", args[0]);
                prop.setProperty("oauth.consumerSecret", args[1]);
                os = new FileOutputStream("twitter4j.properties");
                prop.store(os, "twitter4j.properties");
            
         catch (IOException ioe) 
            ioe.printStackTrace();
            System.exit(-1);
         finally 
            if (is != null) 
                try 
                    is.close();
                 catch (IOException ignore) 
                
            
            if (os != null) 
                try 
                    os.close();
                 catch (IOException ignore) 
                
            
        
        try 
            Twitter twitter = new TwitterFactory().getInstance();
            RequestToken requestToken = twitter.getOAuthRequestToken();
            System.out.println("Got access token.");
            System.out.println("Request token: " + requestToken.getToken());
            System.out.println("Request token secret: " + requestToken.getTokenSecret());
            AccessToken accessToken = null;

            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            while (null == accessToken) 
                System.out.println("Open the following URL and grant access to your account:");
                System.out.println(requestToken.getAuthorizationURL());
                try 
                	 //调用浏览器访问Twiiter的授权页面,帐号登录成功也就是授权成功后将会跳转回到申请的APP中的Redirect_URI地址,并携带了request_token  
                    Desktop.getDesktop().browse(new URI(requestToken.getAuthorizationURL()));
                 catch (UnsupportedOperationException ignore) 
                 catch (IOException ignore) 
                 catch (URISyntaxException e) 
                    throw new AssertionError(e);
                
              //输入浏览器跳转时携带的code参数(应该将Redirect_URI设置成本系统中的一个Servlet的地址,并且下面的代码放到Servlet中来处理授权信息)  
                System.out.print("Enter the PIN(if available) and hit enter after you granted access.[PIN]:");
                String pin = br.readLine();
                try 
                    if (pin.length() > 0) 
                        accessToken = twitter.getOAuthAccessToken(requestToken, pin);
                     else 
                        accessToken = twitter.getOAuthAccessToken(requestToken);
                    
                 catch (TwitterException te) 
                    if (401 == te.getStatusCode()) 
                        System.out.println("Unable to get the access token.");
                     else 
                        te.printStackTrace();
                    
                
            
            System.out.println("Got access token.");
            System.out.println("Access token: " + accessToken.getToken());
            System.out.println("Access token secret: " + accessToken.getTokenSecret());

            try 
                prop.setProperty("oauth.accessToken", accessToken.getToken());
                prop.setProperty("oauth.accessTokenSecret", accessToken.getTokenSecret());
                os = new FileOutputStream(file);
                prop.store(os, "twitter4j.properties");
                os.close();
             catch (IOException ioe) 
                ioe.printStackTrace();
                System.exit(-1);
             finally 
                if (os != null) 
                    try 
                        os.close();
                     catch (IOException ignore) 
                    
                
            
            System.out.println("Successfully stored access token to " + file.getAbsolutePath() + ".");
            System.exit(0);
         catch (TwitterException te) 
            te.printStackTrace();
            System.out.println("Failed to get accessToken: " + te.getMessage());
            System.exit(-1);
         catch (IOException ioe) 
            ioe.printStackTrace();
            System.out.println("Failed to read the system input.");
            System.exit(-1);
        
    

这里我们解释一下”输入PIN“这里到底是输入什么?很简单就是你在授权页面登陆成功之后,浏览器跳转时携带的code参数,如下图所示:



运行完上面的代码之后,我们的授权信息会被写入到twitter4j.properties文件中:

#twitter4j.properties
#Fri Dec 12 11:50:52 CST 2014
<pre name="code" class="html" style="color: rgb(54, 46, 43); font-size: 14px; line-height: 26px;">oauth.consumerSecret=gLpOB2rbyVTVc6DgmL***HQJzTpqTDMU5nOlrfs2ksI7muWZmQ
oauth.accessToken=2926555458-DwB2WcX8eF***hxRLkRZ6xIkCNHVNwj43e5CBWb
oauth.accessTokenSecret=vJsyhLZF3hKLFPUNJINMBI64UgCh***xzJz8p6oxZcS3Ioauth.consumerKey=***7E1l6GHWuMFTwcZ0tIGZhP

 下面我们通过调用api来获取包含指定关键词的twitter。(你可以参考实例代码SearchTweets.java)本人代码如下: 

import java.util.ArrayList;
import java.util.List;

import twitter4j.Query;
import twitter4j.Query.ResultType;
import twitter4j.QueryResult;
import twitter4j.Status;
import twitter4j.Twitter;
import twitter4j.TwitterException;
import twitter4j.TwitterFactory;

import com.twiter.info.domain.TwitterInfo;
import com.twiter.info.search.Search;
import com.twiter.info.utils.DateUtil;
import com.twiter.info.utils.ParserUtil;


public class SearchOnGetImpl implements Search
	private Twitter twitter = new TwitterFactory().getInstance();
	private QueryResult result;
	
	public SearchOnGetImpl() 
	

	@Override
	public <T> List<T> search(String key) 
		return search(key, 1000, null, null);
	

	@Override
	public <T> List<T> search(String key, int count, String sinceDate) 
		return search(key, count, sinceDate, null);
	

	@Override
	public <T> List<T> search(String key, int count, String sinceDate,
			String endDate) 
		List<TwitterInfo> infos=new ArrayList<>();
	
		Query query=new Query();
        try 
        	query.setResultType(ResultType.mixed);
        	query.setQuery(key);        	
            query.setCount(100);//设置每次获取数量
            if(sinceDate!=null)
            	query.setSince(sinceDate);
            
           if(endDate!=null)
        	   query.until(endDate);
           
            do 
                result = twitter.search(query);
                List<Status> tweets = result.getTweets();
                String num = result.getQuery();
                int level = result.getAccessLevel();
                infos.addAll(res2TwitterInfos(tweets));
                if(infos.size()>=count)break;
             while ((query = result.nextQuery()) != null);
         catch (TwitterException te) 
            te.printStackTrace();
        
       
		return (List<T>) infos;
	
	/**
	 * @Title: res2TwitterInfos
	 * @Description: 转换为目标实体类
	 * @param tweets
	 * @return List<TwitterInfo>
	 */
	public List<TwitterInfo> res2TwitterInfos(List<Status> tweets)
		TwitterInfo info=null;
		List<TwitterInfo> infos=new ArrayList<TwitterInfo>();
		for (Status tweet : tweets) 
			 info=new TwitterInfo();
			info.setId(String.valueOf(tweet.getId()));
			info.setContent(ParserUtil.E2C(tweet.getText()));
			info.setDate(DateUtil.date2StandardFormat(tweet.getCreatedAt()));
			info.setClient(ParserUtil.clean(tweet.getSource()));
            infos.add(info);
		
		return infos;
		
	

	@Override
	public <T> List<T> search(String key, int count) 
		
		return this.search(key, count, null, null);
	
	
	public static void main(String[] args) 
		new SearchOnGetImpl().search("fe",5000);
	


ok,到现在为止我们便可获取包含fe关键词的twitter数据。但是要注意,这种方式只能获取一周之内的twitter数据。要想不断的获取的话,只能采取另外的方案,通过调用Streaming apis不断的获取twitter,然后自己再过滤。可以参考PrintSampleStream.java实例代码。

demo下载地址:http://download.csdn.net/detail/dd864140130/9451385






以上是关于通过调用Twitter API抓取Twitter数据的主要内容,如果未能解决你的问题,请参考以下文章

使用 rvest 在 Twitter 中抓取用户视频

使用 Selenium Python 进行网页抓取 [Twitter + Instagram]

API爬虫--Twitter实战

Webpack 开发服务器中 Twitter api 调用的 CORS 问题

api = twitter.Api() AttributeError: 'module' 对象没有属性 'Api

如何使用 Postman 客户端调用 Twitter API