[R] 臉書數據挖掘.初探


說是數據挖掘,其實這篇只涉及了簡單的查詢。
呃,所以說是「初探」。
本篇主要紀錄使用R來對FB上的社交資料進行查詢與存取的技術,參考來源是這篇,不過該文中的R code有一些意外的錯誤,這裡也會進行必要的修正。

臉書上的開發者工具裡頭有所謂的Graph API,他的Explorer介面底下你可以使用兩種方式來對FB上的社交資料——舉例而言,你的照片、照片裡tag了誰、誰留言留了什麼、有幾個人按讚……——進行查詢,第一種是直接使用位於畫面左側的使用者圖形介面,以滑鼠點選你想要查詢的東西然後提交就可以了;第二種方式則是使用FaceBook Query Language FQL(很明顯地,是SQL-like)撰寫查詢語法來取得結果集。

以上這兩種方法都跟本篇文章無關。(咦)
是,我們今天要走的路是以R這個語言來取用FB Graph API的結果集物件。
嗚喔,不知道R是什麼?R就是R,既不偉大也不卑微。

呃,重點是不論是使用哪種方式,我們必須要先取得access token,它是一組字串,代表特定的使用者或頁面等等的身分。在Explorer介面上可以取得這個字串,同時它會進一步問你開放授權那些資料讓Graph API來查詢。要注意的是,這個字串是有時效性的,一個小時後就會自爆失效。

而對Graph API作查詢後FB傳回的結果,基本上是一個JSON物件。如果你不知道什麼是JSON物件也沒關係,就把它當作傑森物件吧。(什麼啦)想要知道這些物件到底長什麼鳥樣,可以登入FB後進入官方的範例頁面,裡面的連結隨便挑一個點進去,那就是傑森物件大抵上的模樣。這裡的重點是,這些傑森物件(我最後一次用這個名字了!)本質上就是文字,並且都有對應放置的url,所以即使不經由Graph API Explorer的介面,我們還是可以取用他們,只要我們知道他們的結構。

訂立個簡單的目標,假設我現在想要把我個人相簿裡的所有照片都抓進桌面端,我們可以這樣做:



(沒錯我換了程式碼顯示的Hack!)

以下說明上面的程式碼。
前兩行是我個人的習慣,不解釋。

一開始,我用dir.create()在工作路徑下新建一個我要拿來放照片圖檔的資料夾。這邊小地方要注意的是如果不使用recursive=T這個引數那麼它只會新建最尾巴的資料夾,在這裡的話就是photos,如果母資料夾FBGraphAPI不存在R會直接擺爛給你。

我們會需要兩個Package,分別是專門用來處理url問題的RCurl,以及用來轉換JSON物件為R物件的rjson。接著前往Graph API Explorer頁面取得你的access token,記得勾選必要的授權否則會抓不到東西。以Photo tags這個物件來說需要的授權可以參考官方文件。因為我是到處亂玩所以基本上我全要了嘿嘿。

我們把這個很長很長很長的字串丟進一個R物件。注意在romainfrancois.blog.free.fr文章中作者將access token丟進access_token,但在他的facebook這個函數中access_token是用在命名引數,推測作者實際上想寫的應該是丟進token才對。小地方,自己注意就好。

接下來細看這個函數,由於這次的重點是在connections這一類的物件,所以我把路徑中"me"這個字串直接寫死,但把物件名稱變數化,然後用sprintf()這個古法(嗄)把他們作成路徑格式。

引數options在這次的例子中沒有採用所以先無視,它是url裡指定參數(以控制查詢內容)時才會用到的設定。

然後很簡單地,再次運用sprintf()把你有效的access token以及你想要查詢的物件拼成該物件放置的url,使用getURL()這個方法去取用其內容(就是JSON物件本身,也是你用同樣條件在FQL裡進行查詢時會得到的結果集),丟進R之後利用fromJSON()這個方法把她轉換成R語言環境底下的物件。啊對了,getURL要加上ssl.verifypeer=FALSE這個引數,否則八成會失敗,不要問為什麼,因為我不知道。

在romainfrancois.blog.free.fr文章中第二個有問題的地方,是getURL裡頭他寫死的路徑中沒有使用"?"而是使用"&"來連接access_token=,這會出問題。

完成函數後,叫用看看:
photos <- facebook(object="photos")
如果你檢視photos這個物件(使用mode()這個方法),會發現它是一個R list。更進一步說,它的長度length(photos)就是你的照片張數,如果你想知道你第一張照片的url,可以這麼做:
url <- photos$data[[1]]$source
如果你眼睛夠好也可以在R裡面使用str()來查看Photo tags這個物件的結構,不過這個list長的絕對不友善(好吧其實要看你現充的程度啦),建議你不必白費工夫想要去搞清楚它的所有結構了。好吧,我怎麼知道source這個元素就是照片的存放網址?因為我上了Graph API Explorer先對Photo tags這個物件作了一個簡單的查詢,稍微瀏覽了一下它的內容。(明明就是因為人家romainfrancois.blog.free.fr裡的文章已經告訴你了。)呃,總之,如果你不想用Explorer,也可以諮詢官方文件,一樣會有欄位說明,只是比較不有趣。 要把這張照片給下載到桌面端,可以這樣:
download.file(url, file.path("FBGraphAPI\\photos", basename(url)), mode="wb")
注意原文教學中並沒有使用mode="wb"這個引數,我猜作者不是使用Windows。Win使用者要下載非純文字檔,根據R的說明文件,要加上這個引數。你可以試試看不加會怎樣,基本上就是你下載下來的圖全部都會無法辨識。也還好。(喂)

來到最後了!簡單地說,使用sapply()對photos這個list上的所有source都執行下載的動作,就醬。



好吧,雖然洋洋灑灑寫了這麼多但是其實根本沒什麼內涵。
這算是小小的第一步吧!

大概會有第二步。

吧。

0 comment(s):

Post a Comment

回應文章前請注意下列三勿原則:

1)勿拍照;(→會有靈異的照片從你的相機裡跑出來...
2)勿餵食;(→會有飢渴的猛獸從我的網誌裡跑出來...
3)勿告白。(→會有奇怪的東西從站長體內裡跑出來...

謝謝大家的配合。
( > ー <)b