【教學】Facebook SDK 二部曲:從Facebook抓取資料


這篇跟大家分享怎樣從Facebook撈金礦抓取資料。


需要準備:

1. 可以讓使用者登入Facebook的iOS App Project。
    可以從這篇:【教學】Facebook SDK 前傳:準備Social一下,開始做起。
2. 看看Graph API Guide,裡的影片會很有幫助。
3. 開啓Graph API explorer,取得uid及access_token。





那...要如何存取user在Facebook上的資料?

透過Graph API或FQL。




其實是兩個是一樣的 :p

FQL
The FQL object enables running FQL queries using the Graph API. Facebook Query Language, or FQL,
enables you to use a SQL-style interface to query the data exposed by the Graph API.
It provides for some advanced features not available in the Graph API.

由Facebook團隊自行開發的語言,讓使用者使用Graph API存取資料就像使用SQL語法一樣,其實還是在用Graph API,XD。


格式:SELECT [fields] FROM [table] WHERE [conditions]


只是FQL指令只有少少的SELECT, FROM, WHERE, IN, AND, NOT, ORDER BY, LIMIT, ORDER BY,看這裡


兩者使用方法很簡單,都可以用HTTP GET or POST直接對Graph API直接作存取,就像跟一個Web Server要資料一樣。



我們先來瞭解一下Graph API,後面就會變得簡單的多。


Graph取自Graph theory,Graph用來代表事物(node)與事物之間的特定關係(connection),Graph API照這理論來設計。



比如說:

Facebook上有我’’Linkin Park(id=8210451787)兩個物件(node)。
我’'讚'以前,我們兩個物件(node)是沒有任何關係(connection)的。
我’按完'讚'以後,我們兩個物件(node)就有'讚'(likes)的關係(connection)。
所以我’可以運用'讚'(likes)的關係(connection)中找到’Linkin Park(id=8210451787)。


要怎麼找到?
像這樣:https://graph.facebook.com/'node'/’connection'/'node'

試試看先按讚,再打開這網址(因為是直接用HTTP GET,要記得加上uid及access_token):

https://graph.facebook.com/me/likes?uid='你的uid'&access_token=
或是打開Graph API explorer在GET右邊的欄位輸入:‘me/likes'。



me指的是目前登入的使用者,likes(有's')是關係,後面會分享怎麼找到這層關係。


回傳的結果的是我’'讚'的內容,裡面會有’Linkin Park(id=8210451787)的資料。


要精確一點可以加上?target_id=8210451787:
https://graph.facebook.com/me/likes?uid='你的uid'&target_id=8210451787&access_token=

Graph API explorer可以輸入:'me/likes/8210451787'



每個不同的物件都有自己的屬性(field),如果想限定只回傳特定的屬性(field),就加上fields=???,???

https://graph.facebook.com/me/likes?fields=name&uid='你的uid'&access_token=
Graph API explorer可以輸入:'me/likes?field=name'


會傳回按過'讚'內容的名字跟id(固定會回傳)。



好像有點亂喔...


那就這樣記吧:
就三個參數:Node、Connection、Field。
使用Graph API都要從一個node開始,經由connection找到我們要的node或fields。

就這樣,可以用Graph API explorer玩看看!


你也可以看看4號使用者按了什麼讚。


4號是誰?就他啊:https://www.facebook.com/4



FQL跟Graph API


FQL是從table裡找field,Graph API是從node找connection跟field。


舉個例子比較容易瞭解怎樣操作。



我們要讀取已登入user的名字及生日資料,我們這樣做:

1. 找到生日,名字兩項所屬的欄位,
    使用Graph API:
    可以在這裡'Object'找到'user'物件,生日是叫做'birthday'Field,名字是'name'

    使用FQL:
    可以在這裡,找到'user'Table,生日是叫做'birthday'Column,名字是'name'


2. 打開Graph API explorer,
    使用Graph API:
    輸入‘me?fields=birthday, name’

    意思是:在目前使用者這個node找出他的birthday跟name的fields。


    使用FQL:
    按下'FQL Query'

    格式:SELECT [fields] FROM [table] WHERE [conditions]
    輸入:SELECT birthday, name FROM user WHERE uid=me()

    意思是:從找出符合uid=目前使用者的user Table,再找出birthday跟name。


也可在瀏覽器上試試:

Graph API:
https://graph.facebook.com/me?uid='uid'&fields=name,birthday&access_token=

