Python请求分段HTTP POST [英] Python Requests Multipart HTTP POST
问题描述
我想知道如何使用Python请求翻译类似的内容?在urllib2中,您可以手动处理通过网络发送到API服务的数据,但是Requests声明分段文件上传很容易.但是,当尝试使用Requests库发送相同的请求时,我相信它没有为这两部分中的每一个正确地在content-type中指定一些关键参数.有人可以说明这件事吗?预先谢谢你!
I was wondering how do you translate something like this using Python Requests? In urllib2, you can manually manipulate the data that is being sent over the wire to the API service, but Requests claims multipart file uploads are easy. However, when trying to send over the same request using the Requests library, I believe that it is not specifying some key parameters in the content-type for each of the two parts correctly. Can someone please shed some light on this matter. Thank you in advance!
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())
当我从用户界面检查萤火虫时,我在POST源中得到了以下内容.
When I examine firebug from the UI, I get the following in the POST source.
-----------------------------662549079759661058833120391
Content-Disposition: form-data; name="userfile"; filename="IMG_1377.jpg" Content-Type: image/jpeg
ÿØÿáÃExif��MM�*���� �������ª���� ���°���������������������º�������Â(�������1�������Ê2�������Ú<�������î�������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中的标头如下:
The headers in firebug are as follows:
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
我想我的问题是通过请求库有什么办法可以调整数据,以便:
I guess my question is is there any way via the requests library to adjust the data so that the:
Content-Disposition: form-data; name="userfile"; filename="IMG_1377.jpg" Content-Type: image/jpeg
和
Content-Disposition: form-data; name="account_id"
69574
语句都存在.我觉得我将不得不做一些事情,例如让文件成为
statements are both present. I feel that I would have to do something like have files be a dictionary of
files = {'file': open('image.jpg', 'rb'), 'account_id': 12345}
但是以某种方式分别编辑了每个部分的Content-Disposition元数据
but somehow edit the Content-Disposition metadata of each of these parts separately
推荐答案
,我相信您不必这么手动,
with requests
, I believe that you don't have to be so manual, simply:
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
我想您的关注点在于您:
I suppose your concern lies with your:
parts.append('Content-Type: %s' % mimetypes.guess_type(file_path)[0] or 'application/octet-stream')
我还没有对我自己证明过这一点.但是,我认为它内置于请求此处.
I haven't proven it to myself beyond the shadow of a doubt. But, I think that is built in to requests here.
看起来像您可以按照建议在文件dict中包含普通字段:
It looks like you can have the normal fields in the files dict, as you propose:
files = {'file': open('image.jpg', 'rb'), 'account_id': 12345}
,并可以根据需要命名文件名:
and could name the filename as you want:
files = {'file': ('userfile', open('image.jpg', 'rb')), 'account_id': 12345}
但是,您会在account_id
字段上得到一个body.write(b'Content-Type: text/plain\r\n\r\n')
,这可能不是您想要的,并且无法自定义每个字段的Content-Disposition(仍然不确定为什么要这样做);对于文件和字段,您都将得到:Content-Disposition: form-data
-这是同时显示的内容.
but, you would get a body.write(b'Content-Type: text/plain\r\n\r\n')
on the account_id
field which is probably not what you want and have no way to customize the Content-Disposition for each field (still not sure why you would need to); for both the file and the field you will get: Content-Disposition: form-data
- which is what you show for both.
我不确定您可以完全使用requests
做您想做的事,也许您应该尝试功能请求.
I'm not sure that you can do exactly what you want with requests
, maybe you should try a feature request.
这篇关于Python请求分段HTTP POST的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!