使用開放的 API 做一個自己的小專案,是一個很好的學習方法。但好像開放的 API 選擇並不多。這裡給大家多一個選擇,簡單介紹一下維基百科使用的 MediaWiki API。
簡介
先簡單介紹幾個容易混淆的概念。
Wiki
Wiki 是一種在網路上開放且可供多人協同創作的超文字系統。Wiki 站點可以由多人維護,不同人可以對同一個主題進行擴充和探討。
MediaWiki
MediaWiki 是一個免費、開放的 Wiki 引擎,很多著名的 wiki 網站都採用這套系統。
Wikipedia
我們常說的維基百科,一般是指 Wikipedia,它是基於 MediaWiki 的一個網路百科全書。
但要理解的是,除了 Wikipedia,還有很多別的 Wiki 站點。從這個角度考慮的話,維基(Wiki)也有可能是指別的網站,不過 Wikipedia 太出名了,以至於很多人直接將 Wikipedia 等同於 Wiki。
文件
在瞭解到維基百科的 API 是開放的之後,我就找到了官方的 API 文件,但以我目前的水平,這個文件幾乎完全看不懂。在網上找了很久,希望可以有一篇文章以中文看得懂的方式,告訴我這些 API 是怎麼用的,但很可惜並沒有。
沒辦法,自己對著官方文件琢磨了很久,勉強總結出一些比較常用的呼叫方法。希望本文可以讓你對 MediaWiki 的內容獲取有一個大概的瞭解,讓你能用它做出自己的專案。
本文所有內容都來自以下官方文件,如果能看懂,就不用再往下看啦。
為了方便理解,下面的說明都會有例子,用的是「灰機wiki」的「冰與火之歌中文維基」站點,域名是 asoiaf.huijiwiki.com,並通過 api.php 訪問。當然,只要是基於 MediaWiki 的 Wiki 站點,下面說明都是適用的。
action
介面中的 action 用來指定請求相應的動作,他的可取值非常非常多。我們這裡只考慮內容的獲取,不進行使用者管理、內容編輯等操作,所以只要知道一個值就行了,所有介面都是 action = query。query 就是代表獲取資料。
format
這個用來指定資料返回的格式,我們統一用 JSON 格式,即 format = json。
但我在使用過程中發現,返回的 JSON 資料很多都是用「*」號或者是數字作為欄位名的,解析起來很麻煩。這種情況下可以嘗試增加 formatversion = 2,讓返回的資料更正常一些,便於解析。
list
在 action = query 的情況下,會增加一些可用的引數,其中 list 是比較常用的一個。list 的可選值也很多,下面是幾個我認為比較常用的值。
allcategories
在對一個站點還不是很瞭解的情況下,我們可以先看一下它有哪些分類。list = allcategories 代表列舉出所有分類:
http://asoiaf.huijiwiki.com/api.php?action=query&format=json&formatversion=2&list=allcategories&aclimit=50
其中,aclimit 指定了返回的條目數量,預設值是 10,不能超過 500。
當資料存在下一頁的時候,返回的資料裡會有 continue 欄位,比如:
continue: {
accontinue: "Castle_Black",
continue: "-||"
}
複製程式碼
要獲取下一頁,把 accontinue 這個引數帶上就行:
http://asoiaf.huijiwiki.com/api.php?action=query&format=json&formatversion=2&list=allcategories&aclimit=50&accontinue=Castle_Black
categorymembers
現在我們知道有哪些分類了,接下來想看一下某個分類下有哪些內容,就要用到 categorymembers,它用於列出指定分類中的所有頁面。分類名傳入 cmtitle,需要包括「Category:」這個字首。
假如我想看一下「史塔克家族」有哪些頁面:
http://asoiaf.huijiwiki.com/api.php?action=query&format=json&formatversion=2&list=categorymembers&cmtitle=Category:史塔克家族&cmlimit=50
這裡控制返回數量的是 cmlimit,獲取下一頁的是 cmcontinue。
random
要是我想給使用者一種新鮮感,每次在首頁隨機展示一些內容,list = random 是你需要的,它用於隨機返回一些內容:
http://asoiaf.huijiwiki.com/api.php?action=query&format=json&formatversion=2&list=random&rnlimit=50&rnnamespace=0
rnlimit 控制返回的數量,預設是 1。同理,獲取下一頁要用 rncontinue。後面也是類似的。
這裡還有一個名稱空間 NameSpace 的概念。當 rncontinue = 0 代表指定返回的是頁面,rncontinue = 6 是檔案,rncontinue = 14 是分類,別的我還沒有用到過。
search
搜尋功能肯定是少不了的,我們用 list = search,將關鍵字傳給 srsearch 進行搜尋。
搜尋含有「史塔克」的頁面:
http://asoiaf.huijiwiki.com/api.php?action=query&format=json&formatversion=2&list=search&srsearch=史塔克&srnamespace=0&srlimit=10
目前我用到的 list 取值就這些。下面講一下另一個重要的引數。
prop
如果是要獲取某個頁面的相關資料,就涉及到 prop 這個引數。它用來指定要獲取的資料型別,它的可選值也很多,下面也挑幾個常用的說。
categories
這個用來獲取頁面所屬的所有分類,比如艾德·史塔克屬於史塔克家族,也屬於國王之手:
http://asoiaf.huijiwiki.com/api.php?action=query&format=json&formatversion=2&prop=categories&titles=艾德·史塔克&cllimit=20
images
除了文字描述,圖片也是內容裡的一個重要資訊,prop = images 用來獲取指定頁面的所有檔案。雖然是 image,但是它能獲取到各種檔案,包括視訊:
http://asoiaf.huijiwiki.com/api.php?action=query&format=json&formatversion=2&prop=images&titles=艾德·史塔克&imlimit=50
pageimages
prop = pageimages 也是用來獲取頁面圖片的,按我的理解,它是用來獲取頁面封面的。比如我們獲取「艾德·史塔克」的封面:
http://asoiaf.huijiwiki.com/api.php?action=query&format=json&formatversion=2&prop=pageimages&titles=艾德·史塔克&pithumbsize=500
pithumbsize 用來指定圖片的尺寸,預設只有 50 px。另外要注意,不是每個頁面都是有封面的。
revisions
接下來是最重要的獲取頁面內容了。revisions 文件解釋是用來獲取修訂版本資訊的,可以用來獲取最新的頁面資料。
我這樣來獲取「艾德·史塔克」的頁面資料:
http://asoiaf.huijiwiki.com/api.php?action=query&format=json&formatversion=2&prop=revisions&titles=艾德·史塔克&rvprop=content&rvparse=true
rvprop = content 表示需要返回頁面的文字內容。rvparse = true 表示將文字內容解析為 html,否則是純文字內容。
除了 content,rvprop 還有很多可選值,同時需要多種內容,可以用「|」分隔。比如同時返回修訂時間戳、修訂的使用者及修訂內容,可以這樣表示:rvprop=timestamp|user|content。
其實很多引數的取值都是支援使用「|」的,將多條資料一起返回。比如我們將上面提到的 prop 取值一次全部獲取到,可以這樣呼叫:
http://asoiaf.huijiwiki.com/api.php?action=query&format=json&formatversion=2&prop=categories|images|pageimages|revisions&titles=艾德·史塔克&rvprop=timestamp|user|content&rvparse=true
總結
上面介紹的這些只能算是接觸到 MediaWiki API 的一點皮毛而已,但我還是花了些時間才總結出來的。想要有很深入的瞭解,還是要去研究一下官方文件。
我用冰與火中文維基的介面寫了一個 Android App,叫「冰與火維基」,但還有一些沒優化好的地方,感興趣的可以在這裡下載到。