TypeError:POST data should be bytes, an iterable of bytes, or a file object. It cannot be of str
程序员文章站
2022-03-08 16:43:10
...
Python2转Python3,调用API在线服务遇到的问题解决(json数据)
Python2代码示例:
import json
import traceback
import urllib
import urllib2
# json格式数据
formdata = {
"CRIM":0.01887747,
"ZN":-0.11363636,
"INDUS":0.25525005,
"CHAS":-0.06916996
}
header = {"Content-Type": "application/json; charset=utf-8"}
url = "https://aistudio.baidu.com/serving/online/xxx?apiKey=a280cf48-6d0c-4baf-bd39xxxxxxcxxxxx"
data = json.dumps(formdata)
try:
request = urllib2.Request(url, data, header)
response = urllib2.urlopen(request)
response_str = response.read()
response.close()
print(response_str)
except urllib2.HTTPError as e:
print("The server couldn't fulfill the request")
print(e.code)
print(e.read())
except urllib2.URLError as e:
print("Failed to reach the server")
print(e.reason)
except:
traceback.print_exc()
修改到Python3的代码
import json
import traceback
import urllib
# 1.首先去掉urllib2, python3统一使用urllib
# import urllib2
# json数据
formdata = {
"CRIM":0.01887747,
"ZN":-0.11363636,
"INDUS":0.25525005,
"CHAS":-0.06916996
}
header = {"Content-Type": "application/json; charset=utf-8"}
url = "https://aistudio.baidu.com/serving/online/xxx?apiKey=a280cf48-6d0c-4baf-bd39xxxxxxcxxxxx"
data = json.dumps(formdata)
# 2.urllib2到urllib转换的语句修改
try:
request = urllib.request.Request(url, data, header)
# 输出字符串
response = urllib.request.urlopen(request)
response_str = response.read()
response.close()
print(response_str)
except urllib.error.HTTPError as e:
print("The server couldn't fulfill the request")
print(e.code)
print(e.read())
except urllib.error.URLError as e:
print("Failed to reach the server")
print(e.reason)
except:
traceback.print_exc()
但,运行之后会报如下错误:
TypeError: POST data should be bytes, an iterable of bytes, or a file object. It cannot be of type str.
查询到有些回答提到,必须使用urllib.parse.urlencode()函数将请求转换为字节,再因此如下:
data = urllib.parse.urlencode(data).encode("utf-8")
# 此时再进行url请求
request = urllib.request.Request(url, data, header)
但这对json数据格式无效,发生新的错误:
TypeError: not a valid non-string sequence or mapping object
原因:json.dumps(data)只是将数组/字典转换为字符串,urllib.parse.urlencode函数无效,当要转换作为url参数传递的字符串(即:将空格字符转换为“%20”)时,使用urlencode ,此方法的输出是字符串,而不是字节数组。
正确解决方案
json.dumps()返回一个字符串,因此必须调用json.dumps().encode()将其转换为字节数组。
# data = urllib.parse.urlencode(data).encode("utf-8")
data = json.dumps(formdata).encode()
此时运行,问题解决。
b'[{"predict":[16.302953720092773]}]'
推荐阅读
-
TypeError: POST data should be bytes, an iterable of bytes, or a file object.制作有道翻译小翻译软件的问题解决方法
-
TypeError: POST data should be bytes, an iterable of bytes, or a file object. It cannot be of type s
-
TypeError: POST data should be bytes, an iterable of bytes, or a file object. It cannot be of type s
-
POST data should be bytes, an iterable of bytes, or a file object. It cannot be of type str.
-
TypeError:POST data should be bytes, an iterable of bytes, or a file object. It cannot be of str