昨天半夜高中社團學弟和他朋友弄了這個康熙字典體產生器,弄完之後跑來問我怎麼加入 meta ? 我心裡想你既然都知道你要弄的東西叫做 meta 了,怎麼會跑來問我? XD
總之我直接貼給他 logdown 的 <head />
裡面我看到的東西XD 。簡單來說,以前大家都知道加入適當的<meta>
tag 有助於幫助搜尋引擎辨認你的網站,並且 適時 地在使用者的搜尋結果中提供你的網站或者頁面。
不過隨著社群媒體 (Facebook、Plurk、Twitter等) 的普及,人們現在更關心一個問題: 我的網頁會如何被呈現在 Facebook 的轉貼連結上? 也就是說,網站主關心的是,如果有使用者把自己的網頁貼到 Facebook 上, Facebook 是不是能正確地抓取你網站上的圖片當作縮圖?是不是能正確地產生文章摘要和文章標題?
Read on →剛才在FB上看到這篇文章,我簡單摘錄一下它的開頭,各位朋友如果有興趣可以把它點開來詳閱:
對不起我不學經濟 不學法律 不學政治 不學社會社工 不是商管人才
我只能用做IC來比喻:小馬以總分"689"這麼優異的成績推甄上ICS組
並且選擇了類比IC的實驗室IC設計是這樣的
你在電腦上設計的電路,也就是你設計的晶片
必須要透過"下線"的流程,把設計圖送交晶圓廠代工
經過幾個月之後,晶圓廠會把製造好的晶片還給你
你拿到你設計的東西之後,再用實驗室的儀器進行量測
晶片製造是很貴滴,所以大家能夠使用的資源有限
.....全文
--from Development Tu 臉書
很多人看了這篇應該都大笑,但是老實說我看了笑不出來,因為我有類似的經驗。
碩二下的時候,雖然那時候已經發了paper,但是實驗驗證一直沒有著落,每個禮拜的 meeting都灰頭土臉,因為實驗又 fail了。老師要我找出原因,到底是模擬失真,還是製程沒做好,或者是光路沒架好?偏振態沒有調好?奈米手不靈敏?
大家看了這篇文章之後,應該也都知道失敗並不可恥,重點是要找出原因,讓後進者得以繼續延續研究的薪火。老實說到現在我還是不知道當時失敗的原因。這麼說來真的很可恥XD,我一直到剛才看完這篇文章才開始反省orz
一直沒找出原因,我就這樣每個禮拜重複一樣的過程,周一跑模擬,周二去中研院做device,晚上回新竹就開始進實驗室量,一直量到禮拜天,fail,然後又像鬼打牆般重複一樣的事情。
我看完這篇文章我覺得很慚愧。雖然我不是ICS組的,但是我確確實實跟文章中的小馬一樣,每次失敗之後,不思失敗的原因,卻一直把餅畫得更大,要我的指導教授相信我,這次不但不會失敗,而且消光比會更好,甚至不用奈米眼,用far-field都看得到!逆境使人堅強,作為一個研究生就像一個不倒翁一樣,越挫越勇。
後來,我畢業了,否則我可能到現在都還在對我的指導教授開空頭支票,然後後面的學弟妹為了阻止我霸佔實驗室資源,可能就只好到台北來靜坐在中研院物理所大廳......
然後多年之後我看到這篇文章,覺得背脊發涼。
最近因為自己經營的粉絲團要辦個抽獎活動,於是就面臨怎麼有效率地把符合資格者的名單列出來的問題。在我的例子裡,符合資格的條件是在有效的時間內,對某篇文章留言。
我想很多商家面對這種事情,一定是花錢請個工讀生或者所謂的「小編」自己把所有的名字複製貼上下來。這樣做不是不好,但是缺點有三
- 曠日費時,留言者動輒上百人
- 容易有人工上遺漏
- 你不確定 facebook 是否有把所有的留言都列出來
而我們身為碼農,怎麼可以讓自己做這種 dirty 的事情呢?用程式來解是一定要的。我第一個想到的方法是抓原始碼,看有沒有結構化的規律,用 regex 來抓就好,因為 Rubular 可以在網頁上解決,就不用 動刀動槍 的了。
但是當你把那一頁存下來之後,你會發現, WTF 根本沒有幾個字是明碼啊。
所以,我放棄了。接著我試著 Google 關鍵字,發現很多人教大家用 FGL 來抓資料。因為我知道 open graph 可以做到我想要做的事情,但是懶得學;但是我會 SQL ,所以看到可以用看起來跟 SQL 長得根本一樣的 FQL 來做,當然是高興的不得了。
但是,人生最厲害的就是這個 but ! FQL 已經停用了。 GG。只好學用 open graph 啦。
使用 open-graph 取得名單
要取得某個粉絲頁(page)特定文章(post)的按讚或者留言者名單,首先你得先知道兩個資訊:
- 該 page 的 Facebook Page ID
- 該 post 的 Post ID
首先粉絲頁的 ID 可以在「關於」頁面的最下面找到。
接著 post id 可以用許多方法找到。
這時候我們就用打開 Facebook 的 API explorer 啦!第一次使用必須要先按一下 Get Access Token,隨意勾選一些項目後,就可以授權讀取資料。
接著我們先試著將剛才得到的 Page ID 代入 open graph 的路徑之下:
此時回傳資料會列出這個粉絲頁的一些諸元。接著我們就要試著探索這個粉絲頁下面的貼文。首先可以試試看
1494556507449732/posts
那麼就會列出前幾篇貼文,還有詳細的推文資料等等。其中我們感興趣的是post id,可以在這裡找到:
另外一個可以找到 post id 的地方當然就是貼文的網址啦!
如果是從網址抓來的話,那你要餵給 open graph 的形式就會變成是
1494556507449732_1541869892718393
總之就是用一個底線隔開啦!
接著事情就簡單了,如果你要查的是該貼文按讚的名單,就是
1494556507449732_1541869892718393/likes
如果要查留言的名單,就是
1494556507449732_1541869892718393/comments
最後,如果回傳資料不是全部的話,可以加上 ?limit=100
這樣就可以指定回傳的數量了。
總之就是如果要抓回該篇貼文的按讚名單,我們就是去詢問這個 open graph
http://graph.facbook.com/1494556507449732_1541869892718393/likes
取出留言者
有了這個 json 檔案之後,最理想的方法當然就是直接用支援 json 的語言去開它。但是如果剛好手邊沒有任何程式語言的平台可以用的時候(例如一台野生的 Windows 電腦...),用網頁工具也是一個好主意。我自己第一個想到的是我很常拿來練習 regex 的網頁工具: Rubular。
方法一: 用 regex
首先把 json 裡面的資料全部貼到網頁上,接著我第一個想到的策略是寫一個「中文或者英文」的條件去抓「名字」,後來又補上了.
和-
也可以。
/"name": "([\s\u4e00-\u9fa5]+|[\w\s\-\.]+)"/
看起來成效不錯,但是居然有漏網之魚!原來有的按讚者是用日文、阿拉伯文...當名字。沒辦法,只好用更骯髒的方式了:
/{\s+"id": "\d+",\s+"name": "([\w\W]{2,30})"\s+}/
嗯,這是連初學者都寫得出來的格式,就只是限制字數而已,但是最重要的是它可行!
方法二: 用 Ruby 讀 json
當然如果手上有 Ruby 或者 Python 當然還是直接對付 json 最快啦。
不囉唆,我的解法如下
# encoding=utf-8
require 'open-uri'
require 'json'
url = 'http://graph.facebook.com/pageid_postid/likes?limit=200'
json = open(url) # download the json file
data_hash = JSON.parse(json.read) # parse the json into hash
data_hash["data"].each do |datum|
puts datum["name"]
end
因為按讚者是包在 data
之中的巢狀結構,所以我寫了一個 each do 去把它們逐一印出來。
如果要印的是「留言者」名單,除了 url 要把 likes
改成 comments
之外,程式的部分請把迴圈部分改為
data_hash["data"].each do |datum|
puts datum["from"]["name"]
end
References
上禮拜辦了一個活動,完全用 facebook 的活動 (event)功能邀請賓客;活動前一天我想要印出賓客清單,才發現 facebook 居然沒有把賓客名單匯出成 .csv 的功能..... 我記得以前有啊?
這種時候就只好動用 facebook 強大的 opengraph API了。opengraph 的 EDGE 除了可以是一個人,一個fan page之外,也可以是一個活動。
取得 event 相關資訊前,要在申請 access token 前額外要求要 event 的權限:
話不多說,來看 code:
# encoding=utf-8
require 'open-uri'
require 'json'
event_id = '1609895432567499'
token = STDIN.read
url = 'https://graph.facebook.com/v2.3/' \
+ event_id + '/attending/?limit=250'
url = url + '&access_token=' + token
json = open(url)
data_hash = JSON.parse(json.read)
data_hash["data"].each do |datum|
puts datum["name"]
end
執行
ruby list_attendees.rb < token > guests.csv
即可
其中 < token
是利用 standard input 將我放在另一個檔案的 token 吃進來; > guests.csv
就是把列印出來的內容存到csv檔裡面。
同場加映
繼上一篇印出 facebook 活動賓客名單,同場加映一下,這次我們把 EDGE 由活動換成社團,印出全部社團成員,並且隨機排列,給他們一個亂數編號。
原先我的想法是按照賓客的長度創照一個連續自然數陣列,再利用 ruby 內建的 shuffle
洗牌,但是這樣名單印出來就是亂的。例如:
nums = 1..16
nums = nums.to_a.shuffle
後來想到一個更簡單的做法,就是直接把成員名單的順序打亂就好。實作如下:
# encoding=utf-8
require 'open-uri'
require 'json'
group_id = '67226335296474'
token = STDIN.read
url = 'https://graph.facebook.com/v2.3/' \
+ group_id + '/members/?fields=name&limit=250'
url = url + '&access_token=' + token
json = open(url)
data_hash = JSON.parse(json.read)
nums = 1..data_hash["data"].size
data = data_hash["data"].shuffle
for t in nums
datum = data[t-1]
puts t.to_s + "\t" + datum["name"]
end
執行
ruby get_members.rb < token
其中 token
放有你的 access token。
如此就會印出洗牌過的成員名單,並加上一個照順序印出的編號了。