本篇将从实际例子出发,展示如何使用api爬取twitter的数据。
1. 创建APP进入https://apps.twitter.com/,创建自己的app。只有有了app才可以访问twitter的api并抓取数据。只需创建最简单的app即可,各种信息随意填写,并不需要进一步的认证,我们要的只是app的Consumer Key (API Key), Consumer Secret (API Secret), Access Token 和 Access Token Secret。鉴于单app的爬取次数限制,可以申请很多app来提高总次数。
2. 确定要使用的APItwitter提供多种类型的api,其中常用的有REST API和Streaming API。前者是常见的api类型,后者则可以跟踪监视一个用户或者一个话题。
REST API下面有很多的api,有价值爬取的有以下几个:
GET statuses/user_timeline:返回一个用户发的推文。注意twitter里回复也相当于发推文。
GET friends/ids:返回一个用户的followees。
GET followers/ids:返回一个用户的followers。
GET users/show:返回一个用户的信息。
3. 官方类库下载twitter的类库。说实话,api爬虫好不好写,全看类库提供的功能强不强。twitter提供了多种语言的类库,本文选择java类库。
4. 验证授权凡是访问api,都需要验证授权,也即:OAuth。一般流程为:以app的id和key,用户的用户名和密码为参数访问授权api,返回一个token(一个字符串),即算是授权完成,之后只需访问其他api时带上这个参数就行了。
当然,不同的网站授权过程各有不同。较为繁琐的比如人人网需要先跳转至回调网页,用户登陆后再返回token。twitter的授权过程也不简单(需要多次http请求),但是幸运的是类库中已经帮我们实现了此过程。
例,twitter的Auth1.1授权,其中需要设置的四个参数在app管理界面就能看到:
ConfigurationBuilder cb = new ConfigurationBuilder(); cb.setOAuthAccessToken(accessToken); cb.setOAuthAccessTokenSecret(accessTokenSecret); cb.setOAuthConsumerKey(consumerKey); cb.setOAuthConsumerSecret(consumerSecret); OAuthAuthorization auth = new OAuthAuthorization(cb.build()); Twitter twitter = new TwitterFactory().getInstance(auth);
twitter还提供一种无需用户授权(需app授权)的选择,,访问某些api时可用次数比Auth1.1授权的要多:
ConfigurationBuilder cb = new ConfigurationBuilder(); cb.setApplicationOnlyAuthEnabled(true); Twitter twitter = new TwitterFactory(cb.build()).getInstance(); twitter.setOAuthConsumer(consumerKey, consumerSecret); try { twitter.getOAuth2Token(); } catch (TwitterException e) { e.printStackTrace(); }
5. 调用API授权之后,我们就可以真正地开始爬数据了。
REST API
爬取用户follower,getFollowersIDs方法每次返回最多5000个follower,cursor用户标记从哪开始:
IDs iDs = twitter.getFollowersIDs(uid, cursor);
爬取用户推文:
ResponseList<Status> status = twitter.getUserTimeline(uid, page);
Streaming API
监视一个用户的所有行为,其中UserStreamListener太长了只截取了一部分:
TwitterStream twitterStream; twitterStream = new TwitterStreamFactory(cb.build()).getInstance(); twitterStream.addListener(listener); twitterStream.user(); private static final UserStreamListener listener = new UserStreamListener() { @Override public void onStatus(Status status) { System.out.println("onStatus @" + status.getUser().getScreenName() + " - " + status.getText() + status.getCreatedAt()); } @Override public void onDeletionNotice(StatusDeletionNotice statusDeletionNotice) { System.out.println("Got a status deletion notice id:" + statusDeletionNotice.getStatusId()); } @Override public void onDeletionNotice(long directMessageId, long userId) { System.out.println("Got a direct message deletion notice id:" + directMessageId); } @Override public void onTrackLimitationNotice(int numberOfLimitedStatuses) { System.out.println("Got a track limitation notice:" + numberOfLimitedStatuses); } @Override public void onScrubGeo(long userId, long upToStatusId) { System.out.println("Got scrub_geo event userId:" + userId + " upToStatusId:" + upToStatusId); } ...
6. 如何提速