如何用 OG Data 取得在 Dcard iOS 文章中的網址縮圖和資訊
在我們開始之前,讓我們先來看看它在 Dcard 裡長什麼樣子吧!
原文網址被轉換成「縮圖」、「標題」與「描述」的 3 種不同呈現方式。
要取得這些資訊,最好的來源當然就是透過 Open Graph protocol 裡已經定義的資訊囉。Open Graph 的資料會呈現在<head> … <head>
之中,如下:
<meta property="..." content="..." />
其中,3 種呈現方式的 property
分別為 :
- 「縮圖」:
og:image
- 「標題」:
og:title
- 「描述」:
og:description
(其他的資料定義可以參考官方文件:http://ogp.me )
在 html 中呈現出來大概就會長的像下面這樣:
因此,我們的目標很明確了,我們需要寫段程式取出這些內容。
首先,在取得網頁的 html 內容後,我們需要一個 HTML 的解析器(parser)來從 html 中取得需要的內容。在這裡使用的是叫 Fuzi 的第三方套件(https://github.com/cezheng/Fuzi) ,它為 Swift 對 libxml2 做了封裝,讓整體更方便使用。
例如要取得標題的話,要讀取<meta property="og:title" content="The Rock" />
中 content
的內容,可以透過 XPath 對 html 查詢,用法如下:
其他的資訊也可以透過相同的方法取得,接下來就來把它封裝成一個好用的物件吧!
再來是封裝的部分,這部分就比較偏向個人需求了,所以接下來就比較按照 Dcard 的需求去設計。
- 由於網址資訊都是在呈現文章時使用的,同一時間還需要載入留言、圖片、推薦文章……等資訊,所以設計上希望可以避免大量的網址資訊在同一時間被載入,去競爭其他資源需要的網路流量。
- 除此之外,同樣的網址基本上不太會需要更新它的資訊,若能儲存在本機端下次就不用再重新抓取資料。
基於以上的需求,我們設計了以下的流程。
- 每次需要取得一個網址的資訊時,會將它包裝為一個請求的物件,其包含了「目標網址」以及一個「回調函式(callback)」。
- 在新的請求產生後,會先從資料庫(使用SQLite)中查詢是否已經有先前取得的資料,若存在則執行回調。
- 若該網址沒有抓取過,則會先被放進一個列隊中。若同時間處理中的請求少於限制,則會從列隊中取出下一個請求處理。
處理過程相當簡單。若能成功取得 HTML 的內容,則解析其中 Open Graph 的資料並寫入資料庫儲存。最後,不論成後與否,皆執行回調函式。流程如下:
最後,附上一個小小的測試專案(https://github.com/Dcard/OpenGraphCrawler),這個功能被封裝成一個叫 OpenGraphCrawler 的物件。
感謝大家閱讀。
By Dcard iOS Team
Dcard 廣大徵才中唷!
心動的朋友歡迎加入Dcard成為我們的夥伴請到 👉🏼 https://join.dcard.today/