Twitter以及一些API
盡管早期的網(wǎng)絡(luò)涉及的是人-機器的交互,但現(xiàn)在的網(wǎng)絡(luò)已涉及機器-機器之間的交互,這種交互是使用web服務(wù)來支持的。大部分受歡迎的網(wǎng)站都有這樣的服務(wù)存在——從各種各樣的Google服務(wù)到LinkedIn、Facebook和Twitter等。通過web服務(wù)創(chuàng)建的API,外部的應(yīng)用可以查詢或是操縱網(wǎng)站上的內(nèi)容。
web服務(wù)可以使用多種方式來實現(xiàn)。目前最流行的做法之一是表述性狀態(tài)轉(zhuǎn)移(Representational State Transfe, REST)。REST的一種實現(xiàn)是通過為人熟知的HTTP協(xié)議,允許HTTP作為RESTful架構(gòu)的媒介存在(使用諸如GET、PUT、POST、DELETE一類的標準HTTP操作)。Twitter的API是作為這一媒介之上的一個抽象來進行開發(fā)的。在這一做法中,沒有涉及REST、HTTP或是XML或JSON一類的數(shù)據(jù)格式的知識,而是代之以清晰地整合到了Ruby語言中的基于對象的接口。
Ruby和Twitter的一個快速展示
讓我們來探討一下如何在Ruby中使用Twitter API。首先,我們需要獲取所需的資源,如果你像我一樣在用Ubuntu Linux®的話,就使用apt框架。
若要獲取最新的完整的Ruby分發(fā)版本(大約13MB的下載量),使用這一命令行:
$ sudo apt-get install ruby1.9.1-full
接著使用gem實用程序來抓取Twitter gem:
$ sudo gem install twitter
現(xiàn)在你已經(jīng)有了這一步驟所需的一切了,我們繼續(xù),測試一下Twitter的包裝器。這一示例使用一個名為交互式的Ruby外殼(Interactive Ruby Shell,IRB)的外殼程序,該外殼程序允許實時地執(zhí)行Ruby命令以及使用語言進行實驗。IRB有著非常多的功能,不過我們只用它來做一些簡單的實驗。
清單1展示了與IRB的一個會話,該會話被分成了三段以便于閱讀。第一段(001和002行)通過導入必需的運行時元素來做好環(huán)境方面的準備(require方法加載并執(zhí)行指定的庫)。接下來的一段(003行)說明的是使用Twitter gem來顯示從IBM® developerWorks®發(fā)出的最新tweet消息。如所展示的那樣,使用Client::Timeline模塊的user_timeline方法來顯示一條消息,這第一個例子說明了Ruby的“鏈方法”的功能。user_timeline方法返回一個有著20條消息的數(shù)組,接著鏈入到方法first中,這樣做是為了從數(shù)組中提取出第一條消息(first是Array類的一個方法),接著從這一條消息中提取出文本字段,通過puts方法把它放到輸出中。
接下來的一段(004行)使用了用戶定義的位置字段,這是一個不限形式的字段,用戶可以在其中提供有用的或是無用的位置信息。在這一例子中,User模塊抓取了位置字段所限定的用戶信息。
最后一段(從005行開始)研究了Twitter::Search模塊,這一搜索模塊提供了極其豐富的用來搜索Twitter的接口。在這一例子中,首先是創(chuàng)建一個搜索實例(005行),接著在006行指定一個搜索,搜 LulzSec用戶在最近發(fā)出的包含了why這一詞的消息,結(jié)果列表已經(jīng)過刪減和編輯。搜索設(shè)置會一直存在在那里,因為搜索實例保持著所定義的過濾條件,你可以通過執(zhí)行search.clear來清除這些過濾條件。
清單1. 通過IRB來實驗Twitter API
$ irb
irb(main):001:0> require "rubygems"
=> true
irb(main):002:0> require "twitter"
=> true
irb(main):003:0> puts Twitter.user_timeline("developerworks").first.text
dW Twitter is saving #IBM over $600K per month: will #Google+ add to that?>
http://t.co/HiRwir7 #Tech #webdesign #Socialmedia #webapp #app
=> nil
irb(main):004:0> puts Twitter.user("MTimJones").location
Colorado, USA
=> nil
irb(main):005:0> search = Twitter::Search.new
=> #Twitter::Search:0xb7437e04 @oauth_token_secret=nil,
@endpoint="https://api.twitter.com/1/",
@user_agent="Twitter Ruby Gem 1.6.0",
@oauth_token=nil, @consumer_secret=nil,
@search_endpoint="https://search.twitter.com/",
@query={:tude=>[], :q=>[]}, @cache=nil, @gateway=nil, @consumer_key=nil,
@proxy=nil, @format=:json, @adapter=:net_http
irb(main):006:0> search.containing("why").to("LulzSec").
result_type("recent").each do |r| puts r.text end
@LulzSec why not stop posting bleep> and get a full time job! MYSQLi isn't
hacking you bleep>.
...
irb(main):007:0>
接下來,我們來看一下Twitter中的用戶的模式,你也可以通過IRB來實現(xiàn)這一點,不過我重排了結(jié)果的格式,以便簡化對Twitter用戶的內(nèi)部結(jié)構(gòu)的說明。清單2給出了用戶結(jié)構(gòu)的輸出結(jié)果,這在Ruby中是一個Hashie::Mash。這一結(jié)構(gòu)很有用,因為其允許對象有類方法的哈希鍵訪問器(公開的對象)。正如你從清單2中看到的那樣,這一對象包含了豐富的信息(用戶特定的以及渲染的信息),其中包括了當前的用戶狀態(tài)(帶有地理編碼信息)。一條tweet消息中也包含了大量的信息,你可以使用user_timeline類來輕松地可視化生成這一信息。
清單2. Twitter用戶的內(nèi)部解析結(jié)構(gòu)(Ruby視角)
irb(main):007:0> puts Twitter.user("MTimJones")
#Hashie::Mash
contributors_enabled=false
created_at="Wed Oct 08 20:40:53 +0000 2008"
default_profile=false default_profile_image=false
description="Platform Architect and author (Linux, Embedded, Networking, AI)."
favourites_count=1
follow_request_sent=nil
followers_count=148
following=nil
friends_count=96
geo_enabled=true
id=16655901 id_str="16655901"
is_translator=false
lang="en"
listed_count=10
location="Colorado, USA"
name="M. Tim Jones"
notifications=nil
profile_background_color="1A1B1F"
profile_background_image_url="..."
profile_background_image_url_https="..."
profile_background_tile=false
profile_image_url="http://a0.twimg.com/profile_images/851508584/bio_mtjones_normal.JPG"
profile_image_url_https="..."
profile_link_color="2FC2EF"
profile_sidebar_border_color="181A1E" profile_sidebar_fill_color="252429"
profile_text_color="666666"
profile_use_background_image=true
protected=false
screen_name="MTimJones"
show_all_inline_media=false
status=#Hashie::Mash
contributors=nil coordinates=nil
created_at="Sat Jul 02 02:03:24 +0000 2011"
favorited=false
geo=nil
id=86978247602094080 id_str="86978247602094080"
in_reply_to_screen_name="AnonymousIRC"
in_reply_to_status_id=nil in_reply_to_status_id_str=nil
in_reply_to_user_id=225663702 in_reply_to_user_id_str="225663702"
place=#Hashie::Mash
attributes=#Hashie::Mash>
bounding_box=#Hashie::Mash
coordinates=[[[-105.178387, 40.12596],
[-105.034397, 40.12596],
[-105.034397, 40.203495],
[-105.178387, 40.203495]]]
type="Polygon"
>
country="United States" country_code="US"
full_name="Longmont, CO"
id="2736a5db074e8201"
name="Longmont" place_type="city"
url="http://api.twitter.com/1/geo/id/2736a5db074e8201.json"
>
retweet_count=0
retweeted=false
source="web"
text="@AnonymousIRC @anonymouSabu @LulzSec @atopiary @Anonakomis Practical reading
for future reference... LULZ \"Prison 101\" http://t.co/sf8jIH9" truncated=false
>
statuses_count=79
time_zone="Mountain Time (US Canada)"
url="http://www.mtjones.com"
utc_offset=-25200
verified=false
>
=> nil
irb(main):008:0>
這就是快速展示部分的內(nèi)容?,F(xiàn)在,我們來研究一些簡單的腳本,你可以在這些腳本中使用Ruby和Twitter API來收集和可視化數(shù)據(jù)。在這一過程中,你會了解到Twitter的一些概念,比如說身份驗證和頻率限制等。
挖掘Twitter數(shù)據(jù)
接下來的幾節(jié)內(nèi)容介紹幾個通過Twitter API來收集和呈現(xiàn)可用數(shù)據(jù)的腳本,這些腳本重點在于其簡易性,不過你可以通過擴展以及組合他們來創(chuàng)建新的功能。另外,本節(jié)內(nèi)容還會提到Twitter gem API,這一API中有著更多可用的功能。
需要注意的很重要的一點是,在指定的時間內(nèi),Twitter API只允許客戶做有限次的調(diào)用,這也就是Twitter的頻率限制請求(現(xiàn)在是一小時不超過150次),這意味著經(jīng)過某個次數(shù)的使用后,你會收到一個錯誤消息,并要求你在提交新的請求之前先做一段時間的等待。
用戶信息
回想一下清單2中的每個Twitter用戶的大量可用信息,只有在用戶不受保護的情況下這些信息才是可訪問的。我們來看一下如何以一種更便捷的方式來提取用戶的信息并呈現(xiàn)出來。
清單3給出了一個(基于用戶的界面顯示名稱)檢索用戶信息的簡單的Ruby腳本,然后顯示一些更有用的內(nèi)容,在需要時使用Ruby方法to_s來把值轉(zhuǎn)換成字符串。需要注意的是,首先用戶是不受保護的,否則的話是不能訪問到她/他的數(shù)據(jù)的。
清單3. 提取Twitter用戶數(shù)據(jù)的簡單腳本(user.rb)
#!/usr/bin/env ruby
require "rubygems"
require "twitter"
screen_name = String.new ARGV[0]
a_user = Twitter.user(screen_name)
if a_user.protected != true
puts "Username : " + a_user.screen_name.to_s
puts "Name : " + a_user.name
puts "Id : " + a_user.id_str
puts "Location : " + a_user.location
puts "User since : " + a_user.created_at.to_s
puts "Bio : " + a_user.description.to_s
puts "Followers : " + a_user.followers_count.to_s
puts "Friends : " + a_user.friends_count.to_s
puts "Listed Cnt : " + a_user.listed_count.to_s
puts "Tweet Cnt : " + a_user.statuses_count.to_s
puts "Geocoded : " + a_user.geo_enabled.to_s
puts "Language : " + a_user.lang
puts "URL : " + a_user.url.to_s
puts "Time Zone : " + a_user.time_zone
puts "Verified : " + a_user.verified.to_s
puts
tweet = Twitter.user_timeline(screen_name).first
puts "Tweet time : " + tweet.created_at
puts "Tweet ID : " + tweet.id.to_s
puts "Tweet text : " + tweet.text
end
若要調(diào)用這一腳本,需要確保其是可執(zhí)行的(chmod +x user.rb),使用一個用戶的名稱來調(diào)用它。清單4顯示了使用用戶developerworks調(diào)用的結(jié)果,給出了用戶的信息和當前狀態(tài)(最后一條tweet消息)。這里要注意的是,Twitter把關(guān)注你的人定義為followers(粉絲);而把你關(guān)注的人稱作friends(朋友)。
清單4. user.rb的輸出例子
$ ./user.rb developerworks
Username : developerworks
Name : developerworks
Id : 16362921
Location :
User since : Fri Sep 19 13:10:39 +0000 2008
Bio : IBM's premier Web site for Java, Android, Linux, Open Source, PHP, Social,
Cloud Computing, Google, jQuery, and Web developer educational resources
Followers : 48439
Friends : 46299
Listed Cnt : 3801
Tweet Cnt : 9831
Geocoded : false
Language : en
URL : http://bit.ly/EQ7te
Time Zone : Pacific Time (US Canada)
Verified : false
Tweet time : Sun Jul 17 01:04:46 +0000 2011
Tweet ID : 92399309022167040
Tweet text : dW Twitter is saving #IBM over $600K per month: will #Google+ add to that? >
http://t.co/HiRwir7 #Tech #webdesign #Socialmedia #webapp #app
朋友的受歡迎情況
研究一下你的朋友(你關(guān)注的人),收集數(shù)據(jù)來了解一下他們的受歡迎程度。在這個例子中,收集朋友的數(shù)據(jù)并按照他們的粉絲數(shù)目來進行排序,這一簡單的腳本如清單5所示。
在這一腳本中,在了解了你要(基于界面顯示名稱)分析的用戶后,創(chuàng)建一個用戶哈希表,Ruby哈希(或是相關(guān)的數(shù)組)是一種可以允許你定義存儲鍵(而不是簡單的數(shù)值索引)的數(shù)據(jù)結(jié)構(gòu)。接著,通過Twitter的界面名稱來索引這一哈希表,關(guān)聯(lián)值則是用戶的粉絲數(shù)目。這一過程簡單地遍歷你的朋友然后把他們的粉絲的數(shù)目放入哈希表中,接著(以降序)排列哈希表,然后把它放到輸出中。
清單5. 關(guān)于朋友的受歡迎程度的腳本(friends.rb)
#!/usr/bin/env ruby
require "rubygems"
require "twitter"
name = String.new ARGV[0]
user = Hash.new
# Iterate friends, hash their followers
Twitter.friends(name).users.each do |f|
# Only iterate if we can see their followers
if (f.protected.to_s != "true")
user[f.screen_name.to_s] = f.followers_count
end
end
user.sort_by {|k,v| -v}.each { |user, count| puts "#{user}, #{count}" }
清單5中的朋友腳本的一個例子輸出如清單6所示。我刪減了輸出內(nèi)容以節(jié)省空間,不過你可以看到,在我的直接網(wǎng)絡(luò)中,ReadWriteWeb(RWW)和Playstation是很受歡迎的Twitter用戶。
清單6. 清單5中的朋友腳本的界面輸出
$ ./friends.rb MTimJones
RWW, 1096862
PlayStation, 1026634
HarvardBiz, 541139
tedtalks, 526886
lifehacker, 146162
wandfc, 121683
AnonymousIRC, 117896
iTunesPodcasts, 82581
adultswim, 76188
forrester, 72945
googleresearch, 66318
Gartner_inc, 57468
developerworks, 48518
我的粉絲來自哪里
回想一下清單2,Twitter提供了豐富的位置信息,有一個不限形式、用戶定義的、可選用地理編碼數(shù)據(jù)的位置字段。不過,用戶設(shè)定的時區(qū)也可以為粉絲的實際位置提供線索。
在這一例子中,你要構(gòu)建一個混搭應(yīng)用程序來從Twitter粉絲中提取時區(qū)數(shù)據(jù),然后使用Google Charts來可視化這一數(shù)據(jù)。Google Charts是一個非常有意思的項目,其允許你通過網(wǎng)絡(luò)來構(gòu)建各種各樣不同類型的圖表;把圖表的類型和數(shù)據(jù)定義成HTTP請求,直接在瀏覽器中渲染作為響應(yīng)的結(jié)果。若要安裝用于Google Charts的Ruby gem,使用下面的命令行:
清單7提供的腳本提取時區(qū)數(shù)據(jù),接著構(gòu)建Google Charts請求。首先,與之前的腳本不同,這一腳本需要你通過Twitter的身份驗證。若要做到這一點,你需要注冊一個Twitter應(yīng)用,這會給你提供一組鍵值和令牌,這些令牌可以用在清單7的腳本中,這樣才能夠成功地取到數(shù)據(jù)。請參閱參考資料了解這一簡單過程的詳細情況。
按照相類似的模式,該腳本接受了一個界面名稱,然后遍歷該用戶的粉絲,從當前粉絲中提取時區(qū)并把它存放在tweetlocation哈希表中。需要注意的是,你先要檢測該鍵值是否已經(jīng)存在于哈希表中,若是的話,增加該鍵值的計數(shù)。你還可以記住所有時區(qū)的個數(shù),以用于后面的百分比的計算。
這一腳本的最后一部分內(nèi)容是構(gòu)造Google Pie Chart的URL,創(chuàng)建一個新的PieChart,指定一些選項(大小、標題和是否為3D等);接著,遍歷時區(qū)哈希表,找出用于圖表的時區(qū)串的數(shù)據(jù)(刪去符號)以及該時區(qū)計數(shù)與總數(shù)的百分比。
清單7.通過Twitter的時區(qū)來構(gòu)建一個餅圖(followers-location.rb)
#!/usr/bin/env ruby
require "rubygems"
require "twitter"
require 'google_chart'
screen_name = String.new ARGV[0]
tweetlocation = Hash.new
timezones = 0.0
# Authenticate
Twitter.configure do |config|
config.consumer_key = ''
config.consumer_secret = ''
config.oauth_token = '
config.oauth_token_secret = ''
end
# Iterate followers, hash their location
followers = Twitter.followers.users.each do |f|
loc = f.time_zone.to_s
if (loc.length > 0)
if tweetlocation.has_key?(loc)
tweetlocation[loc] = tweetlocation[loc] + 1
else
tweetlocation[loc] = 1
end
timezones = timezones + 1.0
end
end
# Create a pie chart
GoogleChart::PieChart.new('650x350', "Time Zones", false ) do |pc|
tweetlocation.each do |loc,count|
pc.data loc.to_s.delete(""), (count/timezones*100).round
end
puts pc.to_url
end
若要執(zhí)行清單7中的腳本,給它提供一個Twitter界面顯示名稱,然后把得出的URL拷貝并粘貼到瀏覽器中,清單8給出了這一過程及最終生成的URL。
清單8. 調(diào)用followers-location腳本(結(jié)果只是一行來的)
$ ./followers-location.rb MTimJones
http://chart.apis.google.com/chart?chl=Seoul|Santiago|Paris|Mountain+Time+(US++Canada)|
Madrid|Central+Time+(US++Canada)|Warsaw|Kolkata|London|Pacific+Time+(US++Canada)|
New+Delhi|Pretoria|Quito|Dublin|Moscow|Istanbul|Taipei|Casablanca|Hawaii|Mumbai|
International+Date+Line+West|Tokyo|Ulaan+Bataar|Vienna|Osaka|Alaska|Chennai|Bern|
Brasilia|Eastern+Time+(US++Canada)|Rome|Perth|La+Paz
chs=650x350chtt=Time+Zoneschd=s:KDDyKcKDOcKDKDDDDDKDDKDDDDOKK9DDDcht=p
$
把清單8中的URL粘貼到瀏覽器中,你就可以得到圖1所示的結(jié)果。
圖1. Twitter粉絲位置分布的餅圖
Twitter用戶的行為
Twitter包含了大量的數(shù)據(jù),你可以通過挖掘這些數(shù)據(jù)來了解用戶行為的某些要素。兩個簡單例子將用來分析Twitter用戶何時發(fā)布消息以及通過什么應(yīng)用來發(fā)布消息,你可以使用下面兩個簡單的腳本來提取并可視化這些信息。
清單9給出的腳本遍歷了某個特定用戶的tweet消息(使用user_timeline方法),然后從每條tweet消息中提取出該tweet消息形成的具體時間,一個簡單的哈希表被再次用來統(tǒng)計一周中每天的計數(shù),然后以與前面的時區(qū)例子相類似的方式使用Google Charts生成一個柱狀圖。
清單9. 構(gòu)建tweet發(fā)布時間的柱狀圖(tweet-days.rb)
#!/usr/bin/env ruby
require "rubygems"
require "twitter"
require "google_chart"
screen_name = String.new ARGV[0]
dayhash = Hash.new
timeline = Twitter.user_timeline(screen_name, :count => 200 )
timeline.each do |t|
tweetday = t.created_at.to_s[0..2]
if dayhash.has_key?(tweetday)
dayhash[tweetday] = dayhash[tweetday] + 1
else
dayhash[tweetday] = 1
end
end
GoogleChart::BarChart.new('300x200', screen_name, :vertical, false) do |bc|
bc.data "Sunday", [dayhash["Sun"]], '00000f'
bc.data "Monday", [dayhash["Mon"]], '0000ff'
bc.data "Tuesday", [dayhash["Tue"]], '00ff00'
bc.data "Wednesday", [dayhash["Wed"]], '00ffff'
bc.data "Thursday", [dayhash["Thu"]], 'ff0000'
bc.data "Friday", [dayhash["Fri"]], 'ff00ff'
bc.data "Saturday", [dayhash["Sat"]], 'ffff00'
puts bc.to_url
end
圖2提供了使用developerWorks帳戶來執(zhí)行清單9中的tweet-days腳本的結(jié)果,正如所展示的那樣,星期三是發(fā)布tweet消息最活躍的一條,最不活躍的是星期六和星期天。
圖2. 比較每天的tweet活躍程度的柱狀圖
接下來的腳本確定特定用戶通過哪一個來源發(fā)布tweet消息,你可以通過幾種方式來發(fā)布消息,這一腳本并未對每一種都做了編碼。如清單10所示,使用類似的模式來提取給定用戶的時間軸上的內(nèi)容,然后嘗試著解碼哈希表中的tweet消息的發(fā)出處。稍后這一哈希表會被用來創(chuàng)建一個簡單的餅圖,使用Google Charts來可視化數(shù)據(jù)。
清單10. 構(gòu)建用戶的tweet消息源的餅圖(tweet-source.rb)
#!/usr/bin/env ruby
require "rubygems"
require "twitter"
require 'google_chart'
screen_name = String.new ARGV[0]
tweetsource = Hash.new
timeline = Twitter.user_timeline(screen_name, :count => 200 )
timeline.each do |t|
if (t.source.rindex('blackberry')) then
src = 'Blackberry'
elsif (t.source.rindex('snaptu')) then
src = 'Snaptu'
elsif (t.source.rindex('tweetmeme')) then
src = 'Tweetmeme'
elsif (t.source.rindex('android')) then
src = 'Android'
elsif (t.source.rindex('LinkedIn')) then
src = 'LinkedIn'
elsif (t.source.rindex('twitterfeed')) then
src = 'Twitterfeed'
elsif (t.source.rindex('twitter.com')) then
src = 'Twitter.com'
else
src = t.source
end
if tweetsource.has_key?(src)
tweetsource[src] = tweetsource[src] + 1
else
tweetsource[src] = 1
end
end
GoogleChart::PieChart.new('320x200', "Tweet Source", false) do |pc|
tweetsource.each do|source,count|
pc.data source.to_s, count
end
puts "\nPie Chart"
puts pc.to_url
end
圖3提供了一個可視化圖表,顯示了一組Twitter用戶感興趣使用的tweet消息發(fā)布源,傳統(tǒng)的Twitter網(wǎng)站最常用到,隨后是移動電話應(yīng)用。
圖3. Twitter用戶的tweet消息發(fā)布源的餅圖
反映粉絲情況的圖表
Twitter是一個龐大的用戶網(wǎng)絡(luò),這些用戶形成了一個網(wǎng)絡(luò)圖。正如你通過腳本所看到的那樣,遍歷你的聯(lián)系人很容易,接著遍歷他們的聯(lián)系人也很容易。即使只是在這一級別上,這樣做也已建立起一張大圖的基本面。
為了可視化圖形,我選擇使用圖形可視化軟件GraphViz。在Ubuntu上,使用下面的命令行,你可以很容易就安裝好這一工具:
$ sudo apt-get install graphviz
清單11中的腳本遍歷了用戶的粉絲,然后再遍歷這些粉絲他們的粉絲。這一模式中的唯一真正不同之處在于 GraphViz的DOT格式文件的構(gòu)造,GraphViz使用簡單的腳本格式來定義圖形,這些圖形作為你列舉的Twitter用戶的組成部分出現(xiàn)。如清單所展示的那樣,可以簡單地通過指定節(jié)點的關(guān)系來定義圖形。
清單11. 可視化Twitter粉絲圖(followers-graph.rb)
#!/usr/bin/env ruby
require "rubygems"
require "twitter"
require 'google_chart'
screen_name = String.new ARGV[0]
tweetlocation = Hash.new
# Authenticate
Twitter.configure do |config|
config.consumer_key = ''
config.consumer_secret = ''
config.oauth_token = ''
config.oauth_token_secret = ''
end
my_file = File.new("graph.dot", "w")
my_file.puts "graph followers {"
my_file.puts " node [ fontname=Arial, fontsize=6 ];"
# Iterate followers, hash their location
followers = Twitter.followers(screen_name, :count=>10 ).users.each do |f|
# Only iterate if we can see their followers
if (f.protected.to_s != "true")
my_file.puts " \"" + screen_name + "\" -- \"" + f.screen_name.to_s + "\""
followers2 = Twitter.followers(f.screen_name, :count =>10 ).users.each do |f2|
my_file.puts " \"" + f.screen_name.to_s + "\" -- \"" +
f2.screen_name.to_s + "\""
end
end
end
my_file.puts "}"
在某個用戶上執(zhí)行清單11的腳本,得出的結(jié)果放在一個dot文件中,接著使用GraphViz來生成圖像。首先調(diào)用Ruby腳本來收集圖形數(shù)據(jù)(存儲成graph.dot);接著使用GraphViz來生成圖像(這里用的是circo,該工具指定了一種圓形的布局)。生成圖像的過程定義如下:
$ ./followers-graph.rb MTimJones
$ circo graph.dot -Tpng -o graph.png
最終得出的圖像如圖4所示。需要注意的是,由于這一Twitter圖表可能會很大,因為我們通過盡量減少要列舉的用戶及其粉絲的數(shù)目來限制圖表的規(guī)模(通過清單11中的:count選項)。
圖4. Twitter粉絲圖例子(極端情況的子集)
位置信息
在功能啟用的情況下,Twitter收集你和你發(fā)出tweet消息的地理位置數(shù)據(jù)。這些由經(jīng)度和緯度信息組成的數(shù)據(jù)能夠用來精確地定位用戶的位置或者是tweet消息從何處發(fā)出。此外,把搜索和這些消息結(jié)合在一起,你就可以根據(jù)已定義的位置或是你所處的位置來識別出某些地方或是某些人。
并非所有的用戶或是tweet消息都啟用了地理位置功能(出于隱私原因),但這一信息是所有Twitter體驗當中的一個非常吸引人的方面。讓我們來看一個腳本,該腳本允許你可視化地理定位數(shù)據(jù),還有另一個腳本允許你使用這一數(shù)據(jù)來進行搜索。
第一個腳本(清單12所示)抓取用戶的經(jīng)度和緯度數(shù)據(jù)(回想一下清單2中的邊界框(bounding box)),盡管邊界框是一個定義代表了用戶區(qū)域的多邊形,但我做了簡化,只用了這一區(qū)域中的一個點。有了這一數(shù)據(jù),我在一個簡單的HMTL文件中生成了一個簡單的JavaScript函數(shù),這一JavaScript代碼與Google Maps接口,給出了這一位置的一個俯視地圖(給出提取自Twitter用戶的經(jīng)度和緯度數(shù)據(jù))。
清單12. 構(gòu)造用戶地圖的Ruby腳本(where-am-i.rb)
#!/usr/bin/env ruby
require "rubygems"
require "twitter"
Twitter.configure do |config|
config.consumer_key = 'consumer_key>
config.consumer_secret = 'consumer_secret>
config.oauth_token = 'oauth_token>
config.oauth_token_secret = 'token_secret>
end
screen_name = String.new ARGV[0]
a_user = Twitter.user(screen_name)
if a_user.geo_enabled == true
long = a_user.status.place.bounding_box.coordinates[0][0][0];
lat = a_user.status.place.bounding_box.coordinates[0][0][1];
my_file = File.new("test.html", "w")
my_file.puts "!DOCTYPE html>
my_file.puts "html> head>
my_file.puts "meta name=\"viewport\" content=\"initial-scale=1.0, user-scalable=no\"/>"
my_file.puts "style type=\"text/css\">"
my_file.puts "html { height: 100% }"
my_file.puts "body { height: 100%; margin: 0px; padding: 0px }"
my_file.puts "#map_canvas { height: 100% }"
my_file.puts "/style>"
my_file.puts " script type=\"text/javascript\""
my_file.puts "src=\"http://maps.google.com/maps/api/js?sensor=false\">"
my_file.puts "/script>"
my_file.puts "script type=\"text/javascript\">"
my_file.puts "function initialize() {"
my_file.puts "var latlng = new google.maps.LatLng(" + lat.to_s + ", " + long.to_s + ");"
my_file.puts "var myOptions = {"
my_file.puts "zoom: 12,"
my_file.puts "center: latlng,"
my_file.puts "mapTypeId: google.maps.MapTypeId.HYBRID"
my_file.puts "};"
my_file.puts "var map = new google.maps.Map(document.getElementById(\"map_canvas\"),"
my_file.puts "myOptions);"
my_file.puts "}"
my_file.puts "/script>"
my_file.puts "/head>"
my_file.puts "body onload=\"initialize()\">"
my_file.puts "div id=\"map_canvas\" style=\"width:100%; height:100%\">/div>"
my_file.puts "/body>"
my_file.puts "/html>"
else
puts "no geolocation data available."
end
清單12中的腳本執(zhí)行起來很簡單:
$ ./where-am-i.rb MTimJones
最終得出的HTML文件可以通過瀏覽器來渲染,像這樣:
如果沒有可用的位置信息的話,這一腳本就會執(zhí)行失敗;不過如果執(zhí)行成功的話,就會生成一個HTML文件,瀏覽器可以讀入該文件來渲染出地圖。圖5給出了最終生成的地圖圖像,其顯示了美國科羅拉多州北部Front Range的部分地區(qū)。
圖5. 清單12中的腳本渲染圖像的例子
有了地理位置,你還可以通過搜Twitter來識別出與某個特定位置相關(guān)聯(lián)的Twitter用戶和tweet消息。Twitter搜索API允許使用地理編碼信息來限定搜索結(jié)果。下面清單13中的例子提取用戶的經(jīng)度和緯度,然后使用這些數(shù)據(jù)獲取該位置方圓5公里之內(nèi)的所有tweet消息。
清單13. 使用經(jīng)度和緯度數(shù)據(jù)來搜索局部地區(qū)的tweet消息(tweets-local.rb)
#!/usr/bin/env ruby
require "rubygems"
require "twitter"
Twitter.configure do |config|
config.consumer_key = ''
config.consumer_secret = ''
config.oauth_token = ''
config.oauth_token_secret = ''
end
screen_name = String.new ARGV[0]
a_user = Twitter.user(screen_name)
if a_user.geo_enabled == true
long = a_user.status.place.bounding_box.coordinates[0][0][0]
lat = a_user.status.place.bounding_box.coordinates[0][0][1]
Array tweets = Twitter::Search.new.geocode(lat, long, "5mi").fetch
tweets.each do |t|
puts t.from_user + " | " + t.text
end
end
清單13中的腳本的執(zhí)行結(jié)果顯示在清單14中,這是指定位置范圍內(nèi)的Twitter用戶發(fā)布的tweet消息的一個子集。
清單14. 查詢我所在位置方圓5公里之內(nèi)的這一局部地區(qū)的tweet消息。
$ ./tweets-local.rb MTimJones
Breesesummer | @DaltonOls did he answer u
LongmontRadMon | 60 CPM, 0.4872 uSv/h, 0.6368 uSv/h, 2 time(s) over natural radiation
graelston | on every street there is a memory; a time and place we can never be again.
Breesesummer | #I'minafight with @DaltonOls to see who will marry @TheCodySimpson I will
marry him!!! :/
_JennieJune_ | ok I'm done, goodnight everyone!
Breesesummer | @DaltonOls same
_JennieJune_ | @sylquejr sleep well!
Breesesummer | @DaltonOls ok let's see what he says
LongmontRadMon | 90 CPM, 0.7308 uSv/h, 0.7864 uSv/h, 2 time(s) over natural radiation
Breesesummer | @TheCodySimpson would u marry me or @DaltonOls
natcapsolutions | RT hlovins: The scientific rebuttal to the silly Forbes release this
morning: Misdiagnosis of Surface Temperatu... http://bit.ly/nRpLJl
$
繼續(xù)深入
本文給出了一些簡單的腳本,這些腳本使用Ruby語言來從Twitter中提取數(shù)據(jù),文章的重點放在用來說明一些基本概念的腳本的開發(fā)和演示方面,但我們能做的遠不止于此。例如,你還可以使用API來瀏覽你的朋友的網(wǎng)絡(luò),并找出你感興趣的最受歡迎的Twitter用戶。另一個吸引人的方面是對tweet消息本身進行挖掘,使用地理位置數(shù)據(jù)來了解基于位置的行為或是事件(比如說流感暴發(fā))。本文只是做了一個淺顯的介紹,請在下面隨意發(fā)表你的評論,附上你自己的各種混搭程序。Ruby和Twitter gem把為數(shù)據(jù)挖掘需要開發(fā)有用的混搭應(yīng)用程序和儀表盤工具的工作變得很容易。
您可能感興趣的文章:- Ruby on Rails實現(xiàn)最基本的用戶注冊和登錄功能的教程