此文選自知乎大佬
https://www.zhihu.com/question/38594466/answer/122391324
https://zhuanlan.zhihu.com/p/30742302
1.知乎上優秀解釋
API(接口)是什么?舉個常見的例子,在京東上下單付款之后,商家選用順豐發貨,然后你就可以在京東上實時查看當前的物流信息。京東和順豐作為兩家獨立的公司,為什么會在京東上實時看到順豐的快遞信息,這就要用到API,當查看自己的快遞信息時,京東利用順豐提供的API接口,可以實時調取信息呈現在自己的網站上。除此,你也可以在快遞100上輸入訂單號查取到快遞信息。只要有合作,或是有允許,別的公司都可以通過順豐提供的API接口調取到快遞信息。既然有多方調用,那提供一個統一的調用規范會方便很多。
我們看下百度是怎么給出API的定義的:
API(Application Programming Interface,應用程序編程接口)是一些預先定義的函數,目的是提供應用程序與開發人員基於某軟件或硬件得以訪問一組例程的能力,而又無需訪問源碼,或理解內部工作機制的細節。
API翻譯成中文就是"應用程式介面",其實這樣翻譯不好,應該說是"程式溝通介面"。
翻譯為介面,顧名思義就要溝通兩個不同的東西用的,通常由一組函式庫所組成。
在一個 同一個平台 下的 兩個不同東西(程式 or 系統),為了能取用對方的功能等等,
所以一個 X程式 寫了一組函式,讓 同一平台的其他程式 取用 X程式 的功能,
那組函式就可以說是那個 X程式 對外開放的 API。
從百度定義中,我們先划下重點:函數、 提供應用程序與開發人員 、無需訪問源碼、例程 。注意這四個短語。其中,例程是某個系統對外提供的功能接口或服務的集合,本文着重說下API的數據服務功能接口。
首先,下面的文章我會先演示怎么通過瀏覽器,不需要編程、不需要訪問源碼,來調用免費的API接口,達到讓你怎么使用最簡單的接口;
然后,會演示怎么通過編程去調用接口;
最后,演示開啟WEB服務,寫一個簡單的API接口,以體現出API的函數 (y=f(x)) 功能。
你也可以復制代碼試下。通過你自己的嘗試,你會了解到些后端、前段的東西,並加深你對API的理解。那么我們就開始吧,先上一個圖:以API提供信息(數據)的功能,看下數據是怎么流動的。如果給API一個具體的位置的話,就位於下圖中央。
為了更改的理解,我穿插一個故事角色。假如,世界太大,身處非洲大陸的你想去看看,成為了一個水手,被一位著名的航海家帶去去遠航(你掌握着船上唯一一台衛星電腦),途中不免航海家會讓確定下城市的經緯度。這時航海家讓你去確定下深圳市的經緯度。
1、你是個人肉API
這時,你能想到簡單的辦法就是去百度搜索一下。 除了航海家,船上的高級水手、大副,估計都有可能向你問,這個時候,其實你就是一個接口,大家都來向你獲取地理位置信息,作為接口,你本身不產生信息,你只是信息的搜集者、傳遞者,提供人肉數據服務。
2、使用免費的經緯度API接口
在百度搜索的過程中,眾多網友給出的經緯度不一致,你要反復對比,去辨真偽。時間長了,你可能會覺得大家都問位置,太煩了,我這個人肉API效率太慢,有沒有更快的方式。
這時你發現了一個阿里雲的一個免費的API接口:http://gc.ditu.aliyun.com/geocoding?a=深圳。你在瀏覽器地址欄輸入了這個URL,果然得到了正確的經緯度,你又把URL中的深圳改為了別的城市,發現也可以查到。這時,通個這個接口,你給大伙確定位置的效率大大提升。
3、你不滿足於此
你覺得這個接口太好了,剛好你會點Python,何不寫點代碼,注意這個時候你的角色發生了變化:你由一個人肉API轉變了一個開發人員(注意這個是百度API定義中的關鍵詞),你現在的目標是寫代碼,能夠自動獲取到這個某個地方的經緯度。
#python import requests r = requests.get("http://gc.ditu.aliyun.com/geocoding?a=深圳") loc = r.json() print loc #打印出的結果:{u'alevel': 4, u'lon': 114.05786, u'level': 2, u'cityName': u'', u'address': u'', u'lat': 22.54309} # 與在瀏覽器輸入地址的結果一致 print "深圳的經度是%s,緯度是%s" % (loc["lon"], loc["lat"]) #打印出的結果是:深圳的經度是114.05786,緯度是22.54309
到這里,我們再來回顧下API的百度定義。目前,你作為一個開發人員, 具備通過寫了幾行代碼訪問“阿里雲經緯度接口”的能力, 你無需訪問這個API的源碼、不需要理解這個API是怎么弄成的 。也就是,不管是通過瀏覽器,還是編程語言,目前你已經會用簡單的API了。
4、在會用簡單API的接口后,你進一步想知道它的內在機制是什么
建立在會用的基礎之上,那么API的源碼、其內在機制是怎么回事?目前你能調用經緯度的API,簡單的獲取到位置還不夠,你可能自己想寫一個API接口,不緊緊提供位置信息,同時附加上對這個城市的介紹。
利用Python的tornado模塊,搭建一個web服務。我們建一個腳本空文件 web_server.py,把以下代碼復制進去
# -*- coding: utf-8 -*- import sys reload(sys) sys.setdefaultencoding('utf-8') import tornado.ioloop import tornado.web import json import requests lists = {u"深圳": "是經濟特區,緊鄰廣州,接壤香港,人口約1200萬", u"青島": "旅游城市,瀕臨黃海,特產啤酒,人口約920萬" } def get_loc(city): r = requests.get("http://gc.ditu.aliyun.com/geocoding?a=%s" % city.encode('UTF-8')) loc = r.json() return "經度是%s,緯度是%s" % (loc["lon"], loc["lat"]) class BaseHandler(tornado.web.RequestHandler): def get_current_user(self): return self.get_secure_cookie("user") class MainHandler(BaseHandler): def get(self): if self.request.arguments.has_key("id"): greeting = self.get_argument('id', 'Hello') if greeting in lists: self.write(greeting + ": " + str(get_loc(greeting)) + "," + str(lists[greeting])) else: self.write("none") settings = dict(cookie_secret="P1/V61oETzdkLmGeJJFuYh7Eo5KXQAGaYgEQnp2XdTo=", debug=True) application = tornado.web.Application([(r"/", MainHandler), ], **settings) if __name__ == "__main__": application.listen(8888) tornado.ioloop.IOLoop.current().start()
執行web_server.py,執行后就會開啟一個web服務
接着,我們在瀏覽器輸入http://192.168.199.204:8888/?id=深圳
注意,我自己的電腦局域網IP是192.168.199.204,需要替換成你自己電腦(或虛擬機)的ip
從上圖看,我們實現了,和”阿里雲經緯接口“的相同功能,並且獲取到了除經緯度,還有對城市的簡單描述。隨着航行越來越多,你讓船上的大伙不僅了解了地理位置信息,也了解了每個城市的經濟人文情況。隨着信息數據的增多,特別需要一個東西能先把數據先保存起來,用到的時候,API再直接調用。
5、數據儲存,調我所需
上面我們模仿了阿里雲的API,自己搭建了一個web服務,提供額一個更為詳細的API地理位置信息服務。現在想一下,我們的代碼里只有深圳、青島兩個城市,還有很多沒提到的城市,另外,城市還有經濟發展情況、飲食文化等。我們把深圳、青島兩個城市信息存入到mysql里。
存入之后,我們從mysql里直接拿數據,通過API直接展現在到瀏覽器中。改動 web_server.py腳本中的
# -*- coding: utf-8 -*- import sys reload(sys) sys.setdefaultencoding('utf-8') import tornado.ioloop import tornado.web import json import requests import MySQLdb.constants def get_mysql(sql_string): conn = MySQLdb.connect(host='localhost', port = 3306, user = 'root', passwd = '123456', db = 'test', charset = 'utf8') cursor = conn.cursor() cursor.execute(sql_string) resultList = {} for data in cursor.fetchall(): city_name = data[0] city_introduce = data[1] resultList[city_name] = city_introduce return resultList cursor.close() conn1.close() def get_loc(city): r = requests.get("http://gc.ditu.aliyun.com/geocoding?a=%s" % city.encode('UTF-8')) loc = r.json() return "經度是%s,緯度是%s" % (loc["lon"], loc["lat"]) class BaseHandler(tornado.web.RequestHandler): def get_current_user(self): return self.get_secure_cookie("user") class MainHandler(BaseHandler): def get(self): if self.request.arguments.has_key("id"): greeting = self.get_argument('id', 'Hello') lists = get_mysql("select name,introduce from test.city where name ='%s' " % greeting.encode('UTF-8')) #直接從mysql里讀取城市信息,特別注意這里的SQL if greeting in lists: self.write(greeting + ": " + str(get_loc(greeting)) + "," + str(lists[greeting]))