<div class="titleLev1">
# Python程式存取RESTful API</div>
<div class='fonts'>
難度:<span class='beginner'><i class="fa fa-star"></i><i class="fa fa-star blur"></i>入門++</span>
## <span class='titleLev2'>Python程式內索取(request)RESTful API資料和存檔的程序</span>
1. 先安裝requests模組:
><font color=#BA9653> pip install requests</font>
>[color=#BA9653]
2. Python程式必須先`import requests`,然後使用`requests.get("<API url>")`方法,傳入參數為API的url(網址),傳回值就是API所提供的資料。可以將這個傳回值賦給一個變數,例如response。
3. 如果傳回的資料是個JSON文件,那簡單,`response.text`或者`response`本身就是文件內容。下面程式示範:
* 透過requests模組索取API的JSON文件^a)^;
* API資料抓回來後,直接顯示其內容。^b)^;
* 藉助Python standard library的json模組中的`json.loads()`方法,將JSON字串decode為Python內設資料型態^c)^;
* 調用`json.dump()`方法存檔^d)^;
* 存檔之後再開檔^e)^;
* 採取`json.load()`方法解碼以及`print()`出內容^f)^,以驗證存檔後的文件,和最初從API傳回的JSON資料是否一致。
檔案讀寫都運用Python的json模組,不以一般文字檔讀寫方式處理。
```python=
import requests
import json # Python處理JSON文件的standard library。
# a) 透過requests模組索取API的JSON文件。
# 本例向International Space Station(ISS, 國際太空站)索取該站目前位置經緯度。
response = requests.get("http://api.open-notify.org/iss-now.json")
issPositionText = response.text
# b) API資料抓回來後,直接顯示其內容。目前內容仍存在記憶體變數中,未存檔。
print()
print('b) API資料抓回來後,直接顯示其內容。目前內容仍存在記憶體變數中,未存檔。')
print('issPositionText:')
print(issPositionText)
print()
# c) 藉json模組的method將JSON字串decode為Python內設資料型態(dict/list等)。
issPositionJsonDoc = json.loads(issPositionText)
print('------------')
print('c) 藉json模組的method將JSON字串decode為Python內設資料型態(dict/list等)。')
print('issPositionJsonDoc:')
print(issPositionJsonDoc)
print('type(issPositionJsonDoc): ' + str(type(issPositionJsonDoc)))
print()
# d) 調用json.dump()方法存檔。
fileName = 'D:/Python/ExcelReadWrite/issPosition.json'
jsonFile = open(fileName, 'w', encoding='utf-8')
# 下面這列json.dump(jsonDoc, jsonFile, ensure_ascii=False)的意思是:
# "Serialize jsonDoc as a JSON formatted stream to jsonFile"。
# 序列化(serialization)在計算機科學的資料處理中,是指將資料結構或物件狀態
# 轉換成可取用格式(例如存成檔案,存於緩衝,或經由網絡中傳送),以留待後續在
# 相同或另一台計算機環境中,能恢復原先狀態的過程。
json.dump(issPositionJsonDoc, jsonFile, ensure_ascii=False)
jsonFile.flush() # dump()之後,欲存檔的內容其實暫存於記憶體中,並未
# 真正寫入檔案,要flush()才會正式寫入。
jsonFile.close() # 存檔完成記得關檔。
# e) 開檔。
jsonFile = open(fileName, 'r', encoding='utf-8-sig')
# f) 利用json.load()方法解碼以及print()出內容。
issPositionFileContent = json.load(jsonFile)
jsonFile.close() # 用完記得關檔。
print('------------')
print('f) 利用json.load()方法解碼以及print()出內容。')
print('issPositionFileContent:')
print(issPositionFileContent)
print()
```
以上程式輸出如下:
![](https://i.imgur.com/vdtO9JU.png =620x)
4. <font color=red>**【作業】**</font>但如果API傳回的是圖片,該如何處理?
```python=
# -*- coding: utf-8 -*-
import requests
# 從API取得圖像。
response = requests.get("https://image.tmdb.org/t/p/w500/x6LOGUWNHH3pRO8gOup68xPJL46.jpg")
# a) 圖片抓回來後(這時尚未存檔,圖片是存在變數response中),如何在程式中顯示?
# b) 如何存檔?最少要能存jpg, png, gif, bmp四種格式。
# c) 如何開啟圖檔?
# d) 如何顯示圖檔?
```
要有如下的效果:
a) 圖片抓回來後尚未存檔,存在變數response中。請在程式中用系統預設的工具顯示,如能指定工具更佳:
![](https://i.imgur.com/LfHF6An.png =400x)
\
d) 外部圖檔開啟後顯示之。下圖的確是外部圖檔,可是檔名並不正確,而且不管原檔是哪一種圖形格式,顯示時都是.BMP。這問題我暫時無解,有賴各位研究改進。
![](https://i.imgur.com/geMbik4.png =400x)
###### tags: `JSON` `RESTful API` `API`
<style type="text/css">
/* @import url('https://fonts.googleapis.com/css?family=Inconsolata&display=swap');
*/
body {
}
.deepRed{
color: #8B0000;
}
.magentaBold {
color: #FF00FF;
font-weight: bold;
}
#b {
color: #00008B;
}
#r {
color: #8B0000;
}
.b {
color: #00008B;
}
#dk {
color: #1E90FF;
}
.t {
color: #FF6347;
font-size: 110%;
font-weight: bold;
}
.r {
color: red;
font-weight: bold;
}
#cg120 {
color: #008248;
font-weight: bold;
font-size: 120%;
}
.classA {
color: #66E141;
font-weight: bold;
font-size: 130%;
}
.classB {
color: #41C6E1;
font-weight: bold;
font-size: 130%;
}
.classC {
color: #E1B141;
font-weight: bold;
font-size: 130%;
}
.highlight {
color: red;
font-weight: bold;
font-size: 120%;
}
.PK {
color: #E6005C;
font-weight: bold;
font-size: 115%;
}
.FK {
color: #FF8C69;
font-weight: bold;
}
.dot {
color: #DAA520; //#8B4513;
font-weight: bold;
font-size: 125%;
}
.smalldot {
color: #4CDA21;
font-weight: bold;
font-size: 125%;
}
.hi {
color: #E6005C;
font-weight: bold;
//font-size: 115%;
}
.tableTitle {
color: #B22222; //000080
font-weight: bold;
text-align: center;
}
.HeYeLv {
color: #1A6840;
// #008248;
}
.YingWuLv {
color: #5BAE23;
}
.ShenZhuYue {
color: #3C69A6;
}
.HaiQing {
color: #22A2C3;
}
.lightRed {
color: #DC143C;
font-weight: bold;
}
.Bloody {
color: #7E2723;
}
.bloody180 {
color: #7E2723;
//A63732;
font-weight: bold;
font-size: 180%;
}
.Fei {
color: #D15B3A;
}
.DaHong {
color: #FF2121;
}
.QiuHaiTangHong {
color: #EC2B24;
}
.CuiLv {
color: #20A162;
}
.MuGuaHuang {
color: #F9C116;
}
.JieHuang {
color: #D9A40E;
}
.CangHuang {
color: #806332;
}
.ChiHong {
color: #C3272B;
}
.Red {
color: #FF0000;
}
.Magenta {
color: #FF00FF;
}
.lightBack {
background-color: #FFFF99;
}
.beginner {
/* color: #008248; */
color: #20A162;
font-weight: bold;
}
.adv {
/* color: red; */
/* color: #D9A40E; */
color: #FF4C00;
font-weight: bold;
}
.pro {
/* color: #A63732; */
color: #801DAE;
font-weight: bold;
}
.fonts {
font-family: Inconsolata, Consolas, Ubuntu Mono, mononoki, Iosevka, Fantasque Sans Mono, agave, Fira Code, ProggyVector, Office Code Pro, Menlo, monospace, Noto Sans TC, Gen Jyuu Gothic P, 細明體;
}
.font-Ubuntu {
font-family: Ubuntu Mono, Inconsolata, Iosevka, Fantasque Sans Mono, mononoki, agave, Fira Code, ProggyVector, Office Code Pro, Menlo, Consolas, monospace, Noto Sans TC, Gen Jyuu Gothic P, 細明體;
}
.titleLev1 {
color: #2A2C4B;
font-family: Ubuntu Mono, Inconsolata, Iosevka, Fantasque Sans Mono, mononoki, agave, Fira Code, ProggyVector, Office Code Pro, Menlo, Consolas, monospace, Noto Sans TC, Gen Jyuu Gothic P, 細明體;
font-weight: bold;
font-size: 110%;
text-align: center;
}
.titleLev2 {
color: #B54C3F;
font-family: Ubuntu Mono, Inconsolata, Iosevka, Fantasque Sans Mono, mononoki, agave, Fira Code, ProggyVector, Office Code Pro, Menlo, Consolas, monospace, Noto Sans TC, Gen Jyuu Gothic P, 細明體;
font-weight: bold;
font-size: 120%;
}
.titleLev3 {
color: #22A2C3;
font-family: Ubuntu Mono, Inconsolata, agave, mononoki, Iosevka, Fantasque Sans Mono, Fira Code, Menlo, Noto Sans TC, Gen Jyuu Gothic P, 細明體;
font-weight: bold;
font-size: 115%;
}
.titleLev4 {
color: #7E5E83;
font-family: Ubuntu Mono, Inconsolata, Iosevka, Fantasque Sans Mono, mononoki, agave, Fira Code, ProggyVector, Office Code Pro, Menlo, Consolas, monospace, Noto Sans TC, Gen Jyuu Gothic P, 細明體;
font-weight: bold;
font-size: 110%;
}
.titleLev5 {
color: #207F4C;
font-family: Ubuntu Mono, Inconsolata, Iosevka, Fantasque Sans Mono, mononoki, agave, Fira Code, ProggyVector, Office Code Pro, Menlo, Consolas, monospace, Noto Sans TC, Gen Jyuu Gothic P, 細明體;
font-weight: bold;
font-size: 108%;
}
.titleLev6 {
/* color: #5E878A; */
color: #C89B40;
font-family: Ubuntu Mono, Inconsolata, Iosevka, Fantasque Sans Mono, mononoki, agave, Fira Code, ProggyVector, Office Code Pro, Menlo, Consolas, monospace, Noto Sans TC, Gen Jyuu Gothic P, 細明體;
font-weight: bold;
font-size: 108%;
}
.Walrus {
color: #FF2121;
font-family: Inconsolata, Ubuntu Mono, mononoki, Consolas, Noto Sans TC, Gen Jyuu Gothic P, 細明體;
font-size: 1500%;
font-weight: bold;
}
.blockquote {
color: #1BA1E2;
font-size: 100%;
line-height: 18px;
}
.great {
color: #E50000;
/* font-weight: bold; */
}
.awful {
color: #008989;
/* font-weight: bold; */
}
.QA {
color: #1C3A90;
}
.myImg {
margin-left: auto;
margin-right:auto;
display: block;
}
.font500 {
font-weight: bold;
font-size: 500%;
}
.font300 {
font-weight: bold;
font-size: 300%;
}
.font200 {
font-weight: bold;
font-size: 200%;
}
.font150 {
font-weight: bold;
font-size: 150%;
}
.font130 {
font-weight: bold;
font-size: 130%;
}
.font125 {
font-weight: bold;
font-size: 125%;
}
.font120 {
font-weight: bold;
font-size: 120%;
}
.font115 {
font-size: 115%;
}
.font110 {
font-size: 110%;
}
.font108 {
font-size: 108%;
}
.font105 {
font-size: 105%;
}
.font100 {
font-size: 100%;
}
.font96 {
font-size: 96%;
}
.font94 {
font-size: 94%;
}
.font90 {
font-size: 90%;
}
.font88 {
font-size: 88%;
}
.font86 {
font-size: 86%;
}
.font82 {
font-size: 82%;
}
.font80 {
font-size: 80%;
}
.font75 {
font-size: 75%;
}
.font70 {
font-size: 70%;
}
.font65 {
font-size: 65%;
}
.font60 {
font-size: 60%;
}
.font50 {
font-size: 50%;
}
.trim {
margin-left: 0px;
margin-right: 0px;
broder: 0px;
padding: 0px;
}
.bold {
font-weight: bold;
}
.blur {
opacity: 0.20;
}
.statement {
color: #22A2C3;
}
.func {
color: #806332;
}
.str {
color: #EC2B24;
}
.filename {
color: #1A6840;
}
.codeFont {
font-size: 110%;
font-weight: bold;
}
.hiBold {
font-size: 110%;
font-weight: bold;
color: #EC2B24;
}
.markdown-body code { /* inline code */
font-family: Inconsolata, Ubuntu Mono, Consolas, Iosevka, Fantasque Sans Mono, mononoki, agave, Fira Code, ProggyVector, Menlo, Inconsolata, monospace, Noto Sans TC, Gen Jyuu Gothic P, 細明體;
font-size: 100%;
/* background-color: #EEEEEE; */
background-color: #E4E4E4;
}
.markdown-body pre code { /* code block */
font-family: Inconsolata, Consolas, Ubuntu Mono, Iosevka, Fantasque Sans Mono, mononoki, agave, Fira Code, ProggyVector, Menlo, Inconsolata, monospace, Noto Sans TC, Gen Jyuu Gothic P, 細明體;
font-size: 110%;
line-height: 16px;
}
.markdown-body {
max-width: 1500px;
}
.CodeMirror {
font-family: Inconsolata !important;
}
.borderlessTable {
border: 0;
}
.markdown-body table th, .markdown-body table td {
padding: 2px 3px 2px 5px !important;
// margin: 20px 30px 50px 10px !important;
border: 2px solid #ddd;
}
ul {
display: block;
/* list-style-type: disc; */
margin-block-start: 0.8em;
margin-block-end: 0.8em;
margin-inline-start: 0px;
margin-inline-end: 0px;
padding-inline-start: 15px;
padding: 0px;
}
.markdown-body ul, .markdown-body ol {
padding-left: 1em !important;
margin: 0 0 0 0;
}
</style>