最近接触到了上传图片的API,所以就学习如何使用Python上传图片等二进制文件。
Python自带的urllib, urllib2库并不能很好的解决用户上传二进制文件的问题,因为urlencode方法默认采用的encoding是‘application/x-www-form-urlencoded’格式,当我们上传二进制文件的时候需要将其encode成'multipart/form-data'格式,所以只能借助一些python的扩展库了。
这里介绍两种方法:1. pycurl 2. poster 另外还有一个urllib2_file,大家Google学习吧。
- import pycurl
-
- pc = pycurl.Curl()
- pc.setopt(pycurl.POST, 1) # POST method
- pc.setopt(pycurl.URL, '') # 上传的API接口
- pc.setopt(pycurl.HTTPPOST, [('file1', (c.FORM_FILE, '/path/to/your/imagefile'))]) # 设置POST方法的参数
- pc.perform() # Actually do POST request, 文件上传
- pc.close()
- from poster.encode import multipart_encode
-
from poster.streaminghttp import register_openers
-
import urllib2
-
-
register_openers()
- # datagen: 对POST参数的encode(multipart/form-data)
- # headers: 发起POST请求时的http header的信息
-
datagen, headers = multipart_encode({'file':open('/path/to/imagefile', 'rb')})
- # Create a Request object
-
request = urllib2.Request('', datagen, headers)
- # Actually do POST request
- response = urllib2.urlopen(request)
- print response.read() # 打印服务器端的回应信息
N.B. 其实上传文件的过程就是先收集POST参数数据,然后将参数数据进行multipart/form-data格式化,这样创建了一个请求对象,最后对这个请求进行处理(实际就是真正的文件上传操作)。
只有上面的代码片段,演示的效果肯定还不够形象生动,下面我们就利用Django来做个小实验吧。
假如我们的client端脚本采用了poster的代码片段,稍作修改如下:
- from poster.encode import multipart_encode
-
from poster.streaminghttp import register_openers
-
import urllib2
-
-
register_openers()
-
datagen, headers = multipart_encode({'file':open('/path/to/imagefile', 'rb')})
-
request = urllib2.Request('', datagen, headers)
-
- response = urllib2.urlopen(request)
-
-
print response.read()
然后我们在server端配置如下:
- Django_Project $> python manage.py startapp web
-
Django_Project $> cd web
- web $> vim urls.py (内容见下文)
- web $> vim views.py (内容见下文)
web $> cd ..
-
Django_Project $> vim urls.py (内容见下文)
N.B. 需要在settings.py文件中的INSTALLED_APP中添加'web'应用。
Django_Project.urls.py 内容:
- from django.conf.urls.defaults import *
-
...
-
urlpatterns = patterns('',
-
...
-
(r'web/', include('web.urls')),
-
...
-
)
Django_Project.web.urls.py 内容:
- from django.conf.urls.defaults import *
-
-
urlpatterns = patterns('',
-
(r'upload/', 'web.views.upload'),
-
)
Django_Project.web.views.py 内容:
- # Create your views here.
-
from django.http import HttpResponse
-
from django.views.decorators.csrf import csrf_exempt
-
-
@csrf_exempt # 若没有csrf处理,服务器会返回403 forbidden错误
-
def upload(request):
-
for file_name in request.FILES.keys():
- file_obj = request.FILES[file_name]
- destination = open('/path/to/save/imagefile', 'wb+')
-
for chunk in file_obj.chunks():
- destination.write(chunk)
- destination.close()
-
-
return HttpResponse('All uploaded files have been saved.')
最后运行客户端脚本,成功提示上传文件已保存,服务器端会创建用户上传的文件。
阅读(14886) | 评论(0) | 转发(0) |