2015-01-31 69 views
1

我試圖重現與Python請求這個curl命令:Python的請求不會上傳文件

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 

,捲曲請求工作正常。現在,我嘗試使用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

回答

3

捲曲上載文件作爲POST體本身,而是你問requests將其編碼到多/ 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) This posts data exactly as specified with no extra processing whatsoever.

If you start the data with the letter @ , the rest should be a filename. Data is posted in a similar manner as --data-ascii does, except that newlines and carriage returns are preserved and conversions are never done.