2010-03-22 16 views
28

BaseHTTPHandler z modułu BaseHTTPServer nie zapewnia wygodnego dostępu do parametrów żądania http. Jaki jest najlepszy sposób analizowania parametrów GET ze ścieżki i parametrów POST z treści żądania?Parse http parametry GET i POST z BaseHTTPHandler?

Teraz używam tego dla GET:

def do_GET(self): 
    parsed_path = urlparse.urlparse(self.path) 
    try: 
     params = dict([p.split('=') for p in parsed_path[4].split('&')]) 
    except: 
     params = {} 

Działa to w większości przypadków, ale chciałbym coś bardziej solidnego, który obsługuje kodowanie oraz przypadków, jak właściwie pustych parametrów. Idealnie, chciałbym coś małego i niezależnego, a nie pełną strukturę sieci.

Odpowiedz

5

Możesz wypróbować moduły Werkzeug, baza biblioteki Werkzeug nie jest zbyt duża i jeśli to konieczne, możesz po prostu wyodrębnić ten fragment kodu i gotowe.

Sposób url_decode zwraca MultiDict i ma kodujący wsparcie :)

W przeciwieństwie do metody urlparse.parse_qs wersja Werkzeug dba:

  • kodowania
  • wiele wartości
  • porządek

Jeśli nie masz n Dla tych (lub w przypadku kodowania, użyj Python 3), nie wahaj się używać wbudowanych rozwiązań.

2

Czy badałeś używając bibliotek takich jak CherryPy? Zapewniają o wiele szybszą ścieżkę do obsługi tych rzeczy niż BaseHTTPServer.

2

Podstawowa obsługa parametrów żądania HTTP jest dostępna w CGI module. Zalecanym mechanizmem obsługi danych formularzy jest klasa cgi.FieldStorage.

Aby uzyskać dane z przesłanych formularzy, najlepiej skorzystać z klasy FieldStorage. Pozostałe klasy zdefiniowane w tym module są dostarczane głównie w celu zapewnienia kompatybilności wstecznej. Wywołaj go dokładnie raz, bez argumentów. Odczytuje zawartość formularza ze standardowego wejścia lub środowiska (w zależności od wartości różnych zmiennych środowiskowych ustawionych zgodnie ze standardem CGI). Ponieważ może zużywać standardowe dane wejściowe, należy utworzyć instancję tylko raz.

Instancja FieldStorage może być indeksowana jak słownik Python. Umożliwia testowanie członkostwa za pomocą operatora in, a także obsługuje standardową metodę słownikową keys() i wbudowaną funkcję len(). Pola formularza zawierające puste ciągi są ignorowane i nie pojawiają się w słowniku; aby zachować takie wartości, podaj prawdziwą wartość opcjonalnego parametru słowa kluczowego keep_blank_values ​​podczas tworzenia instancji FieldStorage.

Na przykład, następujący kod (który zakłada, że ​​nagłówek Content-Type i pusta linia zostały już wydrukowane) sprawdza, czy nazwa pola i addr są zarówno ustawiona na niepustym ciągiem:

form = cgi.FieldStorage() 
if "name" not in form or "addr" not in form: 
    print "<H1>Error</H1>" 
    print "Please fill in the name and addr fields." 
    return 
print "<p>name:", form["name"].value 
print "<p>addr:", form["addr"].value 
#...further form processing here... 
+0

Biblioteka CGI nie obsługuje kodowania (jak UTF -8) dla ciebie, więc jest mniej odpowiedni niż niektóre inne dostępne biblioteki. – Wolph

+0

Kodowanie można przekazać do pliku podobnego do pierwszego argumentu FieldStorage. – gimel

+0

To prawda, ale po co zawracać sobie głowę, gdy istnieją skrypty, które sobie z tym poradzą, w tym łapanie błędów? Nie trzeba wymyślać koła. – Wolph

78

Możesz użyć url.parse:

>>> from url.parse import urlparse, parse_qs 
>>> url = 'http://example.com/?foo=bar&one=1' 
>>> parse_qs(urlparse(url).query) 
{'foo': ['bar'], 'one': ['1']} 

dla Pythonie 2, moduł o nazwie urlparse zamiast url.parse.

+2

Należy zauważyć, że urlparse w Pythonie 2 nie obsługuje kodowania, wersja Pythona 3 to obsługuje. Dodatkowo, aby zachować poprawną kolejność, należy użyć 'parse_qsl' zamiast' parse_qs' który zwraca listę. – Wolph

8

lepszym rozwiązaniem starej pytanie:

def do_POST(self): 
    length = int(self.headers.getheader('content-length')) 
    field_data = self.rfile.read(length) 
    fields = urlparse.parse_qs(field_data) 

Będzie to ciągnąć urlencoded danych POST z treścią dokumentu i analizować je dict z właściwego urldecoding

+0

Próbowałem zrobić najbardziej podstawowy serwer, który mógłby obsłużyć żądania pobierania i wysyłania w Pythonie, a tylko twój pracował dla mnie w obsłudze żądań POST. Zostało to napisane 3 lata temu, ale dzięki! :) – harkirat1892