python接口自动化16-multipart/form-data上传多个附件
前言 reuqests上传一张图片到服务器,前面已经介绍过了,那么如何在提交BUG的时候,上传附件呢? 上传附件的时候,文件的name参数名称是一样的,python里面key是不可以重复的,又如何处理参数名称相同的情况? 一、上传附件 1.以禅道提交BUG的时候上传附件为例
2.fiddler抓包看请求参数,查看到文件上传的参数如下
二、上传一个附件 1.之前学了一篇ultipart/form-data文件上传,然后学了一篇ultipart/form-data表单提交,这里文件上传,就是把两篇的知识点加起来 2.把参数分开,表单的数据用data提交,文件附件用files提交 ``` # -----------------------前面先登录步骤省略了------------- # 提交bug, 带上附件 url1 = host+"/zentao/bug-create-1-0-moduleID=0.html" d= { "product": "1", "module": "0", "project": "", "openedBuild[]": "trunk", "assignedTo": "admin", "type": "codeerror", "os": "all", "browser": "all", "color": "", "title": "yoyoketang-这是一个带附件的1", "severity": "3", "pri": "0", "steps": '<p>[步骤]</p> <p>1、第一步点</p> <p>2、第二步点</p> <p>3、点三步点</p> <p>[结果]</p> <p><img src="data/upload/1/201712/072254170557cdn.png" alt="" /></p> <p>[期望]</p>', "story": "0", "task": "0", "mailto[]": "", "keywords": "", # "files[]": ("1.png", open("d:\1.png", "rb"), "image/png"), # "labels[]": "tu1", "uid": "5a2955c884f98", "case": "0", "caseVersion": "0", "result": "0", "testtask": "0" } file = { "files[]": ("1.png", open("d:\1.png", "rb"), "image/png"), "labels[]": "tu1", } r = s.post(url1, data=d, files=file) # 分开传 print r.content ``` 三、传多个附件 1.传多个文件的时候如下,这两个参数的name都是一样的,如果用字典去传key值,很显然python的key值是不能重复的 Content-Disposition: form-data; name="files[]"; filename="1.png" Content-Type: image/png Content-Disposition: form-data; name="files[]"; filename="2.png" Content-Type: image/png 2.这时候需要换个格式,传list数据 ``` # file = { # "files[]": ("1.png", open("d:\1.png", "rb"), "image/png"), # "labels[]": "tu1", # } #-------------多个文件用list类型------------ file = [ ("files[]", ("2.png", open("d:\1.png", "rb"), "image/png")), ("labels[]", "tu1"), ("files[]", ("2.png", open("d:\2.png", "rb"), "image/png")), ("labels[]", "tu2"), ] ``` 3.上传之后,查看禅道上是可以提交成功的
四、参考代码
```
# coding:utf-8
import requests
base = 'http://127.0.0.1:81' # 禅道的服务器地址
loginUrl = base+"/zentao/user-login.html"
h = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:44.0) Gecko/20100101 Firefox/44.0",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"Accept-Language": "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3",
"Accept-Encoding": "gzip, deflate",
"Referer": base+"/zentao/user-login.html",
# "Cookie": # 头部没登录前不用传cookie,因为这里cookie就是保持登录的
"Connection": "keep-alive",
"Content-Type": "application/x-www-form-urlencoded",
}
body = {"account":"admin",
"password":"e10adc3949ba59abbe56e057f20f883e",
"keepLogin[]":"on",
"referer":base+"/zentao/my/"
}
s = requests.session() # 保持会话
r = s.post(loginUrl, data=body, headers=h)
print r.content # 打印结果看到location='http://127.0.0.1/zentao/my/'说明登录成功了
# 提交bug, 带上附件
url1 = base+"/zentao/bug-create-1-0-moduleID=0.html"
f = {
"product": "1",
"module": "0",
"project": "",
"openedBuild[]": "trunk",
"assignedTo": "admin",
"type": "codeerror",
"os": "all",
"browser": "all",
"color": "",
"title": "yoyoketang-这是一个带附件的1和2",
"severity": "3",
"pri": "0",
"steps": '<p>[步骤]</p>
<p>1、第一步点</p>
<p>2、第二步点</p>
<p>3、点三步点</p>
<p>[结果]</p>
<p><img src="data/upload/1/201712/072254170557cdn.png" alt="" /></p>
<p>[期望]</p>',
"story": "0",
"task": "0",
"mailto[]": "",
"keywords": "",
# "files[]": ("1.png", open("d:\1.png", "rb"), "image/png"),
# "labels[]": "tu1",
"uid": "5a2955c884f98",
"case": "0",
"caseVersion": "0",
"result": "0",
"testtask": "0"
}
# file = {
# "files[]": ("1.png", open("d:\1.png", "rb"), "image/png"),
# "labels[]": "tu1",
# }
#-------------多个文件用list类型------------
file = [
("files[]", ("2.png", open("d:\1.png", "rb"), "image/png")),
("labels[]", "tu1"),
("files[]", ("2.png", open("d:\2.png", "rb"), "image/png")),
("labels[]", "tu2"),
]
r = s.post(url1, data=f, files=file)
print r.content
```
- 《大话数据结构》 查找 以及一个简单的哈希表例子
- 《大话数据结构》树以及赫夫曼编码的例子
- 《大话数据结构》一些基础知识
- Golang RPC 之 gRPC
- 厚土Go学习笔记 | 06. 变量
- 厚土Go学习笔记 | 05. 函数
- Implement Domain Object in Golang
- 厚土Go学习笔记 | 04. 导入和导出的不同 用math.Pi来举例
- 厚土Go学习笔记 | 03. 数学运算的随机数
- Nodejs学习笔记(十一)--- 数据采集器示例(request和cheerio)
- 厚土Go学习笔记 | 02. 打印当前时间time.Now()时不我待
- 厚土Go学习笔记 | 01. Hello World开篇
- Golang精编100题
- IntelliJ idea配置Go开发环境
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 11个技巧让你编写出更好的Python代码
- 芯片探针到基因组区段坐标的映射
- CDH5升级到CDP7.1
- 底层架构真的折磨死个人(急,在线等)
- Python基础语法(五)—常用模块和模块的安装和导入
- Python计算文件或字符串的MD5/SHA
- .NETCore中实现ObjectId反解
- GSE16561数据集的文章图表复现,小众的illumina表达量芯片
- 数据挖掘课程能带给你什么收获
- AkShare-股票数据-龙虎榜-机构席位成交明细
- AkShare-股票数据-龙虎榜-机构席位追踪
- AkShare-股票数据-龙虎榜-营业上榜统计
- AkShare-股票数据-龙虎榜-个股上榜统计
- React中路由的使用
- CyanX 基于ReactHook的状态管理器,遵循函数式编程的理念,极简、可扩展设计哲学上手