Python 中使用 POST 方式上传文件

最近要用 Python 模拟表单上传文件,搜索了一下常见的解决方案。

如果只是要模拟提交一个不包含文件字段的表单,实现起来是很简单的,但涉及到文件上传就有一点小复杂,需要自己对文件进行编码,或者使用第三方模块。

如果机器上有 PycURL,那么可以使用 PycURL 来上传文件

不过,由于 PycURL 需要用到 curl,在 Windows 下安装可能会有点麻烦,除 PycURL 外,也有一些其它实现 POST 文件上传的方式,比如 这儿 的 2 楼有人贴出了一个将文件进行编码之后再 POST 的方法,另外还有 MultipartPostHandlerurllib2_fileposter 等第三方模块。但 MultipartPostHandler 这个模块似乎比较老了,urllib2_file 我试用了一下遇到错误没有成功,这儿我想介绍的是另外一个第三方模块 poster。

如果机器上安装了 Python 的 setuptools,可以通过下面的命令来安装 poster:

easy_install poster

装完之后,就可以像下面这样上传文件了:

# test_client.py
from poster.encode import multipart_encode
from poster.streaminghttp import register_openers
import urllib2

# 在 urllib2 上注册 http 流处理句柄
register_openers()

# 开始对文件 "DSC0001.jpg" 的 multiart/form-data 编码
# "image1" 是参数的名字,一般通过 HTML 中的  标签的 name 参数设置

# headers 包含必须的 Content-Type 和 Content-Length
# datagen 是一个生成器对象,返回编码过后的参数
datagen, headers = multipart_encode({"image1": open("DSC0001.jpg", "rb")})

# 创建请求对象
request = urllib2.Request("http://localhost:5000/upload_image", datagen, headers)
# 实际执行请求并取得返回
print urllib2.urlopen(request).read()

很简单,文件就上传完成了。

其中那个 register_openers() 相当于以下操作:

from poster.encode import multipart_encode
from poster.streaminghttp import StreamingHTTPHandler, StreamingHTTPRedirectHandler, StreamingHTTPSHandler

handlers = [StreamingHTTPHandler, StreamingHTTPRedirectHandler, StreamingHTTPSHandler]
opener = urllib2.build_opener(*handlers)
urllib2.install_opener(opener)

另外,poster 也可以携带 cookie,比如:

opener = poster.streaminghttp.register_openers()
opener.add_handler(urllib2.HTTPCookieProcessor(cookielib.CookieJar()))

params = {'file': open("test.txt", "rb"), 'name': 'upload test'}
datagen, headers = poster.encode.multipart_encode(params)
request = urllib2.Request(upload_url, datagen, headers)
result = urllib2.urlopen(request)

这样,通过表单 POST 的方式上传文件就方便多了。

分类:编程标签:Python
碎碎念

相关文章:

评论:

alex

http://peerit.blogspot.com/2007/07/multipartposthandler-doesnt-work-for.htmlMultipartPostHandler的这个修改版已经相当好,且支持Unicode文件。个人觉得还是MultipartPostHandler和urllib2结合的更紧密和更好用。而且MultipartPostHandler很灵活:既可以使用multipart/form-data也可以使用application/x-www-form-urlencoded当对要POST的数据使用了urllib.urlencode方法时,(实际这些数据就变成了经过编码后的字符串)这些数据就是要使用application/x-www-form-urlencoded来进行提交的;当对要POST的数据直接用Dict的方式表示出来,并且在发出请求时也是直接用的这个dict数据时,这些数据就是使用的multipart/form-data方式。和urllib2配合使用时,直接在build_opener中加上就可以了: opener = urllib2.build_opener(http_handler_debug, http_cookie_processor, MultipartPostHandler.MultipartPostHandler)

alex

Example: import MultipartPostHandler, urllib2, cookielib cookies = cookielib.CookieJar() opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookies), MultipartPostHandler.MultipartPostHandler) params = { "username" : "bob", "password" : "riviera", "file" : open("filename", "rb") } opener.open("http://wwww.bobsite.com/upload/", params)

oldj

测试了一下,果然可以。这个修改版不错,可以直接包含在项目中。多谢!:-)

苏岳宁

请问老杰,本文中的代码着色,当鼠标移动到代码部分,显示的那个查看、复制、打印代码的工具条是怎么弄的呢?我的博客也使用了SyntaxHighlighter,但是只在代码最上面显示:view plaincopy to clipboardprint?,你能帮我看一下吗?http://suyuening.com/archives/74.html

oldj

貌似是因为我们用的 SyntaxHighlighter 的版本不同?我用的是 2.1.364 版,你用的好像是 1.5.1 版。
其实我也没有做特别的设置,就用的默认样式。如果你觉得这个效果不错,换一个新的版本试试呢。:-P

苏岳宁

还真是版本的原因,谢了老杰~_~

家居加盟

这个也可以上传啊 ?

龙岩SEO

走过路过支持一下嘿嘿

北边的二环

我用的是requests库,能否将poster和requests结合起来发送multiart/form-data编码文件?

发表评论: