▍前言
程序員之間往往會(huì)這樣互相調(diào)侃:「所謂編程,只不過是調(diào)用各種 API 罷了」。雖是略帶自嘲意味的說法,但事實(shí)確實(shí)如此,不論是被稱為「程序員入門的第一行代碼的 print("hello world") 」還是擁有復(fù)雜交互邏輯的應(yīng)用軟件,API 都在其中扮演著至關(guān)重要的角色。
▍API 是什么
API(Application Programming Interface,應(yīng)用程序編程接口),它是一些預(yù)先定義的函數(shù),目的是提供應(yīng)用程序與開發(fā)人員基于某軟件或硬件得以訪問一組例程的能力,而又無需訪問源碼或理解內(nèi)部工作機(jī)制的細(xì)節(jié)。我們可以用一個(gè)生活中的例子來理解,假設(shè)家里突然斷電了你會(huì)怎么做?我想大部分人都是直接撥打「電工的電話號(hào)碼」,只需簡(jiǎn)單描述下問題,然后告訴他自己的地址,接下來的修復(fù)工作就交給專業(yè)的電工來完成即可。
在這個(gè)過程中,「撥打電工號(hào)碼」這個(gè)動(dòng)作相當(dāng)于調(diào)用一次 API,向其傳入「維修」「地址」等參數(shù),能夠得到「電力恢復(fù)正常」的結(jié)果,而「電工上門維修」則是這條 API 封裝的功能,這個(gè)例子可以寫一個(gè)偽代碼表示:
def 撥打電工號(hào)碼(目的, 地址): # 電工上門 # 電工維修 return "電力恢復(fù)正常"
每當(dāng)出現(xiàn)電力故障時(shí),我們只需要調(diào)用「撥打電工號(hào)碼」這個(gè)函數(shù)就可以將電力恢復(fù)正常,而無需了解電工上門使用的交通工具和具體的維修過程,API 的概念與此類似,在使用過程中我們關(guān)注的只有兩點(diǎn):
- API 的端點(diǎn)和參數(shù)
- API 的功能(能達(dá)到的目的)
除了上文提到過的「庫」和「函數(shù)」之外,平日里我們說到 API,大部分時(shí)候指的是服務(wù)端與客戶端通信的一種模式,比如:RESTful、GraphQL、gRPC,它們就像是無形的「絲線」,編織起了互聯(lián)網(wǎng)的基礎(chǔ)。
RESTful、GraphQL、gRPC 都是用于設(shè)計(jì)和實(shí)現(xiàn) API 的方式,目的是提供一種標(biāo)準(zhǔn)化的方法來定義和訪問服務(wù)或資源。它們都基于網(wǎng)絡(luò)協(xié)議(如 HTTP 或 HTTP/2)進(jìn)行通信,使用特定的數(shù)據(jù)格式(如 JSON、Protocol Buffers)來傳輸數(shù)據(jù),為服務(wù)提供者和消費(fèi)者之間提供了一種約定和規(guī)范,促進(jìn)了系統(tǒng)的互操作性和松耦合性。
至于 API 能為我們帶來什么效率提升自然不必多說,相信大家在少數(shù)派看過不少使用「API」做文章的高級(jí)技巧了,尤其是作者們基于 Notion API 實(shí)現(xiàn)各種自動(dòng)化功能,著實(shí)令人眼花繚亂。
不過授人以魚不如授人以漁,讀完這篇文章,你也一定能制作出屬于自己的效率工具!
▍捕獲 API
API 雖然無形,可你一定能感知到它們的存在,每當(dāng)我們輕車熟路地點(diǎn)擊一個(gè)「按鈕」或者敲擊一次「回車」,其后都有數(shù)條細(xì)小的絲線將你需要的內(nèi)容準(zhǔn)確無誤地匯聚到瀏覽器窗口之中。這就意味著只要能捕獲這些「絲線」,即使不借助瀏覽器也能獲取需要的資源。
那么該怎么「捕獲」這些絲線呢?主要有三種方法:
- 查看官方 API 文檔
- 使用 F12 觀察網(wǎng)頁特點(diǎn)
- 使用抓包工具
查看官方 API 文檔
首選的方式當(dāng)然是查看各大平臺(tái)的官方網(wǎng)站是否提供 API 文檔,比如 Notion、和風(fēng)天氣、訊飛語音都具備詳盡的開發(fā)者文檔,官方貼心地提供了 API 的詳細(xì)說明,包括如何進(jìn)行認(rèn)證、可用的端點(diǎn)(Endpoints)、請(qǐng)求的參數(shù)、請(qǐng)求和響應(yīng)的格式以及錯(cuò)誤代碼的含義等。
在閱讀官方文檔時(shí)需要關(guān)注以下幾點(diǎn):
- 認(rèn)證機(jī)制:大多數(shù) API 都需要經(jīng)過某種形式的認(rèn)證,比如 bearer token ,可用于標(biāo)注用戶身份以及訪問的合法性。
- 端點(diǎn)作用:了解每個(gè) API 端點(diǎn)的作用,注意其 URL、請(qǐng)求方法、必需和可選參數(shù)、以及返回的數(shù)據(jù)結(jié)構(gòu)是正確使用 API 的關(guān)鍵。
- 響應(yīng)格式:了解 API 的錯(cuò)誤響應(yīng)格式和常見錯(cuò)誤代碼,這對(duì)于調(diào)試和異常處理至關(guān)重要。
- 訪問限制:為避免高并發(fā)導(dǎo)致的服務(wù)器壓力,大部分平臺(tái)均設(shè)置了 API 調(diào)用限額與訪問頻次,提前注意這些信息能避免服務(wù)被意外中斷。
注意以上幾點(diǎn),能夠顯著加速開發(fā)過程,減少猜測(cè)工作,并幫助你避免常見的錯(cuò)誤。
使用 F12 觀察網(wǎng)頁特點(diǎn)
理想很美好,現(xiàn)實(shí)很殘酷,并非所有平臺(tái)都會(huì)貼心地為你附上一篇詳細(xì)的 API 文檔,平臺(tái)方自然是出于服務(wù)器壓力、可維護(hù)性等方面的考量,這就需要使用其他途徑捕獲 API。
現(xiàn)代瀏覽器內(nèi)置的開發(fā)者工具是探索和理解網(wǎng)頁工作原理的寶庫,它們?cè)试S開發(fā)者查看網(wǎng)頁的 HTML 結(jié)構(gòu)、CSS 樣式、JavaScript 代碼以及網(wǎng)絡(luò)請(qǐng)求和響應(yīng)。你可以在開發(fā)者工具中打開「網(wǎng)絡(luò)(Network)」面板,刷新頁面以開始捕獲網(wǎng)絡(luò)請(qǐng)求。頁面刷新后,網(wǎng)絡(luò)面板會(huì)列出所有發(fā)出的網(wǎng)絡(luò)請(qǐng)求,包括 API 的調(diào)用、圖片、腳本、CSS 文件等,使用面板頂部的過濾器可以縮小關(guān)注點(diǎn),在本篇內(nèi)容你只需關(guān)注「Fetch/XHR」請(qǐng)求即可,這里面通常包含與 API 交互的相關(guān)請(qǐng)求。
點(diǎn)擊任何一個(gè)請(qǐng)求,你將看到該請(qǐng)求的詳細(xì)信息,這也是一條網(wǎng)絡(luò) API 請(qǐng)求通常會(huì)包含的內(nèi)容:
- 請(qǐng)求方法(HTTP Method):常見的請(qǐng)求方法有 GET、POST、PUT、DELETE 等,用于指定對(duì)資源的操作類型。
- 請(qǐng)求 URL(Request URL):指定請(qǐng)求的目標(biāo)資源的地址,包括協(xié)議、域名、端口號(hào)(可選)和路徑。
- 請(qǐng)求頭(Request Headers):包含一些附加信息,如:
Accept:指定客戶端可接受的響應(yīng)內(nèi)容類型。
Content-Type:指定請(qǐng)求體的內(nèi)容類型。
Authorization:用于身份驗(yàn)證和授權(quán)。
User-Agent:提供客戶端的相關(guān)信息。
Cookie:包含之前服務(wù)器設(shè)置的 Cookie 信息。
請(qǐng)求體(Request Body):對(duì)于 POST、PUT 等請(qǐng)求方法,請(qǐng)求體包含要提交給服務(wù)器的數(shù)據(jù),格式可以是 JSON、XML、表單數(shù)據(jù)等。
- 查詢參數(shù)(Query Parameters):對(duì)于 GET 請(qǐng)求,查詢參數(shù)附加在 URL 的末尾,以鍵值對(duì)的形式提供額外的數(shù)據(jù)。
純理論未免有些晦澀,下面是一個(gè)實(shí)際的例子:
假設(shè)我想使用少數(shù)派的 API 做一些自動(dòng)化的工具,而官方又沒有提供 API 文檔的情況下,此時(shí)就可以使用 F12 打開「開發(fā)者工具」一探究竟,從中找出需要的內(nèi)容,
在「開發(fā)者工具」選中「Network」下的「Fetch/XHR」標(biāo)簽,使用少數(shù)派的搜索功能搜索一個(gè)關(guān)鍵詞。
上圖所列出的就是這個(gè)網(wǎng)頁背后的「絲線」,你在頁面上看到的所有數(shù)據(jù)(譬如文章數(shù)量、文章標(biāo)題、文章概要以及右側(cè)邊欄的熱門文章)都是通過這些「絲線」進(jìn)行傳遞的。
隨便點(diǎn)進(jìn)其中一條 API 的詳情頁,可以看到完整的 URL 為:
??https://sspai.com/api/v1/search/article/page/get?free=1&title=%E6%B5%8F%E8%A7%88%E5%99%A8&stime=0&offset=0&limit=8??
遺憾的是官方并沒有提供詳細(xì)的使用文檔,具體的功能和使用方式還得觀察和測(cè)試之后才能得知。
在 URL 規(guī)范中「?」用于區(qū)分路徑和參數(shù),「?」前面代表的是請(qǐng)求的基本網(wǎng)址,即 ??https://sspai.com/api/v1/search/article/page/get??,這是由開發(fā)者定義的 API 端點(diǎn),通過英文單詞也可知道其功能是搜索文章,并且需要使用「get」方法。而「?」后用「&」區(qū)分的就是一個(gè)個(gè)傳遞給服務(wù)端的參數(shù),具體的參數(shù)列表如下:
- free=1:這個(gè)參數(shù)的意義暫時(shí)未知,不過從單詞意思來看的話,可能用于判斷文章是付費(fèi)內(nèi)容還是免費(fèi)內(nèi)容。
- title=%E6%B5%8F%E8%A7%88%E5%99%A8:這是搜索的關(guān)鍵詞,但正如上文所述 URL 不能直接包含中文,所以這是編碼后的字符,我們可以使用一些在線工具解碼,可以發(fā)現(xiàn) %E6%B5%8F%E8%A7%88%E5%99%A8 是 「瀏覽器」三個(gè)字的 URL 編碼形式。
- stime=0:這個(gè)參數(shù)可能表示搜索的開始時(shí)間,0 可能表示從最早的記錄開始搜索。
- offset=0:這個(gè)參數(shù)可能表示分頁。
- limit=8:這個(gè)參數(shù)可能是用于限制返回結(jié)果的數(shù)量,這里設(shè)置為最多返回 8 篇文章。
先稱贊一下少數(shù)派網(wǎng)站的開發(fā)者,API 的可讀性不錯(cuò),我們僅憑單詞釋義就將這條 URL 的功能猜了個(gè)七七八八,不過至于猜的到底對(duì)不對(duì)呢,這里推薦使用 Postman 測(cè)試,使用方法也很簡(jiǎn)單,只需要填寫基礎(chǔ)網(wǎng)址,改動(dòng)幾個(gè)參數(shù)的值就能輕松發(fā)送請(qǐng)求和查看響應(yīng),上面還剩下幾個(gè)不確定的參數(shù)就留給讀者朋友們自己測(cè)試?yán)病?/p>
知曉 API 的參數(shù)和功能之后我們就可以使用 API 做一些有趣的事情,這里我編寫了一個(gè)簡(jiǎn)單的示例代碼(適用于 windows)用于獲取少數(shù)派的首頁文章,各位可以在本地建立一個(gè)名為:test.txt 的文件,將代碼拷貝至其中。
@echo off SetLocal EnableDelayedExpansion set "outputFile=titles.txt" powershell -Command "$response = Invoke-RestMethod -Uri 'https://sspai.com/api/v1/article/index/page/get?limit=10&offset=0&created_at=0'; $titles = $response.data | ForEach-Object { $_.title }; [array]::Reverse($titles); $titles" > %outputFile%
保存后將該文件的后綴名改為 bat ,直接點(diǎn)擊 test.bat 你就可以得到一個(gè)包含最近十篇首頁文章標(biāo)題的 titles.txt 文件。
使用抓包工具
網(wǎng)頁端我們可以使用 F12 進(jìn)行抓包,可占據(jù)了互聯(lián)網(wǎng)半壁江山的 app 卻很少提供相應(yīng)的 web 版本,所以如果想在移動(dòng)端 app 上捕獲 API 就要借助一些抓包工具,比如安卓端的 Fiddler、蘋果端的 Stream。不過與直接在瀏覽器的開發(fā)者工具中查看網(wǎng)絡(luò)響應(yīng)不同,使用抓包工具需要手動(dòng)配置 CA 證書才能捕獲 HTTPS 的流量。
這是由于二者捕獲數(shù)據(jù)的原理有差異,我們都知道 HTTPS 傳輸?shù)氖羌用芎蟮臄?shù)據(jù),而抓包工具本質(zhì)上是捕獲網(wǎng)絡(luò)中傳輸?shù)臄?shù)據(jù)包(網(wǎng)絡(luò)層),以分析網(wǎng)絡(luò)通信過程中的數(shù)據(jù)交換細(xì)節(jié),直接抓包只能看到加密后的數(shù)據(jù)。而開發(fā)者工具中則是在查看瀏覽器已經(jīng)解密之后的 HTTPS 通信數(shù)據(jù)(應(yīng)用層),因?yàn)闉g覽器作為受信任的客戶端已經(jīng)與服務(wù)器建立了安全的 TLS 連接。
所以需要額外安裝抓包工具的證書,這樣,抓包工具就可以作為中間人解密來自手機(jī)的數(shù)據(jù)包,再加密后發(fā)送給服務(wù)器;同時(shí)也能解密服務(wù)器的響應(yīng),再加密后發(fā)送回手機(jī)。具體細(xì)節(jié)此處不細(xì)探討,有關(guān) HTTPS 的更多知識(shí)推薦看 B 站的這個(gè)視頻:「HTTPS 是什么?加密原理和證書,SSL/TLS 握手過程」。
看不懂沒關(guān)系,大部分抓包 app 都在下載時(shí)貼心地準(zhǔn)備了安裝證書的教程,以蘋果端的 Stream 為例,初次打開軟件便會(huì)提示你需要安裝 CA 證書。
接著按照上圖流程,在「設(shè)置 - 通用 - VPN 與設(shè)備管理」中安裝下載的描述文件(對(duì)應(yīng)的描述文件的名稱中包含「CA」字樣),安裝完成后還需在「設(shè)置 - 通用 - 關(guān)于本機(jī) - 證書信任設(shè)置」中將該證書設(shè)置為信任。
提示:盡量選擇你信任的抓包軟件,隨意安裝 CA 證書可能會(huì)帶來風(fēng)險(xiǎn)。
配置完成后,只要按下「開始抓包」按鈕,此期間產(chǎn)生的網(wǎng)絡(luò)交換信息都可以輕松捕捉到。
通過以上三種途徑足以捕獲大部分平臺(tái)的 API 信息,之后我們就可以使用這些API實(shí)現(xiàn)效率提升,下面便是一個(gè)實(shí)際的例子。
▍巧用 API 打造「私人信息中心」
在信息爆炸的時(shí)代,我們常常面臨著一個(gè)困境:海量的信息散落在各大平臺(tái),如微博、知乎、少數(shù)派等。每天,我們都需要在這些平臺(tái)之間不斷切換,以獲取自己感興趣的內(nèi)容。這無疑耗費(fèi)了大量的時(shí)間和精力,降低了信息獲取的效率。
面對(duì)這種情況,我們迫切地需要一種更高效、更便捷的信息獲取方式。一個(gè)理想的解決方案是:在個(gè)人筆記或博客的一個(gè)頁面中聚合多個(gè)平臺(tái)的熱門內(nèi)容,實(shí)現(xiàn)信息的一站式瀏覽。
說到這,相信大家心里一定有想法了:如果能夠抓取各大平臺(tái)的熱門文章 API,從接口獲取對(duì)應(yīng)的熱榜信息,是不是就能實(shí)現(xiàn)一個(gè)「私人信息中心」呢。
當(dāng)然每個(gè)人的興趣各異,常逛的論壇也不同,那么第一步就是需要獲取你感興趣的平臺(tái)中與「熱門文章」有關(guān)的 API。
以知乎為例,通過瀏覽其網(wǎng)頁版發(fā)現(xiàn),熱榜信息會(huì)在「首頁 - 熱榜」這一標(biāo)簽下展示,打開 F12 觀察一下這個(gè)網(wǎng)頁的特點(diǎn)。
我們發(fā)現(xiàn)熱榜信息是通過這條 API 獲取的:
??https://www.zhihu.com/api/v3/feed/topstory/hot-lists/total??
觀察一下「Headers」中的信息,可以發(fā)現(xiàn)該 API 使用的是 「GET」方法,附加的參數(shù)也很簡(jiǎn)單,只有兩個(gè):
- limit - 返回的結(jié)果數(shù)量
- desktop - 是否為桌面端
不過直接訪問 API 的話只能得到一個(gè)復(fù)雜的 JSON 格式的數(shù)據(jù),在 Postman 查看返回值能知道其大致結(jié)構(gòu)如下:?
{ "data": [ { "target": { "id": 1234567890, "title": "文章標(biāo)題", "url": "https://api.zhihu.com/questions/1234567890", // 其他字段 }, // 其他字段 }, // 更多數(shù)據(jù)項(xiàng) ] }
試想一下,「私人信息中心」中最需要的是什么數(shù)據(jù)?必不可少的是今日熱榜的標(biāo)題和鏈接,換成 HTML 中的表達(dá)來說就是一個(gè)具有 href 屬性和文本的標(biāo)簽:
/ *這是一條熱榜信息的基本單元* / <a href="https://baidu.com" target="_blank" rel="nofollow">百度</a>
接下來就要從 API 的返回值中獲取我們需要的信息:標(biāo)題和鏈接,從上文的 JSON 中可以看到標(biāo)題信息保存在 data.target.title ,這一部分我們直接獲取即可,但data.target.url中的鏈接格式卻不是很理想,回到網(wǎng)頁端的知乎,我們隨便點(diǎn)擊一條熱榜查看該頁面的地址欄,可以看到有效的 URL 格式為:
??https://www.zhihu.com/question/1234567890??
所以還需將JSON的對(duì)應(yīng)字段轉(zhuǎn)為正確可訪問的 URL。
此外,返回值里面還有很多有趣的信息,比如熱榜的概要、熱度、圖片等,如果你需要的話,也可以獲取這些內(nèi)容。
下面是一個(gè)使用 nodejs 寫的一個(gè)示例:?
const axios = require('axios') async function getZhihuHotList() { const hotList = {} let num = 0 const response = await axios.get('https://www.zhihu.com/api/v3/feed/topstory/hot-lists/total') const data = response.data.data data.forEach((ele) => { hotList[num] = { title: ele.target.title, link: ele.target.url.replace("api","www").replace("questions","question") //將 URL 替換為正確可訪問的地址 } num += 1 }) return hotList }
以上代碼可以將知乎 API 的返回值精簡(jiǎn)為一個(gè)只包含標(biāo)題和鏈接的 JSON,以供后續(xù)使用。接下來各位可以嘗試自己獲取一下少數(shù)派和微博的熱榜數(shù)據(jù)。
前文的例子中我們已經(jīng)編寫了一個(gè) test.bat 文件用于獲取少數(shù)派的首頁文章,在其中使用的 API 端點(diǎn)為:https://sspai.com/api/v1/article/index/page/get,但其實(shí)少數(shù)派也有一個(gè)「熱門」板塊,不過我更關(guān)注的是近期「首頁」的文章,所以選擇了這條 API。
獲取這些必要的信息后,我們就可以在個(gè)人博客中搭建一個(gè)「私人信息中心」頁面,將這些內(nèi)容整合在一起方便日常瀏覽。我使用的是 Trilium 筆記的 Ankia 博客系統(tǒng),下文便以此為例。
Trilium 是一款開源可部署的筆記軟件,擁有一個(gè)可運(yùn)行的 nodejs 環(huán)境;
Ankia 是一款基于 Trilium 的博客主題,能夠直接將 Trilium 中的筆記轉(zhuǎn)換為博客。
- Trilium 是一款開源可部署的筆記軟件,擁有一個(gè)可運(yùn)行的 nodejs 環(huán)境;
- Ankia 是一款基于 Trilium 的博客主題,能夠直接將 Trilium 中的筆記轉(zhuǎn)換為博客。
Trilium 支持直接運(yùn)行 nodejs 環(huán)境的代碼,那么把上文中的示例稍微修改一下,并將精簡(jiǎn)后的 JSON 保存在一個(gè)名為「今日熱榜」的筆記屬性中。
然后通過 EJS 模板獲取 「今日熱榜」筆記中的相關(guān)屬性,將其渲染為通用的 HTML。
<h1>知乎熱榜</h1> <ul> <% zhihuHotList.forEach(function(item) { %> <li><a href="<%= item.link %>" target="_blank" rel="nofollow"><%= item.title %></a></li> <% }); %> </ul>
輔以 EJS 模板的渲染,最終實(shí)現(xiàn)的效果如下:?
最后一步,既然聚合是各大平臺(tái)熱榜,那么定時(shí)更新熱榜信息也是重要的一環(huán),在 Trilium 中可以輕松實(shí)現(xiàn)腳本的定時(shí)運(yùn)行,只需在腳本筆記添加:#run=hourly 屬性就可以讓其每小時(shí)自動(dòng)運(yùn)行一次,以確保信息的及時(shí)有效。
當(dāng)然,以上只是一個(gè)簡(jiǎn)單的示例,這是你的「私人信息中心」,可以根據(jù)自己的需求對(duì)其進(jìn)行擴(kuò)展和定制,比如增加更多的內(nèi)容源、添加分類和標(biāo)簽功能、優(yōu)化頁面樣式等。
▍結(jié)語
在網(wǎng)絡(luò)世界,API 就像是一把潛行者的「利刃」,讓我們?cè)跀?shù)字世界游刃有余,無論是通過查閱官方文檔,還是使用 F12 開發(fā)者工具和抓包軟件,我們都可以發(fā)現(xiàn) API 的蹤跡,稍微思考一番,你也可以利用它們來實(shí)現(xiàn)自己的創(chuàng)意。
最后,請(qǐng)?jiān)谧袷胤煞ㄒ?guī)的前提下爬取和使用 API,作者不鼓勵(lì)或支持任何違反法律的行為,做到尊重他人的知識(shí)產(chǎn)權(quán),保護(hù)用戶的數(shù)據(jù)安全和隱私,不從事任何違法犯罪活動(dòng)是每一個(gè)網(wǎng)民應(yīng)該遵守的基本原則。