【问题标题】:Python-request multipart-dataPython请求多部分数据
【发布时间】:2019-12-13 12:22:28
【问题描述】:

我正在尝试发送 2 张照片 + json-payload 请求。首先,我按照How to send a "multipart/form-data" with requests in python? 中的描述做了,但它不起作用。

from requests_toolbelt.multipart.encoder import MultipartEncoder

import requests

mp_encoder = MultipartEncoder(fields={"parameters": {"sysId": 1, "clientId": 4029487, "fsid": 'ChNKoXqa87YucQ1nlf3hJGTl',
                               "deviceId":"89DEB49F37DD49559D124C9F3AFA2A54"},
                                                          'file1':('img317.jpg',open('/Users/12fhntv21Q/Downloads/pasport_rf.jpg',"rb"),'image/jpeg'),
                                                          'file2':('img317.jpg',open('/Users/12fhntv21Q/Downloads/pasport_rf_1.jpg',"rb"),'image/jpeg')
                                                          }
                                          )
print(mp_encoder)
url = 'https://clientsapi01./..../'
response = requests.post(url,headers={'Content-Type': mp_encoder.content_type}, data=mp_encoder)

给出这样的错误:

Traceback (most recent call last):
  File "/Users/12fhntv21Q/PycharmProjects/Api_Test/Client_CUPIS/identification_cupis.py", line 17, in <module>
    'file2':('img317.jpg',open('/Users/12fhntv21Q/Downloads/pasport_rf_1.jpg',"rb"),'image/jpeg')
  File "/Users/12fhntv21Q/Api_Test/lib/python3.7/site-packages/requests_toolbelt/multipart/encoder.py", line 125, in __init__
    self._prepare_parts()
  File "/Users/12fhntv21Q/Api_Test/lib/python3.7/site-packages/requests_toolbelt/multipart/encoder.py", line 246, in _prepare_parts
    self.parts = [Part.from_field(f, enc) for f in self._iter_fields()]
  File "/Users/12fhntv21Q/Api_Test/lib/python3.7/site-packages/requests_toolbelt/multipart/encoder.py", line 246, in <listcomp>
    self.parts = [Part.from_field(f, enc) for f in self._iter_fields()]
  File "/Users/12fhntv21Q/Api_Test/lib/python3.7/site-packages/requests_toolbelt/multipart/encoder.py", line 494, in from_field
    body = coerce_data(field.data, encoding)
  File "/Users/12fhntv21Q/Api_Test/lib/python3.7/site-packages/requests_toolbelt/multipart/encoder.py", line 472, in coerce_data
    return CustomBytesIO(data, encoding)
  File "/Users/12fhntv21Q/Api_Test/lib/python3.7/site-packages/requests_toolbelt/multipart/encoder.py", line 535, in __init__
    buffer = encode_with(buffer, encoding)
  File "/Users/12fhntv21Q/Api_Test/lib/python3.7/site-packages/requests_toolbelt/multipart/encoder.py", line 416, in encode_with
    return string.encode(encoding)
AttributeError: 'dict' object has no attribute 'encode'

尝试从邮递员导入请求代码(其中2张照片和参数发送正确)

导入请求

 url = "https://clientsapi01/..../"

        payload = "------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition:" \
              " form-data; name=\"parameters\"\r\n\r\n{\"sysId\":1,\n\"lang\":\"ru\"," \
              "\n\"clientId\":4029487,\n\"fsid\":\"ChNKoXqa87YucQ1nlf3hJGTl\"," \
              "\n\"devPrototype\":false,\n\"devPrototypeValue\":0," \
              "\n\"deviceId\":\"89DEB49F37DD49559D124C9F3AFA2A54\"}" \
              "\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\n" \
              "Content-Disposition: form-data; name=\"file1\"; " \
              "filename=\"img317.jpg\"\r\nContent-Type: image/jpeg\r\n\r\n\r\n" \
              "------WebKitFormBoundary7MA4YWxkTrZu0gW\r\n" \
              "Content-Disposition: form-data; name=\"file2\"; filename=\"img318.jpg" \
              "\"\r\nContent-Type: image/jpeg\r\n\r\n\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW--"
    headers = {
        'content-type': "multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW",
        'Content-Type': "multipart/mixed",
        'User-Agent': "PostmanRuntime/7.18.0",
        'Accept': "*/*",
        'Cache-Control': "no-cache",
        'Postman-Token': "9faf7642-3ba3-44da-9353-295a90073191,93b2a684-2b39-496a-b492-68899c3cb82c",
        'Host': "clientsapi01.bksndbx.com",
        'Accept-Encoding': "gzip, deflate",
        'Content-Length': "4566826",
        'Connection': "keep-alive",
        'cache-control': "no-cache"
        }

    response = requests.request("POST", url, data=payload, headers=headers)

    print(response.text)

