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

全部博文(60)

文章存档

2011年(33)

2010年(27)

分类: 系统运维

2011-05-31 20:52:46

最近接触到了上传图片的API,所以就学习如何使用Python上传图片等二进制文件。

Python自带的urllib, urllib2库并不能很好的解决用户上传二进制文件的问题,因为urlencode方法默认采用的encoding是‘application/x-www-form-urlencoded’格式,当我们上传二进制文件的时候需要将其encode成'multipart/form-data'格式,所以只能借助一些python的扩展库了。

这里介绍两种方法:1. pycurl 2. poster 另外还有一个urllib2_file,大家Google学习吧。
  • pycurl
  1. import pycurl

  2. pc = pycurl.Curl()
  3. pc.setopt(pycurl.POST, 1) # POST method
  4. pc.setopt(pycurl.URL, '') # 上传的API接口
  5. pc.setopt(pycurl.HTTPPOST, [('file1', (c.FORM_FILE, '/path/to/your/imagefile'))]) # 设置POST方法的参数
  6. pc.perform() # Actually do POST request, 文件上传
  7. pc.close()
  • poster
  1. from poster.encode import multipart_encode
  2. from poster.streaminghttp import register_openers
  3. import urllib2
  4.  
  5. register_openers()

  6. # datagen: 对POST参数的encode(multipart/form-data)
  7. # headers: 发起POST请求时的http header的信息
  8. datagen, headers = multipart_encode({'file':open('/path/to/imagefile', 'rb')})

  9. # Create a Request object
  10. request = urllib2.Request('', datagen, headers)

  11. # Actually do POST request
  12. response = urllib2.urlopen(request)

  13. print response.read() # 打印服务器端的回应信息

N.B. 其实上传文件的过程就是先收集POST参数数据,然后将参数数据进行multipart/form-data格式化,这样创建了一个请求对象,最后对这个请求进行处理(实际就是真正的文件上传操作)。

只有上面的代码片段,演示的效果肯定还不够形象生动,下面我们就利用Django来做个小实验吧。

假如我们的client端脚本采用了poster的代码片段,稍作修改如下:
  1. from poster.encode import multipart_encode
  2. from poster.streaminghttp import register_openers
  3. import urllib2
  4.  
  5. register_openers()

  6. datagen, headers = multipart_encode({'file':open('/path/to/imagefile', 'rb')})

  7. request = urllib2.Request('', datagen, headers)

  8. response = urllib2.urlopen(request)

  9. print response.read()
然后我们在server端配置如下:
  1. Django_Project $> python manage.py startapp web

  2. Django_Project $> cd web

  3. web $> vim urls.py (内容见下文)

  4. web $> vim views.py (内容见下文)
 
  web $> cd ..

  1. Django_Project $> vim urls.py (内容见下文)
N.B. 需要在settings.py文件中的INSTALLED_APP中添加'web'应用。
Django_Project.urls.py 内容:
  1. from django.conf.urls.defaults import *
  2. ...
  3. urlpatterns = patterns('',
  4.     ...
  5.     (r'web/', include('web.urls')),
  6.     ...
  7. )
Django_Project.web.urls.py 内容:
  1. from django.conf.urls.defaults import *

  2. urlpatterns = patterns('',
  3.     (r'upload/', 'web.views.upload'),
  4. )
Django_Project.web.views.py 内容:
  1. # Create your views here.
  2. from django.http import HttpResponse
  3. from django.views.decorators.csrf import csrf_exempt
  4.  
  5. @csrf_exempt # 若没有csrf处理,服务器会返回403 forbidden错误
  6. def upload(request):
  7.     for file_name in request.FILES.keys():
  8.         file_obj = request.FILES[file_name]
  9.         destination = open('/path/to/save/imagefile', 'wb+')
  10.         for chunk in file_obj.chunks():
  11.             destination.write(chunk)
  12.         destination.close()

  13. return HttpResponse('All uploaded files have been saved.')
最后运行客户端脚本,成功提示上传文件已保存,服务器端会创建用户上传的文件。
阅读(14886) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~