關於httpx模塊和requests模塊發送post請求的差異


網上介紹httpx和requests兩個模塊的資料不少,他們的優劣這里不談。

說下在實際使用中兩者參數的細微差別。

今天 研究人像轉動漫圖像的實現,沒用opencv實現,就找了百度的api來實現,官網有現成例子參考。

自己寫的實現代碼:

import json
import base64
import requests


# 獲取Access Token
url = 'https://aip.baidubce.com/oauth/2.0/token'
post_data = {
    'grant_type': 'client_credentials',
    'client_id': 'App Key',
    'client_secret': 'Secret Key'
}

access_token = None
response = httpx.post(url=url, data=post_data)
if response.status_code == 200:
    json_data = response.json()
    access_token = json_data['access_token']
    print(access_token)
    term_of_validity = json_data['expires_in']
    print(f'有效使用期為{term_of_validity}秒.[有效期30天]')

"""
打開圖片
base64編碼后大小不超過10M(參考:原圖大約為8M以內),最短邊至少10px,最長邊最大5000px,
長寬比4:1以內。注意:圖片的base64編碼是不包含圖片頭的,如(data:image/jpg;base64,)
"""
img_path = 'images/1.png'#input(u'請輸入圖片全路徑:\n')
# with open(img_path, 'rb') as fp:
fp = open(img_path, 'rb')
img = base64.b64encode(fp.read())
# 人臉動漫化
api_url = 'https://aip.baidubce.com/rest/2.0/image-process/v1/selfie_anime'

print(type(img))
params = {
    'image': img,
    'access_token': access_token,
}
headers_ = {
    # post參數是以表單方式提交,不是json
    'Content-Type': 'application/x-www-form-urlencoded'
}
response_ = requests.post(api_url, data=params, headers=headers_)
if response_:
    print(response_.json())
    # 保存文件
    fp = open('images/動漫圖.jpg', 'wb')
    img = (response_.json()['image'])
    fp.write(base64.b64decode(img))
fp.close()

執行成功,生成了個不怎么好看的動漫圖。。。'image'的值就是生成的動漫圖片的base64編碼格式,需要解碼在保存即可。

 

然而,問題來了,因為以往寫爬蟲時喜歡用httpx模塊,對requests不怎么感冒,速度比httpx差太多了,所以我把上述代碼中發送請求的resquests模塊替換成了httpx

代碼如下:

 1 import json
 2 import base64
 3 import httpx
 4 import requests
 5 
 6 
 7 # 獲取Access Token
 8 url = 'https://aip.baidubce.com/oauth/2.0/token'
 9 post_data = {
10     'grant_type': 'client_credentials',
11     # 這兩個參數的值 需要注冊百度ai應用可以獲取
12     'client_id': 'App Key',
13     'client_secret': Secret Key'
14 }
15 
16 access_token = None
17 response = httpx.post(url=url, data=post_data)
18 if response.status_code == 200:
19     json_data = response.json()
20     access_token = json_data['access_token']
21     # print(access_token)
22     print('access_token is: 保密,自己可以去注冊百度獲取')
23     term_of_validity = json_data['expires_in']
24     print(f'有效使用期為{term_of_validity}秒.[有效期30天]')
25 
26 """
27 打開圖片
28 base64編碼后大小不超過10M(參考:原圖大約為8M以內),最短邊至少10px,最長邊最大5000px,
29 長寬比4:1以內。注意:圖片的base64編碼是不包含圖片頭的,如(data:image/jpg;base64,)
30 """
31 img_path = 'images/1.png'#input(u'請輸入圖片全路徑:\n')
32 # with open(img_path, 'rb') as fp:
33 fp = open(img_path, 'rb')
34 img = base64.b64encode(fp.read())
35 # 人臉動漫化
36 api_url = 'https://aip.baidubce.com/rest/2.0/image-process/v1/selfie_anime'
37 
38 print(type(img))
39 params = {
40     'image': img,
41     'access_token': access_token,
42 }
43 headers_ = {
44     'Content-Type': 'application/x-www-form-urlencoded'
45 }
46 response_ = httpx.post(api_url, data=params, headers=headers_) 47 # response_ = requests.post(api_url, data=params, headers=headers_)
48 if response_:
49     print(response_.json())
50     # 保存文件
51     fp = open('images/動漫圖.jpg', 'wb')
52     img = (response_.json()['image'])
53    fp.write(base64.b64decode(img))
54 fp.close()

只是把requests替換成了httpx,結果 卻出錯了,提示 圖片格式錯誤,什么鬼。。。。

不得以 又回頭去翻httpx和requests的源代碼去查找對比,看看是到底哪里傳參不一樣。。結果是果然有差異:

requests發送post請求時,參數data可以是字典,列表,元組,bytes,文件等等。。。。

httpx發送post請求時,參數data只能是字典。。。。ctrl+鼠標點擊 RequestData 轉到_types.py 找到RequestData = dict

但是,但是,,我的代碼中 data就是字典格式啊。。。。。。


 那問題出在哪里呢,突然想起來,img是bytes類型(經過base64編碼了),難道 這里必須轉成string?想不如做,於是 代碼改成了

import json
import base64
import httpx
import requests


# 獲取Access Token
url = 'https://aip.baidubce.com/oauth/2.0/token'
post_data = {
    'grant_type': 'client_credentials',
    'client_id': 'App Key',
    'client_secret': 'Secret Key'
}

access_token = None
response = httpx.post(url=url, data=post_data)
if response.status_code == 200:
    json_data = response.json()
    access_token = json_data['access_token']
    # print(access_token)
    print('access_token is: 保密,自己可以去注冊百度獲取')
    term_of_validity = json_data['expires_in']
    print(f'有效使用期為{term_of_validity}秒.[有效期30天]')

"""
打開圖片
base64編碼后大小不超過10M(參考:原圖大約為8M以內),最短邊至少10px,最長邊最大5000px,
長寬比4:1以內。注意:圖片的base64編碼是不包含圖片頭的,如(data:image/jpg;base64,)
"""
img_path = 'images/1.png'#input(u'請輸入圖片全路徑:\n')
# with open(img_path, 'rb') as fp:
fp = open(img_path, 'rb')
img = base64.b64encode(fp.read())
# 人臉動漫化
api_url = 'https://aip.baidubce.com/rest/2.0/image-process/v1/selfie_anime'

print(type(img))
params = {
    # 'image': img,
    'image': str(img, encoding="utf-8"),
    'access_token': access_token,
}
headers_ = {
    'Content-Type': 'application/x-www-form-urlencoded'
}
response_ = httpx.post(api_url, data=params, headers=headers_)
# response_ = requests.post(api_url, data=params, headers=headers_)
if response_:
    print(response_.json())
    # 保存文件
    fp = open('images/動漫圖.jpg', 'wb')
    img = (response_.json()['image'])
    fp.write(base64.b64decode(img))
fp.close()

點擊綠色小箭頭 開始運行,結果成功!

總結,python的第三方庫實在太多了,對經常使用的模塊應該熟讀它的開源代碼,細節不能放過。。。。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM