您好,我是碼農飛哥,感謝您閱讀本文!本文主要介紹Python中如何請求外部接口以及如何通過Flask架構定義接口。
文章目錄
- 引入requests庫
- Get請求
- Post請求
- 以form表單送出的方式
- 請求方
- 接收方
- 以json字元串的格式來送出
- 請求方
- 接收方
- 檔案上傳
- 請求方
- 接收方
- 三個接口的請求結果如下圖:
- 總結
引入requests庫
Python是通過requests庫來請求接口的,是以,首先需要通過pip安裝requests庫。
pip install requests==2.21.0
#檔案上傳才會用
pip install requests-toolbelt==0.9.1
說明:本文編寫的接口用到的是Flask架構關于Flask架構的使用請參考
Get請求
這裡以微信授權的接口為例。接口文檔如下;
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiATN381dsQWZ4lmZf1GLlpXazVmcvwFciV2dsQXYtJ3bm9CX9s2RkBnVHFmb1clWvB3MaVnRtp1XlBXe0xCMy81dvRWYoNHLwEzX5xCMx8FesU2cfdGLwMzX0xiRGZkRGZ0Xy9GbvNGLpZTY1EmMZVDUSFTU4VFRR9Fd4VGdsYTMfVmepNHLrJXYtJXZ0F2dvwVZnFWbp1zczV2YvJHctM3cv1Ce-cmbw5SM3UjN3ITOiVWZzEDZjZTYyYzXzIzNzMTMzEzLcZDMyIDMy8CXn9Gbi9CXzV2Zh1WavwVbvNmLvR3YxUjLyM3Lc9CX6MHc0RHaiojIsJye.png)
這是一個通過Get方式請求的接口,傳回類型是
application/json
,是以請求的代碼是:
# 引入庫
import requests,json
url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=123&secret=345"
# 請求接口
res = requests.get(url)
#對傳回的内容進行編碼
content = res.content.decode('utf-8')
#将json字元串反序列化
tokenJson = json.loads(content)
access_token = tokenJson['access_token']
代碼解釋:
-
就是發起Get請求,擷取響應值。res = requests.get(url)
-
因為content = res.content.decode('utf-8')
預設的類型是bytes類型的,是以需要進行解碼轉成str類型。隻有轉化之後才能被正确的反序列化。res.content
-
就是将Json字元串反序列了成字典,這個對象是一個dict,python與json的資料類型對應關系如下圖所示:tokenJson = json.loads(content)
Python中如何編寫接口,以及如何請求外部接口 -
擷取key為access_token的token值。access_token = tokenJson['access_token']
Post請求
Post請求方法同樣是一個非常常用的請求方法。Post請求的請求類型有三種:
-
這是以form表單的方式來送出post請求。application/x-www-form-urlencoded
-
這是以json字元串的格式,将請求參數放在RequestBody中的方式。application/json;charset=utf-8
-
form-data
這種方式一般是用來上傳檔案用的。
下面分别就這三種請求方式來編寫請求代碼:
以form表單送出的方式
請求方
def post_form_urlencoded():
url = "http://127.0.0.1:8080/v1/ls/voice/save"
data = {"dst_audio": "9d62ca66-326f-4070-9993-5f89f790dc68.wav"}
res = requests.post(url, data)
content = res.content.decode('utf-8')
print(content)
以form表單送出的post請求,隻需要把請求參數封裝到一個字典dict中進行傳入就可以了。這裡傳入了一個名為dst_audio的參數。不需要設定Content-Type。
如果我們的請求的接口的域名是https的位址的話,直接這樣寫的話會報 SSLError: HTTPSConnectionPool的問題。
解決的方法是:
res = requests.post(url, data=data, verify=False)
将verify參數設定為False。也就是不檢查SSL證書。
接收方
@ma.route('/v1/ls/voice/save', methods=['POST'])
def save():
group_uuid = uuid.uuid1()
dst_audio = request.values.get('dst_audio')
my_data = {
"video_id": group_uuid
}
return jsonify({'code': 0, 'msg': "儲存成功", 'data': json_data})
接收Form表單中的參數隻需要通過request.values.get(參數名) 來擷取。多個參數分别擷取。route裡定義了接口的路由位址,methods屬性指定接口的請求方法。其中jsonify函數是将dict序列化成json字元串,是flask架構的一個函數。
以json字元串的格式來送出
請求方
def post_json():
url = "http://127.0.0.1:8080/v1/ls/json"
x_header = {
'Content-Type': 'application/json; charset=utf-8',
}
body = json.dumps({"name": "張三", "age": 12})
res = requests.post(url, data=body, headers=x_header, timeout=10)
content = res.content.decode('utf-8')
print(content)
application/json請求類型的接口,需要将請求參數通過
json.dumps
方法序列化成一個Json字元串傳入給接口,然後,在請求頭中指定Content-Type為
application/json; charset=utf-8
。
調用post方法
requests.post(url, data=body, headers=x_header)
。其中:data 指定請求參數,headers指定請求頭。timeout 是指定逾時時間是10秒
接收方
@ma.route('/v1/ls/json', methods=['POST'])
def post_json():
if request.method == 'POST':
json_data_str = request.get_data().decode('utf-8')
json_data = json.loads(json_data_str)
return jsonify({'code': 0, 'msg': "請求成功", 'data': json_data})
接收請求體中參數隻需要調用
request.get_data().decode('utf-8')
方法,這裡必須要将其解碼,不然,中文會被編碼
{"name": "\\u5f20\\u4e09", "age": 12}
。
檔案上傳
請求方
from requests_toolbelt.multipart.encoder import MultipartEncoder
def post_form_data():
post_url = "http://127.0.0.1:8080/v1/ls/upload"
headers = {}
multipart_encoder = MultipartEncoder(
fields={
'file': (os.path.basename('D:\\test.txt'), open('D:\\test.txt', 'rb'), 'application/octet-stream'),
'file_name': '張三'
}
)
headers['Content-Type'] = multipart_encoder.content_type
post_response = requests.post(post_url, data=multipart_encoder, headers=headers, verify=False)
content = post_response.content.decode('utf-8')
print(content)
form-data請求類型的接口,一般是檔案上傳的接口,我們可以将參數封裝到MultipartEncoder對象中,在fields中定義一個字典,在這個字典中傳入多個參數。其中 file 參數指定需要上傳的檔案,通過
open('D:\\test.txt', 'rb')
方法讀取檔案的内容。并指定請求類型為
application/octet-stream
。file是參數名稱,需要按照接口方的定義傳入。
接收方
@ma.route('/v1/ls/upload', methods=['POST'])
def post_form_data():
temp_file = request.files['file']
file_name = request.values.get('file_name')
file_path = os.path.abspath('.') + "/" + "temp.txt"
temp_file.save(file_path)
return jsonify({'code': 0, 'msg': "請求成功", 'data': file_path})
檔案上傳的接口接收檔案是通過
request.files['file']
方式來接收的。