Twitter以及一些API
盡管早期的網(wǎng)絡(luò)涉及的是人-機(jī)器的交互,但現(xiàn)在的網(wǎng)絡(luò)已涉及機(jī)器-機(jī)器之間的交互,這種交互是使用web服務(wù)來(lái)支持的。大部分受歡迎的網(wǎng)站都有這樣的服務(wù)存在——從各種各樣的Google服務(wù)到LinkedIn、Facebook和Twitter等。通過(guò)web服務(wù)創(chuàng)建的API,外部的應(yīng)用可以查詢或是操縱網(wǎng)站上的內(nèi)容。
web服務(wù)可以使用多種方式來(lái)實(shí)現(xiàn)。目前最流行的做法之一是表述性狀態(tài)轉(zhuǎn)移(Representational State Transfe, REST)。REST的一種實(shí)現(xiàn)是通過(guò)為人熟知的HTTP協(xié)議,允許HTTP作為RESTful架構(gòu)的媒介存在(使用諸如GET、PUT、POST、DELETE一類的標(biāo)準(zhǔn)HTTP操作)。Twitter的API是作為這一媒介之上的一個(gè)抽象來(lái)進(jìn)行開(kāi)發(fā)的。在這一做法中,沒(méi)有涉及REST、HTTP或是XML或JSON一類的數(shù)據(jù)格式的知識(shí),而是代之以清晰地整合到了Ruby語(yǔ)言中的基于對(duì)象的接口。
Ruby和Twitter的一個(gè)快速展示
讓我們來(lái)探討一下如何在Ruby中使用Twitter API。首先,我們需要獲取所需的資源,如果你像我一樣在用Ubuntu Linux®的話,就使用apt框架。
若要獲取最新的完整的Ruby分發(fā)版本(大約13MB的下載量),使用這一命令行:
$ sudo apt-get install ruby1.9.1-full
接著使用gem實(shí)用程序來(lái)抓取Twitter gem:
$ sudo gem install twitter
現(xiàn)在你已經(jīng)有了這一步驟所需的一切了,我們繼續(xù),測(cè)試一下Twitter的包裝器。這一示例使用一個(gè)名為交互式的Ruby外殼(Interactive Ruby Shell,IRB)的外殼程序,該外殼程序允許實(shí)時(shí)地執(zhí)行Ruby命令以及使用語(yǔ)言進(jìn)行實(shí)驗(yàn)。IRB有著非常多的功能,不過(guò)我們只用它來(lái)做一些簡(jiǎn)單的實(shí)驗(yàn)。
清單1展示了與IRB的一個(gè)會(huì)話,該會(huì)話被分成了三段以便于閱讀。第一段(001和002行)通過(guò)導(dǎo)入必需的運(yùn)行時(shí)元素來(lái)做好環(huán)境方面的準(zhǔn)備(require方法加載并執(zhí)行指定的庫(kù))。接下來(lái)的一段(003行)說(shuō)明的是使用Twitter gem來(lái)顯示從IBM® developerWorks®發(fā)出的最新tweet消息。如所展示的那樣,使用Client::Timeline模塊的user_timeline方法來(lái)顯示一條消息,這第一個(gè)例子說(shuō)明了Ruby的“鏈方法”的功能。user_timeline方法返回一個(gè)有著20條消息的數(shù)組,接著鏈入到方法first中,這樣做是為了從數(shù)組中提取出第一條消息(first是Array類的一個(gè)方法),接著從這一條消息中提取出文本字段,通過(guò)puts方法把它放到輸出中。
接下來(lái)的一段(004行)使用了用戶定義的位置字段,這是一個(gè)不限形式的字段,用戶可以在其中提供有用的或是無(wú)用的位置信息。在這一例子中,User模塊抓取了位置字段所限定的用戶信息。
最后一段(從005行開(kāi)始)研究了Twitter::Search模塊,這一搜索模塊提供了極其豐富的用來(lái)搜索Twitter的接口。在這一例子中,首先是創(chuàng)建一個(gè)搜索實(shí)例(005行),接著在006行指定一個(gè)搜索,搜 LulzSec用戶在最近發(fā)出的包含了why這一詞的消息,結(jié)果列表已經(jīng)過(guò)刪減和編輯。搜索設(shè)置會(huì)一直存在在那里,因?yàn)樗阉鲗?shí)例保持著所定義的過(guò)濾條件,你可以通過(guò)執(zhí)行search.clear來(lái)清除這些過(guò)濾條件。
清單1. 通過(guò)IRB來(lái)實(shí)驗(yàn)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>
接下來(lái),我們來(lái)看一下Twitter中的用戶的模式,你也可以通過(guò)IRB來(lái)實(shí)現(xiàn)這一點(diǎn),不過(guò)我重排了結(jié)果的格式,以便簡(jiǎn)化對(duì)Twitter用戶的內(nèi)部結(jié)構(gòu)的說(shuō)明。清單2給出了用戶結(jié)構(gòu)的輸出結(jié)果,這在Ruby中是一個(gè)Hashie::Mash。這一結(jié)構(gòu)很有用,因?yàn)槠湓试S對(duì)象有類方法的哈希鍵訪問(wèn)器(公開(kāi)的對(duì)象)。正如你從清單2中看到的那樣,這一對(duì)象包含了豐富的信息(用戶特定的以及渲染的信息),其中包括了當(dāng)前的用戶狀態(tài)(帶有地理編碼信息)。一條tweet消息中也包含了大量的信息,你可以使用user_timeline類來(lái)輕松地可視化生成這一信息。
清單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)在,我們來(lái)研究一些簡(jiǎn)單的腳本,你可以在這些腳本中使用Ruby和Twitter API來(lái)收集和可視化數(shù)據(jù)。在這一過(guò)程中,你會(huì)了解到Twitter的一些概念,比如說(shuō)身份驗(yàn)證和頻率限制等。
挖掘Twitter數(shù)據(jù)
接下來(lái)的幾節(jié)內(nèi)容介紹幾個(gè)通過(guò)Twitter API來(lái)收集和呈現(xiàn)可用數(shù)據(jù)的腳本,這些腳本重點(diǎn)在于其簡(jiǎn)易性,不過(guò)你可以通過(guò)擴(kuò)展以及組合他們來(lái)創(chuàng)建新的功能。另外,本節(jié)內(nèi)容還會(huì)提到Twitter gem API,這一API中有著更多可用的功能。
需要注意的很重要的一點(diǎn)是,在指定的時(shí)間內(nèi),Twitter API只允許客戶做有限次的調(diào)用,這也就是Twitter的頻率限制請(qǐng)求(現(xiàn)在是一小時(shí)不超過(guò)150次),這意味著經(jīng)過(guò)某個(gè)次數(shù)的使用后,你會(huì)收到一個(gè)錯(cuò)誤消息,并要求你在提交新的請(qǐng)求之前先做一段時(shí)間的等待。
用戶信息
回想一下清單2中的每個(gè)Twitter用戶的大量可用信息,只有在用戶不受保護(hù)的情況下這些信息才是可訪問(wèn)的。我們來(lái)看一下如何以一種更便捷的方式來(lái)提取用戶的信息并呈現(xiàn)出來(lái)。
清單3給出了一個(gè)(基于用戶的界面顯示名稱)檢索用戶信息的簡(jiǎn)單的Ruby腳本,然后顯示一些更有用的內(nèi)容,在需要時(shí)使用Ruby方法to_s來(lái)把值轉(zhuǎn)換成字符串。需要注意的是,首先用戶是不受保護(hù)的,否則的話是不能訪問(wèn)到她/他的數(shù)據(jù)的。
清單3. 提取Twitter用戶數(shù)據(jù)的簡(jiǎn)單腳本(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),使用一個(gè)用戶的名稱來(lái)調(diào)用它。清單4顯示了使用用戶developerworks調(diào)用的結(jié)果,給出了用戶的信息和當(dāng)前狀態(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ù)來(lái)了解一下他們的受歡迎程度。在這個(gè)例子中,收集朋友的數(shù)據(jù)并按照他們的粉絲數(shù)目來(lái)進(jìn)行排序,這一簡(jiǎn)單的腳本如清單5所示。
在這一腳本中,在了解了你要(基于界面顯示名稱)分析的用戶后,創(chuàng)建一個(gè)用戶哈希表,Ruby哈希(或是相關(guān)的數(shù)組)是一種可以允許你定義存儲(chǔ)鍵(而不是簡(jiǎn)單的數(shù)值索引)的數(shù)據(jù)結(jié)構(gòu)。接著,通過(guò)Twitter的界面名稱來(lái)索引這一哈希表,關(guān)聯(lián)值則是用戶的粉絲數(shù)目。這一過(guò)程簡(jiǎn)單地遍歷你的朋友然后把他們的粉絲的數(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中的朋友腳本的一個(gè)例子輸出如清單6所示。我刪減了輸出內(nèi)容以節(jié)省空間,不過(guò)你可以看到,在我的直接網(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
我的粉絲來(lái)自哪里
回想一下清單2,Twitter提供了豐富的位置信息,有一個(gè)不限形式、用戶定義的、可選用地理編碼數(shù)據(jù)的位置字段。不過(guò),用戶設(shè)定的時(shí)區(qū)也可以為粉絲的實(shí)際位置提供線索。
在這一例子中,你要構(gòu)建一個(gè)混搭應(yīng)用程序來(lái)從Twitter粉絲中提取時(shí)區(qū)數(shù)據(jù),然后使用Google Charts來(lái)可視化這一數(shù)據(jù)。Google Charts是一個(gè)非常有意思的項(xiàng)目,其允許你通過(guò)網(wǎng)絡(luò)來(lái)構(gòu)建各種各樣不同類型的圖表;把圖表的類型和數(shù)據(jù)定義成HTTP請(qǐng)求,直接在瀏覽器中渲染作為響應(yīng)的結(jié)果。若要安裝用于Google Charts的Ruby gem,使用下面的命令行:
$ gem install gchartrb
清單7提供的腳本提取時(shí)區(qū)數(shù)據(jù),接著構(gòu)建Google Charts請(qǐng)求。首先,與之前的腳本不同,這一腳本需要你通過(guò)Twitter的身份驗(yàn)證。若要做到這一點(diǎn),你需要注冊(cè)一個(gè)Twitter應(yīng)用,這會(huì)給你提供一組鍵值和令牌,這些令牌可以用在清單7的腳本中,這樣才能夠成功地取到數(shù)據(jù)。請(qǐng)參閱參考資料了解這一簡(jiǎn)單過(guò)程的詳細(xì)情況。
按照相類似的模式,該腳本接受了一個(gè)界面名稱,然后遍歷該用戶的粉絲,從當(dāng)前粉絲中提取時(shí)區(qū)并把它存放在tweetlocation哈希表中。需要注意的是,你先要檢測(cè)該鍵值是否已經(jīng)存在于哈希表中,若是的話,增加該鍵值的計(jì)數(shù)。你還可以記住所有時(shí)區(qū)的個(gè)數(shù),以用于后面的百分比的計(jì)算。
這一腳本的最后一部分內(nèi)容是構(gòu)造Google Pie Chart的URL,創(chuàng)建一個(gè)新的PieChart,指定一些選項(xiàng)(大小、標(biāo)題和是否為3D等);接著,遍歷時(shí)區(qū)哈希表,找出用于圖表的時(shí)區(qū)串的數(shù)據(jù)(刪去符號(hào))以及該時(shí)區(qū)計(jì)數(shù)與總數(shù)的百分比。
清單7.通過(guò)Twitter的時(shí)區(qū)來(lái)構(gòu)建一個(gè)餅圖(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中的腳本,給它提供一個(gè)Twitter界面顯示名稱,然后把得出的URL拷貝并粘貼到瀏覽器中,清單8給出了這一過(guò)程及最終生成的URL。
清單8. 調(diào)用followers-location腳本(結(jié)果只是一行來(lái)的)
$ ./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ù),你可以通過(guò)挖掘這些數(shù)據(jù)來(lái)了解用戶行為的某些要素。兩個(gè)簡(jiǎn)單例子將用來(lái)分析Twitter用戶何時(shí)發(fā)布消息以及通過(guò)什么應(yīng)用來(lái)發(fā)布消息,你可以使用下面兩個(gè)簡(jiǎn)單的腳本來(lái)提取并可視化這些信息。
清單9給出的腳本遍歷了某個(gè)特定用戶的tweet消息(使用user_timeline方法),然后從每條tweet消息中提取出該tweet消息形成的具體時(shí)間,一個(gè)簡(jiǎn)單的哈希表被再次用來(lái)統(tǒng)計(jì)一周中每天的計(jì)數(shù),然后以與前面的時(shí)區(qū)例子相類似的方式使用Google Charts生成一個(gè)柱狀圖。
清單9. 構(gòu)建tweet發(fā)布時(shí)間的柱狀圖(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帳戶來(lái)執(zhí)行清單9中的tweet-days腳本的結(jié)果,正如所展示的那樣,星期三是發(fā)布tweet消息最活躍的一條,最不活躍的是星期六和星期天。
圖2. 比較每天的tweet活躍程度的柱狀圖
接下來(lái)的腳本確定特定用戶通過(guò)哪一個(gè)來(lái)源發(fā)布tweet消息,你可以通過(guò)幾種方式來(lái)發(fā)布消息,這一腳本并未對(duì)每一種都做了編碼。如清單10所示,使用類似的模式來(lái)提取給定用戶的時(shí)間軸上的內(nèi)容,然后嘗試著解碼哈希表中的tweet消息的發(fā)出處。稍后這一哈希表會(huì)被用來(lái)創(chuàng)建一個(gè)簡(jiǎn)單的餅圖,使用Google Charts來(lái)可視化數(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提供了一個(gè)可視化圖表,顯示了一組Twitter用戶感興趣使用的tweet消息發(fā)布源,傳統(tǒng)的Twitter網(wǎng)站最常用到,隨后是移動(dòng)電話應(yīng)用。
圖3. Twitter用戶的tweet消息發(fā)布源的餅圖
反映粉絲情況的圖表
Twitter是一個(gè)龐大的用戶網(wǎng)絡(luò),這些用戶形成了一個(gè)網(wǎng)絡(luò)圖。正如你通過(guò)腳本所看到的那樣,遍歷你的聯(lián)系人很容易,接著遍歷他們的聯(lián)系人也很容易。即使只是在這一級(jí)別上,這樣做也已建立起一張大圖的基本面。
為了可視化圖形,我選擇使用圖形可視化軟件GraphViz。在Ubuntu上,使用下面的命令行,你可以很容易就安裝好這一工具:
$ sudo apt-get install graphviz
清單11中的腳本遍歷了用戶的粉絲,然后再遍歷這些粉絲他們的粉絲。這一模式中的唯一真正不同之處在于 GraphViz的DOT格式文件的構(gòu)造,GraphViz使用簡(jiǎn)單的腳本格式來(lái)定義圖形,這些圖形作為你列舉的Twitter用戶的組成部分出現(xiàn)。如清單所展示的那樣,可以簡(jiǎn)單地通過(guò)指定節(jié)點(diǎn)的關(guān)系來(lái)定義圖形。
清單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 "}"
在某個(gè)用戶上執(zhí)行清單11的腳本,得出的結(jié)果放在一個(gè)dot文件中,接著使用GraphViz來(lái)生成圖像。首先調(diào)用Ruby腳本來(lái)收集圖形數(shù)據(jù)(存儲(chǔ)成graph.dot);接著使用GraphViz來(lái)生成圖像(這里用的是circo,該工具指定了一種圓形的布局)。生成圖像的過(guò)程定義如下:
$ ./followers-graph.rb MTimJones $ circo graph.dot -Tpng -o graph.png
最終得出的圖像如圖4所示。需要注意的是,由于這一Twitter圖表可能會(huì)很大,因?yàn)槲覀兺ㄟ^(guò)盡量減少要列舉的用戶及其粉絲的數(shù)目來(lái)限制圖表的規(guī)模(通過(guò)清單11中的:count選項(xiàng))。
圖4. Twitter粉絲圖例子(極端情況的子集)
位置信息
在功能啟用的情況下,Twitter收集你和你發(fā)出tweet消息的地理位置數(shù)據(jù)。這些由經(jīng)度和緯度信息組成的數(shù)據(jù)能夠用來(lái)精確地定位用戶的位置或者是tweet消息從何處發(fā)出。此外,把搜索和這些消息結(jié)合在一起,你就可以根據(jù)已定義的位置或是你所處的位置來(lái)識(shí)別出某些地方或是某些人。
并非所有的用戶或是tweet消息都啟用了地理位置功能(出于隱私原因),但這一信息是所有Twitter體驗(yàn)當(dāng)中的一個(gè)非常吸引人的方面。讓我們來(lái)看一個(gè)腳本,該腳本允許你可視化地理定位數(shù)據(jù),還有另一個(gè)腳本允許你使用這一數(shù)據(jù)來(lái)進(jìn)行搜索。
第一個(gè)腳本(清單12所示)抓取用戶的經(jīng)度和緯度數(shù)據(jù)(回想一下清單2中的邊界框(bounding box)),盡管邊界框是一個(gè)定義代表了用戶區(qū)域的多邊形,但我做了簡(jiǎn)化,只用了這一區(qū)域中的一個(gè)點(diǎn)。有了這一數(shù)據(jù),我在一個(gè)簡(jiǎn)單的HMTL文件中生成了一個(gè)簡(jiǎn)單的JavaScript函數(shù),這一JavaScript代碼與Google Maps接口,給出了這一位置的一個(gè)俯視地圖(給出提取自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í)行起來(lái)很簡(jiǎn)單:
$ ./where-am-i.rb MTimJones
最終得出的HTML文件可以通過(guò)瀏覽器來(lái)渲染,像這樣:
$ firefox test.html
如果沒(méi)有可用的位置信息的話,這一腳本就會(huì)執(zhí)行失敗;不過(guò)如果執(zhí)行成功的話,就會(huì)生成一個(gè)HTML文件,瀏覽器可以讀入該文件來(lái)渲染出地圖。圖5給出了最終生成的地圖圖像,其顯示了美國(guó)科羅拉多州北部Front Range的部分地區(qū)。
圖5. 清單12中的腳本渲染圖像的例子
有了地理位置,你還可以通過(guò)搜Twitter來(lái)識(shí)別出與某個(gè)特定位置相關(guān)聯(lián)的Twitter用戶和tweet消息。Twitter搜索API允許使用地理編碼信息來(lái)限定搜索結(jié)果。下面清單13中的例子提取用戶的經(jīng)度和緯度,然后使用這些數(shù)據(jù)獲取該位置方圓5公里之內(nèi)的所有tweet消息。
清單13. 使用經(jīng)度和緯度數(shù)據(jù)來(lái)搜索局部地區(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消息的一個(gè)子集。
清單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ù)深入
本文給出了一些簡(jiǎn)單的腳本,這些腳本使用Ruby語(yǔ)言來(lái)從Twitter中提取數(shù)據(jù),文章的重點(diǎn)放在用來(lái)說(shuō)明一些基本概念的腳本的開(kāi)發(fā)和演示方面,但我們能做的遠(yuǎn)不止于此。例如,你還可以使用API來(lái)瀏覽你的朋友的網(wǎng)絡(luò),并找出你感興趣的最受歡迎的Twitter用戶。另一個(gè)吸引人的方面是對(duì)tweet消息本身進(jìn)行挖掘,使用地理位置數(shù)據(jù)來(lái)了解基于位置的行為或是事件(比如說(shuō)流感暴發(fā))。本文只是做了一個(gè)淺顯的介紹,請(qǐng)?jiān)谙旅骐S意發(fā)表你的評(píng)論,附上你自己的各種混搭程序。Ruby和Twitter gem把為數(shù)據(jù)挖掘需要開(kāi)發(fā)有用的混搭應(yīng)用程序和儀表盤工具的工作變得很容易。
標(biāo)簽:普洱 梧州 遼寧 三沙 永州 公主嶺 張家界 荊門
巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《編寫Ruby腳本來(lái)對(duì)Twitter用戶的數(shù)據(jù)進(jìn)行深度挖掘》,本文關(guān)鍵詞 編寫,Ruby,腳,本來(lái),對(duì),Twitter,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問(wèn)題,煩請(qǐng)?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無(wú)關(guān)。