Chinaunix首页 | 论坛 | 博客
  • 博客访问: 319959
  • 博文数量: 60
  • 博客积分: 2781
  • 博客等级: 少校
  • 技术积分: 600
  • 用 户 组: 普通用户
  • 注册时间: 2010-05-23 16:42
文章分类

全部博文(60)

文章存档

2011年(33)

2010年(27)

分类: Python/Ruby

2011-06-19 17:26:06

在上一篇博文中http://blog.chinaunix.net/space.php?uid=1721137&do=blog&id=348702,讲解了如何使用pycurl和poster进行http post upload files,这仅仅是使用POST方法上传文件,但在实际应用中,我遇到了这样一个问题,倘若有个form,里面既有输入框(FIELDS),又有上传按钮(FILES)的话,那么我们就需要同时POST fields和files,如何做呢?

假如我们有待上传的参数:
  1. params = {
  2.     'email': 'example@example.com'
  3.     'password': 'secret'
  4.     'caption': 'caption text here'
  5.     'file': user upload file
  6. }
先来看看pycurl:
  1. from urllib import urlencode
  2. import pycurl

  3. c = pycurl.Curl()
  4. c.setopt(pycurl.URL, '')
  5. c.setopt(pycurl.POST, 1) # POST method
  6. c.setopt(pycurl.POSTFIELDS, urlencode(params)) # POST fields except file
  7. c.setopt(pycurl.HTTPPOST, [('files', (pycurl.FORM_FILE, '/path/to/uploadfile'))]) # POST file using multipart/form-data
  8. c.perform()
实践中发现上面的代码并不能正确地工作,也就是pycurl并不能很好地处理同时post fields and files的情况,因为post fields使用application/x-www-form-urlencoded’编码,而post files使用'multipart/form-data'编码,所以我们需要使用另外一个更符合我们需求的模块poster。

poster模块能够很好地为我们解决同时post fields and files的问题,只需要简单的几行代码便能完成工作,这里面有个细节需要注意(我遇到的),如果k-v参数里有v是None的,需要将其删除,否则poster会报错。
  1. from poster.encode import multipart_encode
  2. from poster.streaminghttp import register_openers
  3. import urllib2

  4. params = {
    1.     'email': 'example@example.com'
    2.     'password': 'secret'
    3.     'caption': None
    4.     'file': open('/path/to/file', 'rb')
    5. }

  5. # 如果params['caption']==None,需要将caption剔除
  6. params = dict((k, v) for k, v in params.iteritems() if v)

  7. register_openers()
  8. datagen, headers = multipart_encode(params) # 很简单地将fields and files一起进行encode
  9. request = urllib2.Request('', datagen, headers)
  10. try:
  11.     urllib2.urlopen(request)
  12. except urllib2.HTTPError, e:
  13.     print e.code # http status code
总结:以后如果再遇到需要同时post fields and files的情况,就是用poster模块。
阅读(5262) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~