gpt4 book ai didi

Python urllib.request.Request参数 'data'对象类型

转载 作者:行者123 更新时间:2023-12-01 08:18:58 25 4
gpt4 key购买 nike

我尝试使用 urllib.request.Request (Python 3.6.7) 对内部 Web 服务进行 API 调用以获取一些 json 结果。我需要向服务器发送一些数据和 header ,因此我使用 urllib.request.Request 类来执行此操作。对于数据的输入,我尝试找出它接受的格式是什么。来自Python docs ,它说:

The supported object types include bytes, file-like objects, and iterables.

因此,我对此参数数据使用字典数据类型。这是我的代码:

import urllib

my_url = "https://httpbin.org/post"
my_headers = { "Content-Type" : "application/x-www-form-urlencoded" }
my_data = {
"client_id" : "ppp",
"client_secret" : "000",
"grant_type" : "client_credentials" }

req = urllib.request.Request(url=my_url, data=my_data, headers=my_headers)
response = urllib.request.urlopen(req)
html = response.read()
print(html)

然后我得到这样的错误:

Traceback (most recent call last):
File "./callapi.py", line 23, in <module>
response = urllib.request.urlopen(req)
File "/usr/lib64/python3.6/urllib/request.py", line 223, in urlopen
return opener.open(url, data, timeout)
File "/usr/lib64/python3.6/urllib/request.py", line 526, in open
response = self._open(req, data)
File "/usr/lib64/python3.6/urllib/request.py", line 544, in _open
'_open', req)
File "/usr/lib64/python3.6/urllib/request.py", line 504, in _call_chain
result = func(*args)
File "/usr/lib64/python3.6/urllib/request.py", line 1361, in https_open
context=self._context, check_hostname=self._check_hostname)
File "/usr/lib64/python3.6/urllib/request.py", line 1318, in do_open
encode_chunked=req.has_header('Transfer-encoding'))
File "/usr/lib64/python3.6/http/client.py", line 1239, in request
self._send_request(method, url, body, headers, encode_chunked)
File "/usr/lib64/python3.6/http/client.py", line 1285, in _send_request
self.endheaders(body, encode_chunked=encode_chunked)
File "/usr/lib64/python3.6/http/client.py", line 1234, in endheaders
self._send_output(message_body, encode_chunked=encode_chunked)
File "/usr/lib64/python3.6/http/client.py", line 1064, in _send_output
+ b'\r\n'
TypeError: can't concat str to bytes

然后我按照此 docs 中的示例进行操作页面,并将我的代码更改为:

import urllib

my_url = "https://httpbin.org/post"
my_headers = { "Content-Type" : "application/x-www-form-urlencoded" }
my_data = {
"client_id" : "ppp",
"client_secret" : "000",
"grant_type" : "client_credentials" }

my_uedata = urllib.parse.urlencode(my_data)
my_edata = my_uedata.encode('ascii')

req = urllib.request.Request(url=my_url, data=my_edata,headers=my_headers)
response = urllib.request.urlopen(req)
html = response.read()
print(html)

然后就可以了。

我的问题是,文档中不是说这个类接受数据类型 iterables 吗?为什么我在 dict 中的参数是错误的?我的最终结果是使用 str.encode() 方法,该方法返回 byte object ,而且这个类似乎必须采用字节对象而不是可迭代对象。

我正在尝试使用Python标准库文档作为Python代码的主要引用来源,但是我很难使用它,希望任何人都可以提供一些线索来帮助我更多地了解该库的使用方式文档有效,或者是否有任何其他教程我需要先完成才能以更好的方式使用它。谢谢。

最佳答案

我同意你的观点,该文档并不明确。隐含的是,如果 data 参数是可迭代的,则它必须是字节的可迭代。当我尝试将字符串作为数据传递时,我收到一条明确的错误消息:

TypeError: POST data should be bytes, an iterable of bytes, or a file object. It cannot be of type str.

因此,出于这个原因,可迭代对象不能是字典。作为非字节对象中的有效可迭代的示例(好吧,只是一个示例,没有理由在实际代码中使用它......):

def dict_iter(d):
for i in d.items():
yield(str(i).encode())

您可以使用该生成器作为 data 参数:

req = urllib.request.Request(url=my_url, data=dict_iter(my_data), headers=my_headers)

关于Python urllib.request.Request参数 'data'对象类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54802272/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com