TypeError:POSTデータは、バイト、バイトの反復可能、またはファイルオブジェクトである必要があります。それはstrにすることはできません



Typeerror Post Data Should Be Bytes



Python2コード例:

import json import traceback import urllib import urllib2 # json format data 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. First remove urllib2, python3 uses urllib uniformly # import urllib2 # json data 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. Modify the statement from urllib2 to urllib conversion try: request = urllib.request.Request(url, data, header) # Output string 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') # Now make url request request = urllib.request.Request(url, data, header)

ただし、これはjsonデータ形式では無効であり、新しいエラーが発生します。

TypeError: not a valid non-string sequence or mapping object

理由:json.dumps(data)は、配列/辞書を文字列に変換するだけです。urlパラメーターとして渡された文字列を変換する場合(つまり、スペース文字を '%に変換する場合)、urllib.parse.urlencode関数は無効です。 20 ')、urlencodeを使用すると、このメソッドの出力は文字列であり、バイト配列ではありません。



適切なソリューション

json.dumps()は文字列を返すため、json.dumps()。encode()を呼び出してバイト配列に変換する必要があります。

# data = urllib.parse.urlencode(data).encode('utf-8') data = json.dumps(formdata).encode()

この時点で実行すると、問題は解決します。

b'[{'predict':[16.302953720092773]}]'