Вut in 也不起作用。 最后,这个方法:

payload_for_request = {"parameters": [{"sysId": 1, "clientId": 4029487, "fsid": 'JXvI1jbXteO8NOpRZPAeKeeh',
                                      "deviceId":"89DEB49F37DD49559D124C9F3AFA2A54",
                                       "lang":"ru"}]}

files = [("file1",("img317.jpg", open('img317.jpg',"rb"),'image/jpeg')),
         ("file2", ("img318.jpg",open('img318.jpg',"rb"), 'image/jpeg'))]

headers={'Content-Type': 'multipart/form-data; boundary=93c1068f0d0c354feca39cdd75562cf0'}
r = requests.post(url,   data=payload_for_request, files=files)
print(r.text)
print(r.headers)

同样抛出错误 - {"result":"error","errorCode":1,"errorMessage":"bad request","errorValue":"common parameters parsing error"}

【问题讨论】:

    标签: python rest api request automated-tests


    【解决方案1】:

    以下示例是使用请求使用两个图像 + 一些数据(在本例中为温度)发出 POST 请求的基本示例:

    import requests
    import os
    
    def send_data_to_server(image_path1, image_path2, temperature):
    
        image_filename1 = os.path.basename(image_path1)
        image_filename2 = os.path.basename(image_path2)
    
        multipart_form_data = {
            'image1': (image_filename1, open(image_path2, 'rb')),
            'image2': (image_filename2, open(image_path2, 'rb')),
            'temperature': ('', str(temperature)),
        }
    
        response = requests.post('https://httpbin.org/post', files=multipart_form_data)
    
        return(response.status_code)
    
    
    test1 = send_data_to_server("sample444.jpg", "sample555.jpg", 39.2)
    
    
    print(test1)
    

    如果你在处理更多的图像,你自然会有列表输入参数,而不是单独的每个图像路径,并且 JSON 会有点大,或者可能会有所不同。

    【讨论】:

    • 例如,仅使用我的文件名,但仍然没有工作 -T​​ypeError: a bytes-like object is required, not 'dict'
    • 发送您的代码的确切 sn-p,让我们看看有什么问题:)
    • 我正在使用示例中的 url 和我的图像尝试您的示例,它可以正常工作。但我有一条线不是温度,而是嵌套字典。如果按原样发送,则会出现错误--TypeError:需要类似字节的对象,而不是'dict'。如果我制作 b“参数”:bytes_payload,它会在图像格式上给出错误 - {“result”:“error”,“errorCode”:1,“errorMessage”:“bad request”,“errorValue”:“仅 jpg和 png 文件。"}
    • 可能你那本讨厌的字典出了问题。尝试按照此答案中的说明对其进行 JSON 化:stackoverflow.com/a/17135283/5214530
    • 在帖子下的主要答案中附上了示例代码:)
    【解决方案2】:
    file1 = '/Users/12fhntv21Q/Downloads/img317.jpg'
    file2 = '/Users/12fhntv21Q/Downloads/img318.jpg'
    
    url_t = 'createProcess'
    
    def send_data_to_server(image_path1, image_path2):
    
        image_filename1 = os.path.basename(image_path1)
        image_filename2 = os.path.basename(image_path2)
    
        payload = {"sysId": 1, "clientId": 4029487, "fsid": 'JXvI1jbXteO8NOpRZPAeKeeh',
                                   "deviceId":"89DEB49F37DD49559D124C9F3AFA2A54"}
        #bytes_payload = json.dumps(payload).encode('utf-8')
        multipart_form_data = {
            'file1': (image_filename1, open(file1, 'rb')),
            'file2': (image_filename2, open(file2, 'rb')),
            "parameters": payload
        }
    
    
        response = requests.post(url_t, files=multipart_form_data)
        print(response.text)
        print(response.headers)
        return(response.status_code)
    
    test1 = send_data_to_server("img317.jpg", "img318.jpg")
    

    如果我在 "multipart_form_data" 中使用嵌套 dict 运行函数,则结果为 TypeError: a bytes-like object is required, not 'dict'。 但是,如果我制作bytes_payload = json.dumps(payload).encode('utf-8') 并在"multipart_form_data" 中将嵌套字典转换为字节类型-b"parameter" : bytes_payload,那么我得到的结果是{"result":"error","errorCode":1,"errorMessage":"bad request","errorValue":"Only jpg and png files allowed."}

    【讨论】:

      猜你喜欢
      • 2013-08-01
      • 1970-01-01
      • 2020-04-25
      • 2017-10-05
      • 2012-11-27
      • 2016-12-17
      • 2012-03-16
      • 2016-11-11
      • 2013-02-12
      相关资源
      最近更新 更多