Python请求不会上传文件

时间:2015-01-31 19:18:41

标签: python python-requests

我试图用Python请求重现这个curl命令:

curl -X POST -H 'Content-Type: application/gpx+xml' -H 'Accept: application/json' --data-binary @test.gpx "http://test.roadmatching.com/rest/mapmatch/?app_id=my_id&app_key=my_key" -o output.json

curl请求正常。现在我用Python尝试:

import requests

file =  {'test.gpx': open('test.gpx', 'rb')}

payload = {'app_id': 'my_id', 'app_key': 'my_key'}
headers = {'Content-Type':'application/gpx+xml', 'Accept':'application/json'}


r = requests.post("https://test.roadmatching.com/rest/mapmatch/", files=file, headers=headers, params=payload)

我收到错误:

<Response [400]>
{u'messages': [], u'error': u'Invalid GPX format'}

我做错了什么?我是否必须在某处指定data-binary

此处记录了API:https://mapmatching.3scale.net/mmswag

1 个答案:

答案 0 :(得分:3)

Curl将文件上传为POST正文,但您要求requests将其编码为multipart / form-data正文。不要在这里使用files,将文件对象作为data参数传递:

import requests

file = open('test.gpx', 'rb')

payload = {'app_id': 'my_id', 'app_key': 'my_key'}
headers = {'Content-Type':'application/gpx+xml', 'Accept':'application/json'}

r = requests.post(
    "https://test.roadmatching.com/rest/mapmatch/",
    data=file, headers=headers, params=payload)

如果您在with声明中使用该文件,我们会在上传后关闭该文件:

payload = {'app_id': 'my_id', 'app_key': 'my_key'}
headers = {'Content-Type':'application/gpx+xml', 'Accept':'application/json'}

with open('test.gpx', 'rb') as file:
    r = requests.post(
        "https://test.roadmatching.com/rest/mapmatch/",
        data=file, headers=headers, params=payload)

来自curl documentation for --data-binary

  

(HTTP)这完全按照指定发布数据,无需任何额外处理。

     

如果您使用字母@启动数据,则其余应为文件名。数据以与--data-ascii类似的方式发布,但保留换行符和回车符并且永远不会进行转换。