上一篇我們完成所有預定要呼叫API的程式,但因爲寫法結構導致不好管理,此篇會透過函式進行模組化,減少重覆的程式碼。
承 【筆記】用Python呼叫API (三):完成剩下的呼叫API 的內容
首先導入需要的套件
import requests
import json
from datetime import datetime
from bs4 import BeautifulSoup
API跟爬蟲畢竟不是一樣的東西,寫法不同,沒有重複部分,所以還是會分開寫
接著,定義函式(Function):
# 定義名為usdt_twd_api的函式,這個函式可以接收三個數據
# 分別是url、headers、body,其中headers、body可以是空的
def usdt_twd_api(url, headers=None, body=None):
# 如果headers是空的,傳空字典
if headers is None:
headers = {}
# 如果body是空的,傳空字典
if body is None:
body = {}
if body:
# 如果body不是空的,requests使用post
response = requests.post(url, headers=headers, json=body)
else:
# 如果body是空的,requests使用get
response = requests.get(url, headers=headers)
# 因為GET跟POST的請求都是定義為response,所以無論是透過GET還是POST請求,都會返回到 response
return response
這裡我們用了def跟return,先透過def定義一個函式,函式回傳的結果可以透過return存在response,這個架構可以處理呼叫get、post方法的api,但我們這次只使用到get方法就是了
接下來,把請求的網址放上來:
# 定義一個變數名為 api_array,它用來放各個網址的陣列
api_array = [
{
"name": "ACE",
"url": "https://ace.io/polarisex/oapi/v2/list/tradePrice",
"headers": None,
"body" : None
},
{
"name": "MAX",
"url": "https://max-api.maicoin.com/api/v2/tickers",
"headers": None,
"body" : None
},
{
"name": "BitoPro",
"url": "https://api.bitopro.com/v3/tickers/usdt_twd",
"headers": None,
"body" : None
},
]
這裡用了陣列,呼叫由上到下依序呼叫,這樣如果需要加或是改,只要改這個位置就可以了
再來就是呼叫API跟處理每個API需要取出的值:
def process_response(api_name, data):
# ACE,USDT/TWD的資料結構處理
if api_name == "ACE":
specific_value = data.get("USDT/TWD").get("last_price")
return specific_value
# MAX,USDT/TWD的資料結構處理
if api_name == "MAX":
specific_value = data.get("usdttwd").get("last")
return specific_value
# BitoPro,USDT/TWD的資料結構處理
if api_name == "BitoPro":
specific_value = data.get("data").get("lastPrice")
return specific_value
#如果api_name 不是ACE、MAX、BitoPro,回傳None
return None
把所有三個交易所幣對價格取出的值都放在specific_value,底下加一個防呆,如果不是設定的三個交易所回None,因為如果不回任何東西,即便現在可能沒問題,但也會在未來某天修改別的地方時,出現不可預期的錯誤
接下來要開始把數據印出來了,先放上時間:
# 獲取當下時間
current_time = datetime.now()
# 格式化當下時間並印出
formatted_time = current_time.strftime("%Y-%m-%d %H:%M:%S")
print(f"\n請求時間:{formatted_time}\n")
這塊都沒改,就不講了
再來利用for迴圈逐一讀取api_array 這個我們上面放網址的陣列:
# 利用for迴圈遍歷api_array內的url、headers、body
for api_info in api_array:
url = api_info["url"]
headers = api_info["headers"]
body = api_info["body"]
# 定義一個變數為response,它調用了usdt_twd_api函式,函式裡面執行了API請求
# 數據資料來源是api_array,已透過for迴圈撈過一輪,包含url、headers、body
response = usdt_twd_api(url, headers=headers, body=body)
定義了api_info為for的變數,根據設定,我們可以拿api_info來處理API的相關資訊,包含url、headers、body
接下來就是響應是否成功跟逐一印出資料:
# 如果程式狀態回應是200,那回應將會解析成json格式的數據,存在變數data中
if response.status_code == 200:
data = response.json()
# 定義一個變數,它調用了process_response函式,它是用來取值我們要的特定值
specific_value = process_response(api_info.get("name"), data)
# 檢查api_info中的name是否有ACE、MAX、BitoPro,如果有就進入那塊程式碼
if api_info.get("name") in ["ACE","MAX","BitoPro"]:
# 被轉成浮點數後,格式化限制為小數點三位
formatted_name="{:.3f}".format(float(specific_value))
# 印出api_info中name對應的值,分別是ACE、MAX、BitoPro,並印出設定小數點三位後的價格
print(f"{api_info.get('name')} 的USDT/TWD匯率: \n{formatted_name}")
else:
print("壞了,根本就不能用啊,ERROR CODE:",response.status_code)
ACE、MAX、BitoPro的數值會都需要格式化小數點三位的原因是,忘記是ACE還MAX,有些回傳的訊息如果小數點三位為0的話,會不顯示,為了好看,就都顯示三位,這樣長度就一樣了
最後再把前幾篇完成的爬蟲放在下面就完成了
# 獲取網頁的HTML內容
url = "https://rate.bot.com.tw/xrt?Lang=zh-TW"
response = requests.get(url)
html_doc = response.text
# 使用Beautiful Soup解析HTML內容
soup = BeautifulSoup(html_doc, 'html.parser')
# 找到該元素
element = soup.find('td', {'data-table': '本行即期賣出', 'class': 'rate-content-sight'})
# 提取出數字
number = element.text.strip()
formatted_number = "{:.3f}".format(float(number))
print(f"台灣銀行 的USD/TWD匯率:\n{formatted_number}\n")
結果: