【问题标题】:Creating POST request in python, need to send data as multipart/form-data?在 python 中创建 POST 请求,需要将数据作为 multipart/form-data 发送吗?
【发布时间】:2017-02-02 04:44:59
【问题描述】:

我正在为一位朋友编写一个非常简单的 Python 应用程序,该应用程序将查询服务并获取一些数据作为回报。我可以很容易地管理 GET 请求,但是我在处理 POST 请求时遇到了问题。只是为了让我的脚湿透,我只是稍微修改了他们的示例 JSON 数据,但是当我发送它时,我得到了一个错误。这是代码(识别信息已更改):

import urllib.request
import json

def WebServiceClass(Object):

    def __init__(self, user, password, host):
        self.user = user
        self.password = password
        self.host = host
        self.url = "https://{}/urldata/".format(self.host)

        mgr = urllib.request.HTTPPasswordMgrWithDefaultRealm()
        mgr.add_password(None, "https://{}".format(self.host), self.user, self.password)
        self.opener = urllib.request.build_opener(urllib.request.HTTPDigestAuthHandler(mgr))

username = "myusername"
password = "mypassword"
service_host = "thisisthehostinfo"

web_service_object = WebServiceClass(username, password, service_host)

user_query = {"searchFields": 
        {
        "First Name": "firstname",
        "Last Name": "lastname"
        },
        "returnFields":["Entity ID","First Name","Last Name"]
        }

user_query = json.dumps(user_query)
user_query = user_query.encode("ascii")

the_url = web_service_object.url + "modules/Users/search"

try:
    user_data = web_service_object.opener.open(the_url, user_query)
    user_data.read()

except urllib.error.HTTPError as e:
    print(e.code)
    print(e.read())

我从他们的 API 文档中获得了类数据。

正如我所说,我可以很好地执行 GET 请求,但是这个 POST 请求给我一个 500 错误,并带有以下文本:

Content type 'application/x-www-form-urlencoded;charset=UTF-8' not supported

在研究这个错误时,我的假设变成了上述错误意味着我需要将数据作为 multipart/form-data 提交。这个假设是否正确是我想测试的,但是股票 Python 似乎没有任何简单的方法来创建 multipart/form-data - 那里有模块,但它们似乎都需要一个文件并将其转换为 multipart/form-data,而我只想将这个简单的 JSON 数据转换为测试。

这让我想到了两个问题:我是否认为我需要 multipart/form-data 才能使其正常工作的假设是正确的?如果是这样,我是否需要将我的 JSON 数据放入一个文本文件并使用其中一个模块将其转换为多部分,或者有什么方法可以在不创建文件的情况下做到这一点?

【问题讨论】:

  • 您可以使用io.StringIO 在内存中创建类似文件的对象并使用它来代替文件。但我认为模块requests 可能是更好的解决方案。

标签: python python-3.x post


【解决方案1】:

也许你想试试 requests 库,你可以传递一个files 参数,然后请求将发送一个 multipart/form-data POST 而不是 application/x-www-form-urlencoded POST。但是,您不仅限于使用该字典中的实际文件:

import requests
response = requests.post('http://httpbin.org/post', files=dict(foo='bar'))
print response.status_code

如果您想了解有关 requests 库的更多信息,特别是在发送多部分表单方面,请查看以下内容:

http://docs.python-requests.org/en/master/http://docs.python-requests.org/en/master/user/advanced/?highlight=Multipart-Encoded%20Files

【讨论】:

  • 原谅我的无知 - 我已经开始走这条路,但因为我不知道如何结合请求使用 build_opener 方法而停止了。我在 build_opener 对象上有效地调用了 open(),但我认为我不能在 build_opener 对象上调用 post() 或任何东西。
  • 如果你想发出经过身份验证的请求,你可以调用 requests post 方法如下:requests.post('http://httpbin.org/post', files=dict(foo='bar'), auth=HTTPBasicAuth('username', 'password') 所以你根本不必使用 urllib。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-19
  • 1970-01-01
  • 1970-01-01
  • 2017-10-31
  • 1970-01-01
相关资源
最近更新 更多