解决python发送multipart/form-data请求上传文件的问题
服务器接收文件时,有时会使用表单接收的方式,这意味着我们需要使用Python的requests上传表单数据和文件。
常用的方式一般如下:
data = {
'name': 'nginx'
}
files = {'file': open("abc.csv", 'rb')}
response = requests.post(url, data=data, files=files)
files是封装好的参数,直接包括了文件内容,文件名,格式等,data则是表单内容,但这样做有一个问题,文件是中文名时,requests就会报错,哪怕encode转码成utf8也没用
百度发现除了requests的这个方法,还可以用一个第三方包MultipartEncoder,而这个包相对来说比较灵活。
一般是from requests_toolbelt.multipart.encoder import MultipartEncoder,这样导入使用
由于公司项目需要兼容各种环境,不主张使用大量第三方库,我精简模块后提取出my_compat 文件,变成 from my_compat import MultipartEncoder这样导入使用
但MultipartEncoder也存在无法转化中文名的问题,所以我在代码里取了巧,先把文件名转化成可解析的字符,然后用to_string方法解析,最后把解析后的字符串转化回去
from requests_toolbelt.multipart.encoder import MultipartEncoder
from my_compat import MultipartEncoder
import urllib
import requests
import json encoded_name = urllib.quote(file_name.encode('utf-8'))//取巧做法,先转化字符
with open(res_path, 'rb') as f_:
m = MultipartEncoder(
fields={'file': (encoded_name, f_,
'application/octet-stream')}
) decoded_m = m.to_string()//解析时不支持中文
decoded_m = decoded_m.replace(encoded_name, file_name)//替代转化
response = requests.post(url,
data=decoded_m,
headers={'Content-Type': m.content_type,
'charset': 'UTF-8'},
verify=False) try:
content = json.loads(response.content)
except ValueError:
content = response.content
return content, response.status_code
后来发现这样做其实很不方便,所以我就阅读MultipartEncoder的源码,发现content_type其实就是一个很简单的随机字符串的构造,而数据的字符流只要符合一定规范就可以构造,再结合requests包,写出了如下的代码,
#coding=utf8
import requests
from uuid import uuid4
import os file_name='test'
url= boundary=uuid4().hex
header={'Content-Type': 'multipart/form-data; boundary={0}'.format(boundary),'charset': 'UTF-8'}
with open(r'C:\test'.decode('utf8'), 'r') as f:
content=f.readlines()
print content
content=''.join(content)
datas = '--{0}{1}Content-Disposition: form-data; name="file"; filename="{2}"{1}Content-Type: application/octet-stream{1}{1}{3}{1}--{0}--{1}'. \
format(boundary,os.linesep, file_name, content,boundary)
print repr(datas)
print header
response = requests.post(url,
data=datas,
headers=header,
verify=False)
print response.status_code,response.text
在windows上调试可以,但在linux上调试一直报错,后来把os.linesep换成指定的'\r\n'分隔符就可以成功了,不知道是我们公司服务器设置问题还是这个库的解析问题。
#coding=utf8
import requests
from uuid import uuid4
import os file_name='test'
url= boundary=uuid4().hex
header={'Content-Type': 'multipart/form-data; boundary={0}'.format(boundary),'charset': 'UTF-8'}
with open(r'C:\test'.decode('utf8'), 'r') as f:
content=f.readlines()
print content
content=''.join(content)
datas = '--{0}{1}Content-Disposition: form-data; name="file"; filename="{2}"{1}Content-Type: application/octet-stream{1}{1}{3}{1}--{0}--{1}'. \
format(boundary,'\r\n', file_name, content,boundary)
print repr(datas)
print header
response = requests.post(url,
data=datas,
headers=header,
verify=False)
print response.status_code,response.text
结合saltstack,在proxy上执行的 "salt '{}' cp.push {}".format(path, agent_id, file_path)命令,效果更佳
解决python发送multipart/form-data请求上传文件的问题的更多相关文章
- python中使用multipart/form-data请求上传文件
最近测试的接口是上传文件的接口,上传单个文件,我主要使用了2种方法~ 接口例如: URL: http://www.baidu.com/*** method:post 参数: { "salar ...
- 巨蟒python全栈开发django11:ajax&&form表单上传文件contentType
回顾: 什么是异步? 可以开出一个线程,我发出请求,不用等待返回,可以做其他事情. 什么是同步? 同步就是,我发送出了一个请求,需要等待返回给我信息,我才可以操作其他事情. 局部刷新是什么? 通过jq ...
- SpringMVC实现PUT请求上传文件
在JQuery中,我们可以进行REST ful中delete和put的请求,但是在java EE标准中,默认只有在POST请求的时候,servlet 才会通过getparameter()方法取得请求体 ...
- Postman Post请求上传文件
Postman Post请求上传文件一.选择post请求方式,输入请求地址 二.填写Headers Key:Content-Type :Value:multipart/form-data 如下图 三. ...
- django 基于form表单上传文件和基于ajax上传文件
一.基于form表单上传文件 1.html里是有一个input type="file" 和 ‘submit’的标签 2.vies.py def fileupload(request ...
- SSM框架下,使用ajax请求上传文件(doc\docx\excel\图片等)
1.准备工作 1.1.添加上传必要jar包 <dependency> <groupId>commons-io</groupId> <artifactId> ...
- vue form表单上传文件
<script src="https://cdn.staticfile.org/vue-resource/1.5.1/vue-resource.min.js">< ...
- JsonResponse类的使用、form表单上传文件补充、CBV和FBV、HTML的模板语法之传值与过滤器
昨日内容回顾 Django请求生命周期 # 1.浏览器发起请求 到达Django的socket服务端(web服务网关接口) 01 wsgiref 02 uwsgi + nginx 03 WSGI协议 ...
- Python3+Selenium3+webdriver学习笔记9(发送富文本信息及上传文件处理)
#!/usr/bin/env python# -*- coding:utf-8 -*-'''Selenium3+webdriver学习笔记9(发送富文本信息及上传文件处理)'''from seleni ...
- 使用form表单上传文件
在使用form表单上传文件时候,input[type='file']是必然会用的,其中有一些小坑需要避免. 1.form的 enctype="multipart/form-data" ...
随机推荐
- python 小数据池 is和 == 编码解码
########################总结######################### 今日主要内容 1. 小数据池, id() 小数据池针对的是: int, str, bool 在p ...
- ES6checker ES6浏览器检测
检测地址如下: http://ruanyf.github.io/es-checker/index.cn.html Chrome 44检测结果如下:
- Dev-Tips
186 Chrome DevTools: How to use Logpoints for quicker JavaScript debugging You can use the new Logpo ...
- Jmeter测试报告生成
Jmeter测试报告生成 本文使用的 Jmeter 版本为 apache-jmeter-3.2 1. 命令行模式将 jtl 文件转成测试图表 注意: 这种方式只适用于jmeter3.0以后的版本 1. ...
- typdef void(*fun)(void)笔记【函数指针/typdef函数指针】
1. 函数指针:返回类型(*函数名)(参数表) 2. 使用typdef void(*fun)(void) typedef的功能是定义新的类型.第一句就是定义了一个MyFun的类型,并定义这种类型为 指 ...
- 一、VS2017 的创建程序
1.1 创建第一个子程序 1.1.1 创建项目 打开 VS2017,选择菜单栏 [文件]->[新建]->[项目]: 点击[确定]后,弹出如下界面: 点击[下一步]: 选择 空项目, 然后点 ...
- asp.net上传图片,上传图片
想必很多人工作中经常需要实现上传图片的功能. 先引用此插件 http://files.cnblogs.com/files/hmYao/jquery-form.js. 前台代码 <form dat ...
- 建立一个漂亮的PHP验证码类文件及调用方式
//验证码类class ValidateCode { private $charset = 'abcdefghkmnprstuvwxyzABCDEFGHKMNPRSTUVWXYZ23456789';/ ...
- js apply使用
js中apply方法的使用 1.对象的继承,一般的做法是复制:Object.extend prototype.js的实现方式是: Object.extend = function(destinati ...
- Oracle 数据库监听配置和服务
-- 补充说明 如果要远程连接192.168.10.44上的oracle,那么192.168.10.44服务器必须启动TNSListener.(配置文件 listener.ora) PLSQL Dev ...