web-dev-qa-db-ja.com

http GETおよびPOST BaseHTTPHandlerからのパラメーターを解析しますか?

BaseHTTPServerモジュールのBaseHTTPHandlerは、http要求パラメーターにアクセスする便利な方法を提供していないようです。パスのGETパラメーターと、リクエスト本文のPOSTパラメーターを解析する最良の方法は何ですか?

今、私はこれを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 = {}

これはほとんどの場合に機能しますが、エンコードや空のパラメーターのようなケースを適切に処理する、より堅牢なものが欲しいのです。理想的には、完全なWebフレームワークではなく、小規模でスタンドアロンの何かが欲しいです。

34
ataylor

Werkzeug モジュールを試すことができます。ベースのWerkzeugライブラリは大きすぎず、必要に応じてこのコードを抽出するだけで完了です。

url_decodeメソッドはMultiDictを返し、エンコードをサポートしています:)

urlparse.parse_qs Werkzeugバージョンが処理するメソッド:

  • エンコーディング
  • 複数の値
  • ソート順

これらが必要ない場合(またはエンコードの場合は、Python 3)を使用してください)、組み込みのソリューションを自由に使用できます。

6
Wolph

urllib.parse を使用することもできます。

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

Python 2の場合、モジュールの名前はurl.parseではなく urlparse になります。

85
zag

古い質問に対するより良い解決策:

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

これは、urlencoded POSTドキュメントのコンテンツからデータを取得し、適切なurldecodingで辞書を解析します

12
Mike

CherryPy のようなライブラリを使用して調査しましたか?これらは、BaseHTTPServerよりもこれらのものを処理するためのはるかに速いパスを提供します。

2
Benno

基本的なHTTP要求パラメーターのサポートは、 CGI module で提供されます。フォームデータを処理するための推奨メカニズムは_cgi.FieldStorage_クラスです。

送信されたフォームデータを取得するには、FieldStorageクラスを使用するのが最善です。このモジュールで定義されている他のクラスは、主に下位互換性のために提供されています。引数なしで1回だけインスタンス化します。これは、標準入力または環境(CGI標準に従って設定されたさまざまな環境変数の値に応じて)からフォームの内容を読み取ります。標準入力を消費する可能性があるため、インスタンス化は1回のみにしてください。

FieldStorageインスタンスは、Python辞書のようにインデックスを付けることができます。in演算子によるメンバーシップテストを可能にし、標準辞書メソッドkeys()および組み込み関数len()。空の文字列を含むフォームフィールドは無視され、辞書に表示されません;そのような値を保持するには、FieldStorageインスタンスを作成するときにオプションのkeep_blank_valuesキーワードパラメーターにtrue値を指定します。

たとえば、次のコード(Content-Typeヘッダーと空白行が既に印刷されていることを前提としています)は、フィールド名とaddrが両方とも空でない文字列に設定されていることを確認します。

_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...
_
2
gimel