Python 3 urllib 产生 TypeError: POST data should be bytes or an iterable of bytes。它不能是 str 类型
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/30760728/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Python 3 urllib produces TypeError: POST data should be bytes or an iterable of bytes. It cannot be of type str
提问by Greg
I am trying to convert working Python 2.7 code into Python 3 code and I am receiving a type error from the urllib request module.
我正在尝试将可用的 Python 2.7 代码转换为 Python 3 代码,但我收到来自 urllib 请求模块的类型错误。
I used the inbuilt 2to3 Python tool to convert the below working urllib and urllib2 Python 2.7 code:
我使用内置的 2to3 Python 工具来转换以下工作 urllib 和 urllib2 Python 2.7 代码:
import urllib2
import urllib
url = "https://www.customdomain.com"
d = dict(parameter1="value1", parameter2="value2")
req = urllib2.Request(url, data=urllib.urlencode(d))
f = urllib2.urlopen(req)
resp = f.read()
The output from the 2to3 module was the below Python 3 code:
2to3 模块的输出是以下 Python 3 代码:
import urllib.request, urllib.error, urllib.parse
url = "https://www.customdomain.com"
d = dict(parameter1="value1", parameter2="value2")
req = urllib.request.Request(url, data=urllib.parse.urlencode(d))
f = urllib.request.urlopen(req)
resp = f.read()
When the Python 3 code is run the following error is produced:
当 Python 3 代码运行时,会产生以下错误:
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-56-206954140899> in <module>()
5
6 req = urllib.request.Request(url, data=urllib.parse.urlencode(d))
----> 7 f = urllib.request.urlopen(req)
8 resp = f.read()
C:\Users\Admin\Anaconda3\lib\urllib\request.py in urlopen(url, data, timeout, cafile, capath, cadefault, context)
159 else:
160 opener = _opener
--> 161 return opener.open(url, data, timeout)
162
163 def install_opener(opener):
C:\Users\Admin\Anaconda3\lib\urllib\request.py in open(self, fullurl, data, timeout)
459 for processor in self.process_request.get(protocol, []):
460 meth = getattr(processor, meth_name)
--> 461 req = meth(req)
462
463 response = self._open(req, data)
C:\Users\Admin\Anaconda3\lib\urllib\request.py in do_request_(self, request)
1110 msg = "POST data should be bytes or an iterable of bytes. " \
1111 "It cannot be of type str."
-> 1112 raise TypeError(msg)
1113 if not request.has_header('Content-type'):
1114 request.add_unredirected_header(
TypeError: POST data should be bytes or an iterable of bytes. It cannot be of type str.
I have also read two other tickets (ticket1and ticket2) which mentioned encoding the date.
我还阅读了另外两张票(ticket1和ticket2),其中提到了对日期进行编码。
When I changed the line f = urllib.request.urlopen(req)
to f = urllib.request.urlopen(req.encode('utf-8'))
I received the following error: AttributeError: 'Request' object has no attribute 'encode'
当我将行更改为时f = urllib.request.urlopen(req)
,f = urllib.request.urlopen(req.encode('utf-8'))
收到以下错误:AttributeError: 'Request' object has no attribute 'encode'
I am stuck as to how to make the Python 3 code work. Could you please help me?
我对如何使 Python 3 代码工作感到困惑。请你帮助我好吗?
采纳答案by Padraic Cunningham
From the docsNote that params output from urlencode is encoded to bytes before it is sent to urlopen as data:
来自文档请注意, urlencode 的 params 输出在作为数据发送到 urlopen 之前被编码为字节:
data = urllib.parse.urlencode(d).encode("utf-8")
req = urllib.request.Request(url)
with urllib.request.urlopen(req,data=data) as f:
resp = f.read()
print(resp)
回答by Leb
Try this:
尝试这个:
url = 'https://www.customdomain.com'
d = dict(parameter1="value1", parameter2="value2")
f = urllib.parse.urlencode(d)
f = f.encode('utf-8')
req = urllib.request.Request(url, f)
Your problem lies in the way you were handling the dictionary.
你的问题在于你处理字典的方式。
回答by Dasitha Abeysinghe
I used python requests module with ZOHO CRM API V2. It worked without any issues. Here is a sample working code with GET request:
我在 ZOHO CRM API V2 中使用了 python 请求模块。它没有任何问题。这是带有 GET 请求的示例工作代码:
import json
import requests
# API methods - https://www.zoho.com/crm/developer/docs/api/api-methods.html
# getrecords API Call
module_name = 'Deals'
authtoken = '*****'
api_url = "https://crm.zoho.com/crm/private/json/"+module_name+"/getRecords?authtoken="+authtoken+"&scope=crmapi&fromIndex=1&toIndex=2"
# GET Request
request_response = requests.get(
url=api_url
)
print(json.dumps(json.loads(request_response.text), sort_keys=True, indent=4, separators=(",", ": ")))
json_response = json.loads(request_response.text)