一、官方说明
官方文档已经说得很明确了:
二、操作实战
我最初就没有完全理解upload:后面的意思,所以搞了好久。去看源码,使用request_toolbelt来搞明白具体怎么操作的。
结果就是这样:
其中file:后面接的是,需要上传的文件的绝对路径,看下get_file()的代码:
三、抓包分析
contractId是上传文件时,一起上传的一个值,浏览器抓包:
只需要在upload字段下面填写两个字段:
file:文件的绝对路径(D:\\uploadfile\\mudan.xlsx)
contractId:900559
四、源码分析
其他的步骤,HttpRunner都帮你做好了,源码:uploader/__init__.py
def multipart_encoder(**kwargs):
""" initialize MultipartEncoder with uploading fields.
Returns:
MultipartEncoder: initialized MultipartEncoder object
"""
def get_filetype(file_path):
file_type = filetype.guess(file_path)
if file_type:
return file_type.mime
else:
return "text/html"
ensure_upload_ready()
fields_dict = {}
for key, value in kwargs.items():
#######
# 把upload的字段 分别提取出来,分别传给key,value
# 我这边分别有两个值,一个值是file:'D:\\import.xlsx',还有一个值是, contractId:900559
#######
if os.path.isabs(value): ######所以传的路径需要时 绝对路径, 去判断文件是否存在
# value is absolute file path
_file_path = value
is_exists_file = os.path.isfile(value)
else:
# value is not absolute file path, check if it is relative file path
from httprunner.loader import load_project_meta
project_meta = load_project_meta("") ###这边是处理不是绝对路径的,寻找debugtalk.py文件,所以如果不填绝对路径,填写基于debugtalk的相对路径也是可以的
_file_path = os.path.join(project_meta.RootDir, value)
is_exists_file = os.path.isfile(_file_path)
if is_exists_file: ######文件存在,包装好文件
# value is file path to upload
filename = os.path.basename(_file_path)
mime_type = get_filetype(_file_path)
# TODO: fix ResourceWarning for unclosed file
file_handler = open(_file_path, "rb")
fields_dict[key] = (filename, file_handler, mime_type)
else:
fields_dict[key] = value ##如果不是路径,直接在fields_dict添加键值对。
return MultipartEncoder(fields=fields_dict) ###使用requests_toolbelt 封装刚刚的数据
其中 fields_dict最终的值是:
虽然它的content-type值不对,最终还是成功的
可以看下charles抓包看到的数据情况:
使用httprunner抓到的包:(不影响上传结果)
五、使用request_toobelt上传文件
直接使用requests_toolbelt上传文件,可以更加深入理解其中传值,需要什么值
其中fields就是httprunner中 fileds_dict锁需要的值
import requests
from requests_toolbelt.multipart.encoder import MultipartEncoder
import random, string
fields={
"contractId": "900643",
"file": (
"import.xlsx", open('D:\\py_36\\httpRun\\erp_create\\import.xlsx', 'rb'),
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')}
boundary = '----WebKitFormBoundary'+''.join(random.sample(string.ascii_letters+string.digits,16))
m=MultipartEncoder(fields=fields,boundary=boundary)
headers={
"Content-Type": "multipart/form-data; boundary={}".format(boundary),
"erp-token": "token-erp-a112b5e3-1304-44e9-9533-e26937bd395f"}
r = requests.post('http://XXXX?type=1', headers=headers, data=m)
print(r.text)