前面我们通过 post 请求发送的是文本内容,也就是 ASCII 字符。如果需要发送文件到服务器,比如上传图片、视频等,就需要发送二进制数据。
一般上传文件使用的都是Content-Type: multipart/form-data;
数据类型,可以发送文件,也可以发送相关的消息体数据。
使用 requests 上传文件的基本步骤:
requests 官方文档上给出的示例如下:
>>> url = 'http://httpbin.org/post'
>>> files = {'file': open('report.xls', 'rb')} # => 直接通过open函数打开文件并将文件对象存在字典中
>>> r = requests.post(url, files=files)
>>> r.text
{
...
"files": {
"file": ""
},
...
}
# 你可以显式地设置文件名,文件类型和请求头:
>>> url = 'http://httpbin.org/post'
>>> files = {'file': ('report.xls', open('report.xls', 'rb'), 'application/vnd.ms-excel', {'Expires': '0'})} # => 打开上传文件并且加入文件相关参数
>>> r = requests.post(url, files=files)
>>> r.text
{
...
"files": {
"file": ""
},
...
}
我想大家虽然能看懂,但是依然会略显懵逼。这里我还是以 showdoc 中的文件上传为例为大家演示一下:
showdoc 中的文件上传位于接口文档的编辑页面。
我们任意选择一张图片上传,并抓包查看:
在原始中看到了相关的内容,包括 Content-Type,图片信息等(切换到 Raw 的时候会比较卡)。Raw 中始终是查看请求内容最全面的地方,只是这里会显示二进制的图片内容,会比较卡。所以第一次我们看一下 Raw 即可。以后直接在 WebForms 中查看,需要的数据在那里都可以看到。
注意其中的
name="editormd-image-file"
,需要用此 name 为服务器指定文件对象。
好,接下来我们参考官方文档上的方式模拟:
from urllib import parse
from pprint import pprint
import requests
host = 'http://127.0.0.1'
user = {
'username': 'showdoc',
'password':'123456'
}
s = requests.Session() # => 会话对象
# 登录
login_url = parse.urljoin(host, '/showdoc/server/index.php?s=/api/user/login')
lr = s.post(login_url, data=user)
pprint(lr.json())
# 上传图片
upload_url = parse.urljoin(host,'http://127.0.0.1/showdoc/server/index.php?s=/api/page/uploadImg')
# 构造图片数据,这里必须要填上图片相关参数
file = {
'editormd-image-file': open(r'D:\data\1.png', 'rb'), # => 用name指定文件
'Content-Disposition': 'form-data',
'Content-Type': 'image/png',
'filename':'1.png'
}
ur = s.post(upload_url, files=file) # => 注意这里,参数名是 files
pprint(ur.json())
警告
我们强烈建议你用二进制模式(binary mode)打开文件。这是因为 Requests 可能会试图为你提供 Content-Length header,在它这样做的时候,这个值会被设为文件的字节数(bytes)。如果用文本模式(text mode)打开文件,就可能会发生错误。