您的位置: 网站首页> requests爬虫> 当前文章

requests上传多个文件及表单信息

老董-我爱我家房产SEO2021-11-12156围观,131赞

  HTTP协议中没有规定post提交数据必须使用什么数据格式,服务端根据请求头中的Content-Type字段来获取提交方式然后对数据进行解析。在html中的form表单中enctype属性有3种设置方式:

 <form action="url地址" enctype="application/x-www-form-urlencoded" method="POST">
<form action="url地址" enctype="multipart/form-data" method="POST"> 上传文件的设置
<form action="url地址" enctype="text/plain" method="POST">

  在form表单中可能会上传多个文件,我们可以写1个简单上传多个文件的界面(丑陋无比):

<form action="https://www.baidu.com/upload.php" enctype="multipart/form-data" method="POST">
<span>账号</span>:<input type="text" name="user" />
<span>密码</span>:<input type="text" name="pwd" />
<input  type="file" name="file1">  <!--选择文件按钮-->
<input  type="file" name="file2">  <!--选择文件按钮-->
<input  type="file" name="file3">  <!--选择文件按钮-->
<input type="submit" />
</form>

  在浏览器上传多个文件需要1个个点击选择提交,在requests中上传多个文件需要把文件信息写到一个由元组的列表中,每个元组就是1个文件信息。 元组的结构为(form_field_name, file_info),form_field_name代表input元素的name属性值,file_info也是1个元组,代表文件信息,一般为文件名、文件路径、文件类型

url = 'http://httpbin.org/post'
multiple_files = [
('file1', ('foo.png', open('foo.png', 'rb'), )),
('file2', ('bar.png', open('bar.png', 'rb'),)),
('file3', ('111.xlsx', open('111.xlsx', 'rb'),)),
]
r = requests.post(url, files=multiple_files)
r.text
# 看请求头
print(r.request.headers)
# 响应头
print('--------')
print(r.headers)
# 返回内容
print(r.text) # 内容太多省略
{'User-Agent': 'python-requests/2.26.0', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive', 'Content-Length': '15863', 'Content-Type': 'multipart/form-data; boundary=9a8cfa31a7ef4cd551fc5d100d5197ad'}
--------
{'Date': 'Wed, 17 Nov 2021 09:03:41 GMT', 'Content-Type': 'application/json', 'Content-Length': '21334', 'Connection': 'keep-alive', 'Server': 'gunicorn/19.9.0', 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Credentials': 'true'}

  上述请求头里有'Content-Type': multipart/form-data代表是上传文件,响应头中'Content-Type': 'application/json'代表返回的内容是json形式,即r.text是json字符串,可自行打印出来查看。

  上面丑陋的图片中,除了上传文件还要填写一些表单信息,如果两者组合起来的一起post的话,那就是files参数和data参数一并使用了,当然也可以加入一些自定义的请求头。

headers = {
'User-Agent':'www.python66.com',
'Referer': 'https://www.hao123.com/'
}
url = 'http://httpbin.org/post'
multiple_files = [
('file1', ('foo.png', open('foo.png', 'rb'), )),
('file2', ('bar.png', open('bar.png', 'rb'),)),
('file3', ('111.xlsx', open('111.xlsx', 'rb'),)),
]
dict_values = {'user':'dong','pwd':123456}
r = requests.post(url, files=multiple_files,data=dict_values,headers=headers)
r.text
# 看请求头
print(r.request.headers)
# 响应头
print('--------')
print(r.headers)
# 返回内容
print(r.text)
{'User-Agent': 'www.python66.com', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive', 'Referer': 'https://www.hao123.com/', 'Content-Length': '16042', 'Content-Type': 'multipart/form-data; boundary=80220ce953ec6177b83ffb923cbcaa38'}
--------
{'Date': 'Wed, 17 Nov 2021 09:15:49 GMT', 'Content-Type': 'application/json', 'Content-Length': '21415', 'Connection': 'keep-alive', 'Server': 'gunicorn/19.9.0', 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Credentials': 'true'}

  上述代码的响应头中可以看到header参数值都传进去了,如果检查一下r.text的值,会发现账号密码表单信息和文件file1、file2、file3都在。

  PS:强烈建议用二进制模式(binary mode)打开文件,因为requests可能会在header中增加Content-Length字段,该值会被设为文件的字节数,如果用文本模式打开文件,可能碰到错误。

很赞哦!

python编程网提示:转载请注明来源www.python66.com。
有宝贵意见可添加站长微信(底部),获取技术资料请到公众号(底部)。同行交流请加群 python学习会

文章评论

    requests上传多个文件及表单信息文章写得不错,值得赞赏

站点信息

  • 网站程序:Laravel
  • 客服微信:a772483200