使用Ruby来编写访问Twitter的命令行应用程序的教程
简介
Twitter现已成为社交网络中的佼佼者。Twitter只允许用户发布不多于140个字符的内容,谁能够想到,这个过去毫不起眼的小网站如今却价值十多亿美元,拥有数百万用户,Twitter平台上已构建了大量的应用程序,并且不断有新的开发人员准备投入这一浪潮中。
本文并不打算介绍Twitter(事实上,也没有这个必要)。相反,本文将介绍如何访问Twitter平台来构建出色的命令行应用程序。Twitter支持各种编程语言,包括C++、Java?、Perl、Ruby、PHP和Python。对于每种语言,都有大量的库或包可以帮助您完成大量工作。
本文将介绍如何使用Ruby来访问Twitter。您应该对Ruby有所了解,但是即使不具备这方面的知识,也很容易快速掌握Ruby。
安装Twittergem
一些gem可用于从Ruby访问Twitter(参见参考资料,以获得有关的更多信息)。对于本文,我选择使用twitter,这是由JohnNunemaker编写的Ruby包装器。安装gem非常简单:
bash$geminstalltwitter
该命令用于在您的机器上安装Twitter客户端。如果您有一个定制的gem安装文件夹,那么首先需要从脚本中调用rubygems,然后调用twitter。下面展示了具体过程:
require'rubygems' require'twitter'
第一个Twitter脚本
现在,您已经准备好构建第一个应用程序,该应用程序用于检测您所关注的人的位置。首先创建一个脚本,它会获取其他人的姓名,并告诉您他们的当前位置。清单1显示了相关代码。
清单1.跟踪用户位置
require'rubygems' require'twitter' deftrack ARGV.eachdo|name| putsname+"=>"+Twitter.user("#{name}").location end end
track
这段代码执行了哪些操作?如果您刚刚接触Ruby,则需要向您解释一下,ARGV是一个数组,它提供脚本对命令行参数的访问。Twitter.userAPI返回有关您对其位置感兴趣的人的信息。调用以下脚本可以获得LadyGaga、AshtonKutcher和OprahWinfrey的当前位置:
bash$./location_tracker.rbladygagaapluskOprah ladygaga=>NewYork,NY aplusk=>LosAngeles,California Oprah=>Chicago,IL
在Twitter上实现用户搜索并了解认证情况
现在,让我们搜索Twitter上的一些现有用户。如果可以猜出用户的TwitterID,那么可以使用以下命令行:
require'rubygems' require'twitter' puts"Userexists"ifTwitter.user?(ARGV[0])
不过,一般情况下无法猜出用户的ID。因此,需要提供搜索用户名的功能。这需要用以下代码实现,该代码将搜索名称与Arpan匹配的所有用户:
require'rubygems' require'twitter' names=Twitter.user_search("Arpan")
但是这段代码未能正常工作。清单2显示的错误日志告诉您问题出现在哪里。
清单2.无法执行用户搜索
Twitter::Unauthorized:GEThttps://api.twitter.com/1/users/search.json?q=Arpan% 20Sen:401:Couldnotauthenticateyou. fromD:/Ruby/lib/ruby/gems/1.8/gems/twitter-1.6.2/lib/faraday/response/r aise_http_4xx.rb:12:in`on_complete' fromD:/Ruby/lib/ruby/gems/1.8/gems/faraday-0.7.4/lib/faraday/response.r b:9:in`call' fromD:/Ruby/lib/ruby/gems/1.8/gems/faraday-0.7.4/lib/faraday/response.r b:62:in`on_complete'
从这段代码可以看出,您首先需要通过Twitter的认证,然后才能执行其他操作。这里的认证不是要求您进行登录并输入密码;而是指对您的脚本(在Twitter中称为应用程序)进行认证。请牢记这一差异,然后访问http://dev.twitter.com/apps,并使用平常的帐号和密码进行登录。Twitter会要求您提供应用程序名称、描述和应用程序的占位符(placeholder)网站。提供这些信息后,还必须提供以下四项内容实现脚本认证:
- 用户密匙(Consumerkey)
- 用户秘密令牌(Consumersecrettoken)
- 用户OAuth密匙
- 用户OAuth秘密令牌
现在,在Ruby代码内部,您需要使用这些选项填充Twitter.configure对象。清单3显示了相关代码。
清单3.配置脚本进行认证
Twitter.configuredo|config| config.consumer_key="mT4atgBEKvNrrpV8GQKYnQ" config.consumer_secret="BiQX47FXa938sySCLMxQCTHiTHjuTTRDT3v6HJD6s" config.oauth_token="22652054-Yj6O38BSwhwTx9jnsPafhSzGhXvcvNQ" config.oauth_token_secret="o9JuQuGxEVF3QDzMGPUQS0gmZNRECFGq12jKs" end
注意,清单3中的条目是虚构的:您需要在脚本中填充自己的内容。顺利完成认证后,就可以搜索名为Arpan的人(参见下面的清单4)。
清单4.在Twitter上搜索用户
require'rubygems' require'Twitter' Twitter.configuredo|config| config.consumer_key="mT4atgBEKvNrrpV8GQKYnQ" config.consumer_secret="BiQX47FXa938sySCLMxQCTHiTHjuTTRDT3v6HJD6s" config.oauth_token="22652054-Yj6O38BSwhwTx9jnsPafhSzGhXvcvNQ" config.oauth_token_secret="o9JuQuGxEVF3QDzMGPUQS0gmZNRECFGq12jKs" end users=Twitter.user_search(ARGV[0]) users.eachdo|user| print"\n"+user.name+"=>" printuser.locationunlessuser.location.nil? end
现在,将脚本保存为search_for.rb,并在命令行中以./search_for.rbArpan形式调用脚本后,您将获得清单5所示的用户名称。
清单5.清单4的代码输出
ArpanJhaveri=>NewYork ArpanBoddishv=> ArpanPeter=>Bangalore,India ArpanPodduturi=>NYC ArpanKumarDe=>IITKharagpur ArpanShrestha=>Kathmandu,Nepal ArpanDivanjee=>Mumbai,India ArpanBajaj=>BayArea,CA
您可能期望获得更多结果。Arpan这个名字(印度姓名)并不少见,那么为什么搜索结果这么少?最后您会发现,user_search使用了一个可选参数(一个Rubyhash表),您也可以指定可产生更多结果的选项。因此,可以稍微修改一下清单5的代码,传递可选的hash参数(#)并预填充它的值。例如,如果希望在一个页面中填充15项结果,那么可以使用清单6中的代码。
清单6.在每个页面显示15项搜索条目
require'rubygems' require'twitter' #..authenticationcodehere users=Twitter.user_search(ARGV[0],{:per_page=>15}) #...sameasListing10
是不是可以在每个页面中显示100项条目?不行,Twitter.user_search允许每页显示的最多条目为20。清单7显示了如何在每个页面中显示20个条目。
清单7.每个页面显示20个条目
#...usualauthenticationstuff pagecount=0 whilepagecount<10 u=Twitter.user_search("#{ARGV[0]}",{:per_page=>20,:page=>pagecount}) u.eachdo|user| print"\n"+user.name+"=>"+user.screen_name print"=>"+user.locationunlessuser.location.nil? endunlessu.size<20 pagecount+=1 end
现在看上去好多了。您现在可以根据偏好名和用户的屏幕名称搜索用户,下面让我们做一些更有趣的事情。让我们搜索居住在纽约的、喜欢Ruby的名为Nick的人。您可以从user_search获得姓名和位置,但是如何处理喜欢Ruby的搜索要求?这引入了下一个需要学习的内容:创建定制搜索客户端。
使用Twitter::Search类
使用Twitter::Search类创建定制搜索客户端。清单8显示了相关代码。
清单8.学习使用Twitter::Search类
#...userauthentication pagecount=0 whilepagecount<10 u=Twitter.user_search("#{ARGV[0]}",{:per_page=>20,:page=>pagecount}) u.eachdo|w| ifw.location=="NewYork" results=Twitter::Search.new.from(w.screen_name).containing("ruby").fetch putsw.screen_nameifresults.size>10 end endunlessu.size<20 pagecount+=1 end
这里发生了什么呢?代码首先使用Twitter::Search.new创建了一个搜索客户端。接下来,要求搜索客户端从包含ruby的相应用户那里获取所有tweet。最后,代码返回一组结果,如果在tweet中提到Ruby的次数超过十次,则将此人定义为喜欢Ruby的人。
让我们尝试为hash标记#ruby获取一组tweet。下面是具体实现:
#...userauthenticationcode results=search.hashtag("ruby").fetch results.eachdo|r| putsr.text+"from"+r.from_user end
不过,还可以实现更多内容。对于ruby之类的hash标记,您希望获得数百个条目,不是吗?对于这种情况,使用搜索客户端也会带来便利,因为您可以从搜索客户端轻松地检索下一个页面。清单9的代码显示了有关Ruby的十页tweet。
清单9.显示多个页面
更多搜索选项
搜索客户端可以让您实现更出色的功能,比如使用特定语言或来自某个地方(比如德国)的tweet。您甚至可以搜索提到特定用户的tweet,或搜索匹配特定条件的tweet。例如,搜索所有提到Ruby但没有提到Rails的tweet?尝试下面的代码:
search.containing("ruby").not_containing("rails").fetch
当然,您可以像下面这样进行串联:
search.containing("ruby").not_containing("rails").mentioning("username").from("place-id")
搜索短语非常直观。例如,输入以下代码:
search.phrase("rubyonrails").fetch
现在,您已经掌握了入门要领!
速度限制
关于Twitter,您需要了解一件重要的事情,即速度限制,Twitter非常重视这个问题。速度限制意味着Twitter只允许您的脚本每个小时执行有限次数的查询。您可能已经发现,对于某些应用程序,您不需要进行显式的认证,但是对于另外一些应用程序,认证则是必须的。对于不包含OAuth标记的应用程序,当前的最大限制是每小时执行150个调用;对于带有该标记的应用程序,允许每小时执行350个调用。有关Twitter速率限制的最新信息,请查看参考资源。要了解您的脚本认证的当前限制,请添加以下代码:
putsTwitter.rate_limit_status
下面是输出结果:
<#Hashie::Mashhourly_limit=350remaining_hits=350reset_time="SatAug1321:48: 59+00002011"reset_time_in_seconds=1313272139>
如果您希望获得更具体的结果,请用代码查看下面的内容:
Twitter.rate_limit.status.remaining_hits
下面的输出禁用了认证。注意,您已经用完了可用限制的50%:
<#Hashie::Mashhourly_limit=150remaining_hits=77reset_time="SatAug1321:13:5 0+00002011"reset_time_in_seconds=1313270030>
更新Twitter的状态,重新发布tweet和其他内容
搜索功能暂时告一段落。现在需要使用脚本更新tweet的状态。只需一行代码即可(当然,您需要在脚本中包含认证代码):
#...authenticationcode Twitter.update(ARGV[0])
将代码保存为update.rb,并以rubyupdate.rb"HelloWorldfromRubyScript"的形式从命令行调用它。现在,您的Twitter页面已经实现了更新!对话功能是Twitter的一个自然扩展,向另一个用户发送消息非常简单:
#...authenticationcode Twitter.direct_message_create("username","Hi")
您可以选择使用用户的屏幕名或数字ID发送消息。Twitter的另一个有趣特性是可以快速查看最近发送的和最近接收到的20条消息:
#...authenticationcode Twitter.direct_messages_sent.eachdo|s| puts"Sentto:"+s.recipient_screen_name puts"Text:"+s.text end
我们有时候需要强调某些tweet的重要性,一个好方法就是重新发布tweet。下面显示了重新发布的最近20个tweet:
#...authenticationcode Twitter.retweets_of_me.eachdo|rt| printrt.text puts"retweetcount="+rt.retweet_count.to_s end
当然,如果能知道是谁在重新发布tweet就更好了,但是无法从retweets_of_meAPI直接获取该信息。相反,您需要使用retweeters_ofAPI。注意,每个tweet都有一个唯一的ID,而retweeters_of需要获得这一ID。清单10展示了相关代码:
清单10.谁在向我重新发布tweet
#...authenticationcode Twitter.retweets_of_me.eachdo|rt| printrt.text print"retweetedby" Twitter.retweeters_of(rt.id).eachdo|user| putsuser.screen_name end end
用Twitter实现有趣的功能
您可以利用自己的脚本做许多有趣的事情。例如,假如您很关心当前Twitter中正在发生的事情,那么您可以获取前十个趋势:
Twitter.trends.eachdo|trend| putstrend.name end
twitter.com只能报告前十个趋势。参考参考资源,获得有关的更多信息。通常,您可能只关心所在地的趋势。只需要提供所在地的where-on-earthID(WOEID),Twitter就可以提供这些信息。下面我展示了如何获得印度的当前趋势:
Twitter.local_trends(12586534).eachdo|trend| putstrend#local_trendsreturnsString end
获得Twitter推荐的用户也很容易。首先查看以下脚本:
Twitter.suggestions("technology").users.eachdo|user| putsuser.screen_name end
我对这段代码的输出进行了仔细检查。前十个结果意味着这段代码可以正常工作。Twitter提供了不同的用户感兴趣的类别,通过调用Twitter.suggestions(只需将Twitter.suggestions放在脚本里)便可获得此信息。每个类别都有一个简短名称,在Twitter中称为slug,您需要将其传递给Twitter.suggestions,然后便可获得Twitter推荐的用户。清单11展示了相关输出。
清单11.技术类别中推荐的前几名用户
gruber
dannysullivan
AlecJRoss
timoreilly
Padmasree
tedtalks
OpenGov
twitter
BBCClick
woot
anildash
laughingsquid
digiphile
jennydeluxe
biz
ForbesTech
chadfowler
leolaporte
本文最后将介绍如何找到SachinTendulkar(最棒的板球队员)的最受欢迎的粉丝。首先,Sachin的ID是sachin_rt(在相关主题上,您可以使用Twitter.user("sachin_rt").follower_count查看其粉丝的数量,并使用Twitter.user("sachin_rt").verified确认他的状态)。
现在,使用Twitter.follower_ids("sachin_rt")获得Sachin粉丝的数量。默认情况下,您将获得5000名用户,这足够支持您完成下面的工作。确保您已经阅读Twitter文档并参考了Twitter的APIresourcesforfriendsandfollowers,了解如何获得完整的粉丝列表。下面是一个代码示例:
#...authenticateyourself putsTwitter.follower_ids("sachin_rt").ids.size
最后,根据follower_count对这5000名用户中的某些用户进行排序:
#...authenticateyourself putsTwitter.follower_ids("sachin_rt").ids[0..49].sort!{|a,b|\ Twitter.user(a).followers_count<=>\ Twitter.user(b).followers_count}.reverse.first.name
在sort之后,"!"表示排序对所调用的内容修改了数组(并且没有返回新的数组),花括号({})中的代码是比较功能。这解释了使用Ruby的另一个原因:能够在一行代码中实现20行C++代码完成的工作。
结束语
为Twitter编写命令行脚本非常有趣,并且可以使您洞悉Twitter尚未提供的功能。此外,无论是搜索符合您的条件的特定用户(从本地技术人员到领域中的主题专家),还是搜索令人兴奋的新tweet,都可以很方便地通过命令行来实现。在结束本文之前,我需要给出最后两条忠告:首先,Twitter非常在意每小时的速率限制,因此最好将搜索结果缓存到您的代码中。其次,随时关注Twitter的RESTAPI资源,其中列出了您的Twitter客户端的所有API。最重要的是,尽情享受Twitter的乐趣!