6

ファイルを Web サーバーにアップロードしたいと考えています。私が読んだことから、これを行う最善の方法は、HTTP POST 要求で multipart/form-data エンコーディング タイプを使用することです。

私の調査によると、Python 標準ライブラリを使用してこれを行う簡単な方法はないようです。私はPython 3を使用しています。

(注:これを簡単に実現するには、 requests ( PyPI Link ) というパッケージを参照してください)

私は現在この方法を使用しています:

import mimetypes, http.client
boundary = 'wL36Yn8afVp8Ag7AmP8qZ0SA4n1v9T' # Randomly generated
for fileName in fileList:
    # Add boundary and header
    dataList.append('--' + boundary)
    dataList.append('Content-Disposition: form-data; name={0}; filename={0}'.format(fileName))

    fileType = mimetypes.guess_type(fileName)[0] or 'application/octet-stream'
    dataList.append('Content-Type: {}'.format(fileType))
    dataList.append('')

    with open(fileName) as f: 
        # Bad for large files
        dataList.append(f.read())

dataList.append('--'+boundary+'--')
dataList.append('')
contentType = 'multipart/form-data; boundary={}'.format(boundary)

body = '\r\n'.join(dataList)
headers = {'Content-type': contentType}

conn = http.client.HTTPConnection('http://...')
req = conn.request('POST', '/test/', body, headers)

print(conn.getresponse().read())

これは、テキストを送信するために機能します。

2 つの問題があります。これはテキストのみであり、テキスト ファイル全体を巨大な文字列としてメモリに格納する必要があります。

バイナリファイルをアップロードするにはどうすればよいですか? ファイル全体をメモリに読み込まずにこれを行う方法はありますか?

4

3 に答える 3

3

私が python3 に翻訳した小さなDoug Hellmann の urllib2を見てください。

私はほぼこのように使用します:

import urllib.request
import urllib.parse
from lib.multipart_sender import MultiPartForm

myfile = open('path/to/file', 'rb')
form = MultiPartForm()
form.add_field('token', apipost[mycgi['domain']]._token)
form.add_field('domain', mycgi['domain'])
form.add_file('file', 'logo.jpg', fileHandle=myfile)
form.make_result()

url = 'http://myurl'
req1 = urllib.request.Request(url)
req1.add_header('Content-type', form.get_content_type())
req1.add_header('Content-length', len(form.form_data))
req1.add_data(form.form_data)
fp = urllib.request.urlopen(req1)
print(fp.read()) # to view status
于 2013-04-03T10:36:52.020 に答える