通过调用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数据的主要内容,如果未能解决你的问题,请参考以下文章
使用 Selenium Python 进行网页抓取 [Twitter + Instagram]
Webpack 开发服务器中 Twitter api 调用的 CORS 问题