通过调用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实例代码。

如果想要完整项目可联系我索取。



时间: 2024-09-29 05:38:50

通过调用Twitter API抓取Twitter数据的相关文章

Tweepy1——抓取Twitter数据

之前一直想用爬虫登陆并抓取twitter数据,试过scrapy,requests等包,都没成功,可能是我还不太熟悉的原因,不过 今天发现了一个新包tweepy,专门用于在Python中处理twitter API.先尝试一下教程的第一个例子,经过了自己的一点修改 代码如下: Tweepy抓取twitter数据 1 import re import tweepy auth = tweepy.OAuthHandler("xxxxx", "xxxxx") auth.set_

web scraper 抓取网页数据的几个常见问题

如果你想抓取数据,又懒得写代码了,可以试试 web scraper 抓取数据. 相关文章: 最简单的数据抓取教程,人人都用得上 web scraper 进阶教程,人人都用得上 如果你在使用 web scraper 抓取数据,很有可能碰到如下问题中的一个或者多个,而这些问题可能直接将你计划打乱,甚至让你放弃 web scraper . 下面列出几种你可能会碰到的问题,并说明解决方案. 1.有时候我们想选择某个链接,但是鼠标点击就出触发页面跳转,如何处理? 在我们选择页面元素的时候,勾选 "Enab

【iOS】正则表达式抓取网页数据制作小词典

应用程序不一定要自己去提供数据,有现成的数据学会去用才好. 网络很大,各种搜索引擎每天到处爬.本文通过正则表达式抓取网站的数据来做一个小词典. 一.正则表达式的使用 1. 确定匹配方案,即pattern 2. 用pattern实例化NSRegularExpression 3. 用匹配方法开始匹配. 匹配一次:可以使用firstMatch方法 匹配多次:可以用matchs方法 正则表达式对照表:(在网上找到了一个很不错的表,正则表达式各个语言通用) http://www.jb51.net/shou

iOS—网络实用技术OC篇&amp;网络爬虫-使用java语言抓取网络数据

网络爬虫-使用java语言抓取网络数据 前提:熟悉java语法(能看懂就行) 准备阶段:从网页中获取html代码 实战阶段:将对应的html代码使用java语言解析出来,最后保存到plist文件 上一片文章已经介绍我们可以使用两个方式来抓取网络数据实现网络爬虫,并且大致介绍了一下怎么使用正则表达式去实现数据的抓取 由于笔者曾经学过一段时间java和android相关的技术,今天就讲讲怎么使用java去抓取网络数据,关于Python有机会等笔者好好研究一下再来分享,但其实会一种就可以,除非你的需求

wireshark抓取本地数据包

windows系统中,本地向自身发送数据包没有经过真实的网络接口,而是通过环路(loopback interface)接口发送,所以使用基于只能从真实网络接口中抓数据的winpcap是无法抓取本地数据包,需要使用npcap,npcap是基于winpcap 4.1.3开发的,api兼容WinPcap,并且提供“npcap loopback adapter”用于抓取本地向自身发送的数据包. 使用方法: 1.下载安装WireShark,版本号必须是高于 1.12.8和 1.99.9,已安装就不用装了,

iOS开发——网络实用技术OC篇&amp;网络爬虫-使用java语言抓取网络数据

网络爬虫-使用java语言抓取网络数据 前提:熟悉java语法(能看懂就行) 准备阶段:从网页中获取html代码 实战阶段:将对应的html代码使用java语言解析出来,最后保存到plist文件 上一片文章已经介绍我们可以使用两个方式来抓取网络数据实现网络爬虫,并且大致介绍了一下怎么使用正则表达式去实现数据的抓取 由于笔者曾经学过一段时间java和android相关的技术,今天就讲讲怎么使用java去抓取网络数据,关于Python有机会等笔者好好研究一下再来分享,但其实会一种就可以,除非你的需求

抓取网页数据

项目说明:[抓取网页数据] 项目介绍:采集指定网页内容,通过模式匹配匹配到要采集的数据格式返回到数组中 项目步骤:1.创建匹配模式表2.请求网页连接3.过滤文本,并对数据去重处理4.显示结果 效果展示: 完整代码: import console; /* 项目说明:[抓取网页数据] 项目介绍: 采集指定网页内容,通过模式匹配匹配到要采集的数据格式返回到数组中 项目步骤: 1.创建匹配模式表 2.请求网页连接 3.过滤文本,并对数据去重处理 4.显示结果 */ //参考来源:http://bbs.a

Java语言实现通过Ajax抓取后台数据及图片

1.Java语言实现通过Ajax抓取后台数据及图片信息 1.1数据库设计 create table picture( pic_id number not null, pic_name varchar(200)not null, pic_url varchar2(200) not null, pic_descp varchar2(200) not null, pic_price varchar2(200) not null ) insert into picture values(1 ,'小米5s

Asp.net 使用正则和网络编程抓取网页数据(有用)

Asp.net 使用正则和网络编程抓取网页数据(有用) /// <summary> /// 抓取网页对应内容 /// </summary> /// <param name="strUrl">採集地址</param> /// <param name="Begin">開始字符</param> /// <param name="End">结束字符</param&g