10

コンテンツが MultipartFormData である必要があるサイトへの POST 要求を実行するために、Python で (python-requests atm を使用して) スクリプトを作成しようとしています。この POST リクエストを手動で (サイトのフォームに入力して投稿することにより)、wireshark を使用して行うと、次のようになりました (短いバージョン):

Content-Type: multipart/form-data;
Content-Disposition: form-data; name="name"
Data (8 Bytes)
    John Doe

同じ結果を得るために python-requests ライブラリを使用しようとすると、次のメッセージが送信されます。

Content-Type: application/x-pandoplugin
Content-Disposition: form-data; name="name"; filename="name"\r\n
Media type: application/x-pandoplugin (12 Bytes)
    //and then in this piece is what we posted://
    John Doe

奇妙なことに、パケットの「一般的なタイプ」は確かに multipart/form-data ですが、送信される個々のアイテム (キー = 「名前」、値 = 「John Doe」) のタイプは application/x-pandoplugin (ランダムな私のPC上のアプリケーションだと思います)。

これは使用されるコードです:

response = s.post('http://url.com', files={'name': 'John Doe'})

headers 引数を使用する代わりに、個々のアイテムの content-type を指定する方法はありますか (「全体」のパケットのタイプのみを変更します)。

サーバーが送信したコンテンツ タイプを理解できないため、サーバーが正しく応答していないと考えられます。

ちょっとした更新: マルチパート コンテンツのさまざまな部分は、ブラウザーで POST を実行した場合に送信されるものと同じになっていると思います。これで問題ありません。それでも、サーバーはスクリプトで送信した変更を実際には行いません。まだ異なるのは、異なるパーツの順序だけです。

たとえば、これは私のブラウザが送信するものです:

Boundary: \r\n------WebKitFormBoundary3eXDYO1lG8Pgxjwj\r\n
Encapsulated multipart part:  (text/plain)
    Content-Disposition: form-data; name="file"; filename="ex.txt"\r\n
    Content-Type: text/plain\r\n\r\n
    Line-based text data: text/plain
        lore ipsum blabbla

Boundary: \r\n------WebKitFormBoundary3eXDYO1lG8Pgxjwj\r\n
Encapsulated multipart part: 
    Content-Disposition: form-data; name="seq"\r\n\r\n
    Data (2 bytes)

Boundary: \r\n------WebKitFormBoundary3eXDYO1lG8Pgxjwj\r\n
Encapsulated multipart part: 
    Content-Disposition: form-data; name="name"\r\n\r\n
    Data (2 bytes)

そして、これはスクリプトが (python-requests を使用して) 送信するものです:

Boundary: \r\n------WebKitFormBoundary3eXDYO1lG8Pgxjwj\r\n
Encapsulated multipart part: 
    Content-Disposition: form-data; name="name"\r\n\r\n
    Data (2 bytes)

Boundary: \r\n------WebKitFormBoundary3eXDYO1lG8Pgxjwj\r\n
Encapsulated multipart part:  (text/plain)
    Content-Disposition: form-data; name="file"; filename="ex.txt"\r\n
    Content-Type: text/plain\r\n\r\n
    Line-based text data: text/plain
        lore ipsum blabbla

Boundary: \r\n------WebKitFormBoundary3eXDYO1lG8Pgxjwj\r\n
Encapsulated multipart part: 
    Content-Disposition: form-data; name="seq"\r\n\r\n
    Data (2 bytes)

サーバーがパーツの注文をカウントする可能性はありますか? マルチパートアップロードフォームによると: 注文は保証されていますか? 、どうやらそうですか?もしそうなら、リクエストライブラリを使用して明示的に注文を強制することは可能ですか? さらに悪いことに、ファイルとテキスト値だけが混在しています。

したがって、注文を強制するのはかなり難しいようです。これは私がやっている現在の方法です:

s.post('http://www.url.com', files=files,data = form_values)

EDIT2: パーツの順序が元のリクエストと同じになるように、リクエスト プラグインを変更しました。これは問題を解決しないので、私の問題に対する直接的な解決策はないと思います。サイトの開発者にメールを送って、彼らが私を助けてくれることを願っています!

4

3 に答える 3

2

今日の時点で、次のことができます。

response = s.post('http://url.com', files={'name': (filename, contents, content_type)})
于 2016-11-14T04:01:12.300 に答える
0

Python は、システム全体の構成ファイルを使用して、ファイルの MIME タイプを「推測」します。これらのプラグインがファイル拡張子をカスタム MIME タイプで登録している場合、代わりにそれを入れることになります。

最も安全な方法は、送信する特定のサーバーに適した独自の MIME タイプ推測を作成し、考えもしなかった拡張機能に対してネイティブの Python MIME タイプ推測のみを使用することです。

python-requests を使用して content-type を手動で正確に指定する方法はわかりませんが、可能になるはずです。

于 2013-11-20T19:24:22.387 に答える