6

Python Requests を使用して、このようなものをどのように翻訳するのだろうか? urllib2 では、ワイヤー経由で API サービスに送信されるデータを手動で操作できますが、Requests はマルチパート ファイルのアップロードは簡単だと主張しています。ただし、Requests ライブラリを使用して同じ要求を送信しようとすると、2 つの部分のそれぞれの content-type でいくつかの重要なパラメーターが正しく指定されていないと思います。誰かがこの問題に光を当てることができますか. 前もって感謝します!

def upload_creative(self, account_id, file_path):
    """"""
    boundary = '-----------------------------' + str(int(random.random()*1e10))
    parts = []

    # Set account ID part.
    parts.append('--' + boundary)
    parts.append('Content-Disposition: form-data; name="account_id"')
    parts.append('')
    parts.append(str(account_id))

    # Set creative contents part.
    parts.append('--' + boundary)
    parts.append('Content-Disposition: form-data; name="userfile"; filename="%s"' % file_path)
    parts.append('Content-Type: %s' % mimetypes.guess_type(file_path)[0] or 'application/octet-stream')
    parts.append('')
    # TODO: catch errors with opening file.
    parts.append(open(file_path, 'r').read())

    parts.append('--' + boundary + '--')
    parts.append('')

    body = '\r\n'.join(parts)

    headers = {'content-type': 'multipart/form-data; boundary=' + boundary}
    url = self._resolve_url('/a/creative/uploadcreative')
    req = urllib2.Request(url, headers=headers, data=body)
    res = urllib2.urlopen(req)

    return json.loads(res.read())

UI から firebug を調べると、POST ソースに次のように表示されます。

-----------------------------662549079759661058833120391 
Content-Disposition: form-data; name="userfile"; filename="IMG_1377.jpg" Content-Type: image/jpeg 

ÿØÿáÃExif��MM�*���� �������ª���� ���°���������������������º�������Â(�������1�������Ê2�������Ú&lt;�������î�������i�������þ%������p��Apple�iPhone 4���H������H�����QuickTime 7.7.1�2012:08:17 11:47:11�Mac OS X 10.7.4�������������� "�������'�����P�������0220������(������<������ �����P������X������� ����� �� ������`������h �����0100 ������� ������  ������¢�������¤��������¤��������¤��������¤ ����������������������2011:10:01 17:19:23�2011:10:01 17:19:23���4��Á��¹��¡���M���Ç»¸������N����������Ê�����W����������â�������ú�����M�����������������!�����S���d����������T�����ÿ���d���������������������Ú����%Á��r��������������t������|(�������������������7������������H������H�����ÿØÿà�JFIF��H�H��ÿþ�AppleMark ÿÛ��  % #!,!#'(***.1-)1%)*( (((((((((((((((((((((((((((((((((((((((((((((((((((ÿÄ¢���������� ������� ���}�!1AQa"q2¡#B±ÁRÑð$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖ×ØÙÚáâãäåæçèéêñòóôõö÷øùú��w�!1AQaq"2B¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz¢£¤¥¦§¨©ª²³´µ¶·¸¹ð.¥ÛWíÇLòV³FcaoæÂÒ8§É¸(è3E¢"Ú×S^+yj�!òû0Oüµn- yè){[oÝ/¸?ÃÔMY¡ÃgÔò4êò4n͸í¶={ÔM¤¸m¯K&ñæ«,©ù»zTÝ=öØô×6¶Ö:MÑi�,Û$Oö[ª÷ª©ÆiîỤJAxj>ÞAõúu¥}lIf÷û^Â)#´y^)Ô"/·v>n~4ººµ­¬æ}FURì·Î 3¿Ãèh»ÐµÈÿ�·|Gu:ß²<ëlWäG·^+¡Ó¼gâ.-Þè|ϸ*ª®  }é?Ú=(i:2½Ïg!ʵÑi¤¼eþ!÷³ÍC'æCqv®ÖÊÕiçCë·øsQy#K_B´þ0s'¦|¿Þ²lò¼?½ÿ�]rZ¶¨ø·6ñÆØ·mvV;þÿ�þ=ôª¿»r\zPñtHö÷>Ù¤R#+ Á òBôR;ú²¾)!àËn<.ÁÔlÏcRäÂ&§­eX´fTóLžQßt§Zµ{â t·pK]ÈL1²îýúEüxþ÷j\î×-jÏÂ>!û:^,E­,>^ýêßwû+Ópæ»?i÷û5kéá¹^ 6Ddq°öÁ¯Rù¨¦yãjòÿÙ 
-----------------------------662549079759661058833120391 
Content-Disposition: form-data; name="account_id" 

69574 
-----------------------------662549079759661058833120391--

firebug のヘッダーは次のとおりです。

Request Headersview source
Accept  text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding gzip, deflate
Accept-Language en-us,en;q=0.5
Cache-Control   no-cache
Connection  keep-alive
Content-Length  1713991
Content-Type    multipart/form-data; boundary=---------------------------662549079759661058833120391
Cookie  instance_defaults=%7C%20%7Cen_US; access_token=75c48e
Host    ui.host.com
Pragma  no-cache
Referer http://ui.host.com/
User-Agent  Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:14.0) Gecko/20100101 Firefox/14.0.1