FQL:https://graph.facebook.com/fql?q=SELECT+name,birthday+FROM+user+WHERE+uid=me()&access_token=


會得到的結果會是一樣的(但格式不一樣)。



Note:
a. 在使用FQL時也可以用me()來代替目前登入的使用者uid。
b. 在SELECT或WHERE可以加入IN為第二條件,但只能是有'indexable'屬性的field,文件上會標示星號。
c. Table有Column是indexable,代表可以用這個column找到某物件的table內容,
    比如目前使用者按讚的內容:SELECT object_id FROM like WHERE user_id=me()
    有按某照片讚的人的ID:SELECT user_id FROM like WHERE object_id=照片的ID



Coding Time !!!

再度的copy,Coding之前又要先說明一下:

我們會用的Class為FBRequest跟FBRequestConnection,兩者的關係有點像是NSURLRequest跟NSURLRequestConnection,一個負責傳遞要發送的訊息,一個負責發送。

不同的是,FBRequestConnection提供的方法可以直接設定訊息,應用各種情況,FBRequest大部份用在要傳送大量訊息的時候。

不管用Graph API或是FQL,只要掌握三個重點:

1. GraphPath:開始的地方,用Graph API看node,FQL一定從'fql'。
2. 參數:找什麼資料,多玩Graph API explorer就會了。
3. 輸入輸入,都用JSON,Facebook SDK很多Class都是JSON物件,不必拘泥。


我們用之前寫好的App來加強吧~!
這個App已經可讓使用者登入了!(嘿嘿)


多放兩個按鈕,一個FQL,一個Graph API。

都寫抓取目前使用者按讚的項目。


Graph API:

- (IBAction)graphAPIAction:(id)sender {
    
    [FBRequestConnection startWithGraphPath:@"me" parameters:@{@"fields":@"likes"} HTTPMethod:@"GET" completionHandler:^(FBRequestConnection *connection,
                            id result,
                            NSError *error) {
        NSLog(@"result : %@", result);
        self.showView.text = [NSString stringWithFormat:@"%@", result];
    }];

}


Graph API使用FBRequest和FBrequestConnection:

    FBRequest *request = [[FBRequest alloc] initWithSession:FBSession.activeSession graphPath:@"me"];
    FBRequestConnection *connection = [[FBRequestConnection alloc] init];
    [connection addRequest:request completionHandler:^(FBRequestConnection *connection,
                                                      id result,
                                                      NSError *error) {
        //  Will do this after call 'start' and response is back. (time out, too).
        NSLog(@"result : %@", result);
        self.showView.text = [NSString stringWithFormat:@"%@", result];
    }];
    [connection start];

FQL:

- (IBAction)fqlAction:(id)sender {



    NSString *command3 = @"SELECT object_id FROM like WHERE user_id=me()";
    NSDictionary *para3 = @{@"q" : command3};
    
    [FBRequestConnection startWithGraphPath:@"fql" parameters:para3 HTTPMethod:@"GET" completionHandler:^(FBRequestConnection *connection,
         id result,
         NSError *error) {
        NSLog(@"result : %@", result);
        self.showView.text = [NSString stringWithFormat:@"%@", result];
    }];

} 


好像有點快吼?


After Coding


那...上篇說好的[FBRequestConnection startForMeWithCompletionHandler:]呢?

這個...就跟[FBRequestConnection startWithGraphPath:@"me" parameters:nil HTTPMethod:@"GET" completionHandler:]是一樣的。

只是要注意的是,startForMeWithCompletionHandler:回傳物件是id<FBGraphUser>,
FBGraphUser會有設好的property可以用,但是他其實還是JSON物件,不用拘泥直接存取就好。


那...POST方法呢?

嗯~我們下篇再說XD



繼續奮鬥:

【教學】Facebook SDK 三部曲(上):點一下,分享到Facebook(這一定有什麼誤會!

 




參考文件:


FQL

FQL Guide

Permissions

Permissions Guide

Graph API

Graph API Guide


工具:


Graph API explorer


範例:


Fetch User Data

Run FQL Queries

留言

  1. 我想抓取facebook粉絲頁 某篇文章的 按讚、大心 的數量該怎麼做呢@@

    回覆刪除

張貼留言

這個網誌中的熱門文章

【給程式新手】陰魂不散的物件導向?

【教學】Facebook SDK 首部曲:登入Facebook(這是我的一小步...卻是人類...咦?這麼多人啊?)

【教學】Facebook SDK 前傳:準備Social一下