2014-11-20 10 views
8

Vorrei fare una richiesta POST per caricare un file su un servizio web (e ottenere risposta) usando python. Ad esempio, posso fare la seguente richiesta POST con curl:Effettuare una richiesta HTTP POST per caricare un file usando python urllib/urllib2

curl -F "[email protected]" -F output=json http://jigsaw.w3.org/css-validator/validator 

Come posso fare la stessa richiesta con python urllib/urllib2? Il più vicino che ho ottenuto finora è il seguente:

with open("style.css", 'r') as f: 
    content = f.read() 
post_data = {"file": content, "output": "json"} 
request = urllib2.Request("http://jigsaw.w3.org/css-validator/validator", \ 
          data=urllib.urlencode(post_data)) 
response = urllib2.urlopen(request) 

Ho ricevuto un errore HTTP 500 dal codice sopra. Ma dal momento che il mio comando curl ha esito positivo, deve essere qualcosa di sbagliato con la mia richiesta python?

Sono abbastanza nuovo su questo argomento e ti prego di perdonarmi se la domanda del principiante ha risposte o errori molto semplici. Grazie in anticipo per tutti i tuoi aiuti!

risposta

8

Dopo un po 'scavare intorno, sembra this post risolto il mio problema. Si scopre che ho bisogno di avere il codificatore multipart configurato correttamente.

from poster.encode import multipart_encode 
from poster.streaminghttp import register_openers 
import urllib2 

register_openers() 

with open("style.css", 'r') as f: 
    datagen, headers = multipart_encode({"file": f}) 
    request = urllib2.Request("http://jigsaw.w3.org/css-validator/validator", \ 
           datagen, headers) 
    response = urllib2.urlopen(request) 
+0

Non dimenticare di chiudere il file 'style.css'? – Vladius

+6

@Vladius Il file verrà chiuso automaticamente perché viene utilizzato come gestore di contesto. Vedi la documentazione su [la dichiarazione 'with'] (https://docs.python.org/2.7/reference/compound_stmts.html#with). – nandhp

+0

Im davvero nuovo per Python. Ho eseguito quanto sopra, apparentemente di successo. Cosa dovrei aspettarmi ora? Dove posso verificare che funzioni. – Omar

12

Personalmente penso che dovresti considerare la libreria requests per inviare file.

url = 'http://jigsaw.w3.org/css-validator/validator' 
files = {'file': open('style.css')} 
response = requests.post(url, files=files) 

Caricamento di file utilizzando urllib2 non è impossibile, ma piuttosto un compito complicato: http://pymotw.com/2/urllib2/#uploading-files

+1

Grazie, @Wolph. Ho appena provato la libreria delle richieste, ma ho ancora un errore HTTP 500. Quindi la mia domanda dovrebbe probabilmente essere riformulata come, quali sono le differenze tra la richiesta che abbiamo fatto in python e quella fatta da curl? Grazie. –

+0

Bene, hai la 'output = json' nella tua richiesta di ricciolo, che non è nella richiesta Python, quindi questa è probabilmente la differenza. Sono contento che tu abbia funzionato ora però :) – Wolph