私の質問は、リクエストライブラリを介してデータを調整して次のようにする方法があると思います:

Content-Disposition: form-data; name="userfile"; filename="IMG_1377.jpg" Content-Type: image/jpeg

そしてその

Content-Disposition: form-data; name="account_id" 

69574

ステートメントは両方とも存在します。ファイルを辞書にするようなことをしなければならないと感じています

files = {'file': open('image.jpg', 'rb'), 'account_id': 12345}

ただし、これらの各パーツの Content-Disposition メタデータを個別に編集する

4

3 に答える 3

9

ではrequests、それほど手動である必要はないと思います。単純に:

import requests

# ...
url = self._resolve_url('/a/creative/uploadcreative')
files = {'file': ('userfile', open(filepath, 'rb'))}
data = {'account_id': account_id}
headers = {'content-type': 'multipart/form-data'}
res = requests.post(url, files=files, data=data, headers=headers)
return res.json

あなたの懸念はあなたにあると思います:

parts.append('Content-Type: %s' % mimetypes.guess_type(file_path)[0] or 'application/octet-stream')

私は疑いの影を超えてそれを自分自身に証明していません. でも、ここのリクエストにはそれが組み込まれていると思います。

編集:あなたが提案するように、ファイル辞書に通常のフィールドを含めることができるようです:

files = {'file': open('image.jpg', 'rb'), 'account_id': 12345}

必要に応じてファイル名に名前を付けることができます:

files = {'file': ('userfile', open('image.jpg', 'rb')), 'account_id': 12345}

しかし、おそらくあなたが望むものではないフィールドで取得し、body.write(b'Content-Type: text/plain\r\n\r\n')account_idフィールドの Content-Disposition をカスタマイズする方法がありません (なぜ必要なのかはまだわかりません)。ファイルとフィールドの両方について、次のようになります。Content-Disposition: form-data- これは、両方について表示するものです。

でやりたいことを正確に実行できるかどうかはrequestsわかりません。機能リクエストを試してみてください。

于 2012-09-25T23:45:49.413 に答える
0
 import requests

 import urllib

 def upload_creative(self, account_id, file_path):

    files = [('userfile', (file_path, open(file_path, 'rb'), "image/jpeg" ))]

    url = self._resolve_url('/a/creative/uploadcreative')

    url =  url + "?"  +  urlib.urlencode(account_id=account_id)

    reuests.post(url, files=files)
于 2014-10-08T04:46:25.617 に答える
-4

python-requests ライブラリ (v.0.13.3) では、リクエスト呼び出し自体に「files」フィールドの前に「data」フィールドを含めると、データが消去されることがわかりました。

例えば、

requests.post(url, headers=headers, data=data, files=files) 

空のフォームデータが生成されます。ただし、次の例ではデータ ディクショナリがフォーム データとして送信されます。

requests.post(url, headers=headers, files=files, data=data)

みんな答えてくれてありがとう

于 2012-09-26T22:09:56.497 に答える