如何在python中发送多部分/表单数据请求?怎么发文件,我懂,但是怎么用这种方法发表单数据就不懂了。
当前回答
您需要使用网站HTML中上传文件的name属性。例子:
autocomplete="off" name="image">
你看到name="image">?你可以在上传文件的网站的HTML中找到它。您需要使用它来上传Multipart/form-data文件
脚本:
import requests
site = 'https://prnt.sc/upload.php' # the site where you upload the file
filename = 'image.jpg' # name example
这里,在image的位置,用HTML添加上传文件的名称
up = {'image':(filename, open(filename, 'rb'), "multipart/form-data")}
如果上传需要点击按钮进行上传,可以这样使用:
data = {
"Button" : "Submit",
}
然后启动请求
request = requests.post(site, files=up, data=data)
完成,文件上传成功
其他回答
您需要使用网站HTML中上传文件的name属性。例子:
autocomplete="off" name="image">
你看到name="image">?你可以在上传文件的网站的HTML中找到它。您需要使用它来上传Multipart/form-data文件
脚本:
import requests
site = 'https://prnt.sc/upload.php' # the site where you upload the file
filename = 'image.jpg' # name example
这里,在image的位置,用HTML添加上传文件的名称
up = {'image':(filename, open(filename, 'rb'), "multipart/form-data")}
如果上传需要点击按钮进行上传,可以这样使用:
data = {
"Button" : "Submit",
}
然后启动请求
request = requests.post(site, files=up, data=data)
完成,文件上传成功
即使不需要上传任何文件,也需要使用files参数发送多部分表单POST请求。
从原始请求来源:
def request(method, url, **kwargs):
"""Constructs and sends a :class:`Request <Request>`.
...
:param files: (optional) Dictionary of ``'name': file-like-objects``
(or ``{'name': file-tuple}``) for multipart encoding upload.
``file-tuple`` can be a 2-tuple ``('filename', fileobj)``,
3-tuple ``('filename', fileobj, 'content_type')``
or a 4-tuple ``('filename', fileobj, 'content_type', custom_headers)``,
where ``'content-type'`` is a string
defining the content type of the given file
and ``custom_headers`` a dict-like object
containing additional headers to add for the file.
file-tuple可以是a:
2元组(文件名,fileobj) 3-tuple (filename, fileobj, content_type) 4元组(文件名,fileobj, content_type, custom_headers)。
\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \
基于以上,最简单的多部分表单请求,包括要上传的文件和表单字段,将如下所示:
import requests
multipart_form_data = {
'upload': ('custom_file_name.zip', open('myfile.zip', 'rb')),
'action': (None, 'store'),
'path': (None, '/path1')
}
response = requests.post('https://httpbin.org/post', files=multipart_form_data)
print(response.content)
注意None作为纯文本字段的元组中的第一个参数——这是文件名字段的占位符,仅用于文件上传,但对于文本字段,为了提交数据,必须将None作为第一个参数。
具有相同名称的多个字段
如果你需要发布多个具有相同名称的字段,那么你可以将你的有效负载定义为元组的列表(或元组):
multipart_form_data = (
('file2', ('custom_file_name.zip', open('myfile.zip', 'rb'))),
('action', (None, 'store')),
('path', (None, '/path1')),
('path', (None, '/path2')),
('path', (None, '/path3')),
)
流媒体请求API
如果上面的API对你来说不够python化,那么可以考虑使用requests toolbelt (pip install requests_toolbelt),它是核心请求模块的扩展,提供了对文件上传流的支持,以及可以用来代替文件的MultipartEncoder,它还允许你将负载定义为字典、元组或列表。
MultipartEncoder可以用于有或没有实际上传字段的多部分请求。它必须分配给data参数。
import requests
from requests_toolbelt.multipart.encoder import MultipartEncoder
multipart_data = MultipartEncoder(
fields={
# a file upload field
'file': ('file.zip', open('file.zip', 'rb'), 'text/plain')
# plain text fields
'field0': 'value0',
'field1': 'value1',
}
)
response = requests.post('http://httpbin.org/post', data=multipart_data,
headers={'Content-Type': multipart_data.content_type})
如果你需要发送多个相同名称的字段,或者如果表单字段的顺序很重要,那么可以使用元组或列表来代替字典:
multipart_data = MultipartEncoder(
fields=(
('action', 'ingest'),
('item', 'spam'),
('item', 'sausage'),
('item', 'eggs'),
)
)
邮差生成的代码文件上传附加的表单字段:
import http.client
import mimetypes
from codecs import encode
conn = http.client.HTTPSConnection("data.XXXX.com")
dataList = []
boundary = 'wL36Yn8afVp8Ag7AmP8qZ0SA4n1v9T'
dataList.append(encode('--' + boundary))
dataList.append(encode('Content-Disposition: form-data; name=batchSize;'))
dataList.append(encode('Content-Type: {}'.format('text/plain')))
dataList.append(encode(''))
dataList.append(encode("1"))
dataList.append(encode('--' + boundary))
dataList.append(encode('Content-Disposition: form-data; name=file; filename={0}'.format('FileName-1.json')))
fileType = mimetypes.guess_type('FileName-1.json')[0] or 'application/octet-stream'
dataList.append(encode('Content-Type: {}'.format(fileType)))
dataList.append(encode(''))
with open('FileName-1.json', 'rb') as f:
dataList.append(f.read())
dataList.append(encode('--'+boundary+'--'))
dataList.append(encode(''))
body = b'\r\n'.join(dataList)
payload = body
headers = {
'Cookie': 'XXXXXXXXXXX',
'Content-type': 'multipart/form-data; boundary={}'.format(boundary)
}
conn.request("POST", "/fileupload/uri/XXXX", payload, headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))
自从编写了以前的一些答案之后,请求已经发生了变化。在Github上看看这个问题的更多细节,这条评论是一个例子。
简而言之,files参数接受一个字典,键为表单字段的名称,值为字符串或2、3或4长度的元组,如请求快速入门中的POST一个多部分编码文件部分所述:
>>> url = 'http://httpbin.org/post'
>>> files = {'file': ('report.xls', open('report.xls', 'rb'), 'application/vnd.ms-excel', {'Expires': '0'})}
在上面,元组的组成如下:
(filename, data, content_type, headers)
如果值只是一个字符串,文件名将与键相同,如下所示:
>>> files = {'obvius_session_id': '72c2b6f406cdabd578c5fd7598557c52'}
Content-Disposition: form-data; name="obvius_session_id"; filename="obvius_session_id"
Content-Type: application/octet-stream
72c2b6f406cdabd578c5fd7598557c52
如果值是一个元组,并且第一个条目是None,则filename属性将不包括在内:
>>> files = {'obvius_session_id': (None, '72c2b6f406cdabd578c5fd7598557c52')}
Content-Disposition: form-data; name="obvius_session_id"
Content-Type: application/octet-stream
72c2b6f406cdabd578c5fd7598557c52
发送multipart/form-data键和值
curl命令:
curl -X PUT http://127.0.0.1:8080/api/xxx ...
-H 'content-type: multipart/form-data; boundary=----xxx' \
-F taskStatus=1
python请求-更复杂的POST请求:
updateTaskUrl = "http://127.0.0.1:8080/api/xxx"
updateInfoDict = {
"taskStatus": 1,
}
resp = requests.put(updateTaskUrl, data=updateInfoDict)
发送多部分/表单数据文件
curl命令:
curl -X POST http://127.0.0.1:8080/api/xxx ...
-H 'content-type: multipart/form-data; boundary=----xxx' \
-F file=@/Users/xxx.txt
POST一个多部分编码的文件:
filePath = "/Users/xxx.txt"
fileFp = open(filePath, 'rb')
fileInfoDict = {
"file": fileFp,
}
resp = requests.post(uploadResultUrl, files=fileInfoDict)
这是所有。
推荐文章
- 使用元组/列表等等。从输入vs直接引用类型如list/tuple/etc
- 结合conda环境。Yml和PIP requirements.txt
- 将命名元组转换为字典
- 如何使x轴和y轴的刻度相等呢?
- Numpy在这里函数多个条件
- 在Python中,使用argparse只允许正整数
- 如何排序mongodb与pymongo
- 不可变与可变类型
- 列表是线程安全的吗?
- 操作系统。makdirs在我的路径上不理解“~”
- 如何在Django模板中获得我的网站的域名?
- 在django Forms中定义css类
- 如何在Python中scp ?
- Numpy Max vs amax vs maximum
- 我应该在.gitignore文件中添加Django迁移文件吗?