2014-11-20 27 views
8

Chciałbym wysłać żądanie POST, aby przesłać plik do usługi sieciowej (i uzyskać odpowiedź) przy użyciu Pythona. Na przykład, można zrobić następujące żądania POST z curl:Utwórz żądanie http POST, aby przesłać plik za pomocą pythona urllib/urllib2

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

Jak mogę sprawić, że sam wniosek z python urllib/urllib2? Najbliższe do tej pory są następujące:

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) 

Mam błąd HTTP 500 z powyższego kodu. Ale ponieważ moje polecenie curl się powiedzie, musi być coś nie tak z moim pytaniem pythona?

Jestem całkiem nowy w tym temacie i proszę mi wybaczyć, jeśli pytanie rekrutów ma bardzo proste odpowiedzi lub błędy. Z góry dziękuję za wszystkie pomocne!

Odpowiedz

8

Po niektóre kopania wokół wydaje this post rozwiązać mój problem. Okazuje się, że muszę poprawnie skonfigurować koder wieloczęściowy.

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

Nie zapomnij zamknąć pliku 'style.css'? – Vladius

+6

@Vladius Plik zostanie zamknięty automatycznie, ponieważ jest używany jako menedżer kontekstów. Zobacz dokumentację na [the 'with' statement] (https://docs.python.org/2.7/reference/compound_stmts.html#with). – nandhp

+0

Jestem naprawdę nowy dla Pythona. Przeprowadziłem powyższe, z pozoru udane. Czego powinienem się teraz spodziewać? Gdzie mogę sprawdzić, czy działa. – Omar

12

Osobiście uważam, że powinieneś rozważyć opublikowanie biblioteki requests.

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

Przesyłanie plików za urllib2 nie jest niemożliwe, ale dość skomplikowanym zadaniem: http://pymotw.com/2/urllib2/#uploading-files

+1

Dzięki, @Wolph. Po prostu próbowałem biblioteki żądań, ale nadal mam błąd HTTP 500. Więc moje pytanie powinno zostać ponownie sformatowane jako, jakie są różnice między żądaniem, które zrobiliśmy w pythonie a tym, co zrobiło curl? Dzięki. –

+0

Cóż, masz 'output = json' w twoim żądaniu curl, którego nie ma w pytaniu Pythona, więc prawdopodobnie jest to różnica. Cieszę się, że teraz to działa :) – Wolph