我试图将相同的文件上传到两个不同的URL,但奇怪的是,这不起作用。第二个POST
请求从未获得该文件。因此,我尝试实现一个最小的例子来展示正在发生的事情:
import requests
files = [('file',open(os.path.join(os.getcwd(),"textFile.txt")))]
op1 = requests.post("https://httpbin.org/post",files=files)
op2 = requests.post("https://httpbin.org/post",files=files)
print(op1.json())
print("================")
print(op2.json())
因此,我希望这两个结果都有file
文件和文本信息。但我得到的是:
{'args': {}, 'data': '', 'files': {'file': "I'm Mr. TextSeeks look at meeee!"}, 'form': {}, 'headers': {'Accept': '*/*', 'Accept-Encoding': 'gzip, deflate', 'Content-Length': '186', 'Content-Type': 'multipart/form-data; boundary=196646c7550f74ac2d0a130f90350f1b', 'Host': 'httpbin.org', 'User-Agent': 'python-requests/2.22.0', 'X-Amzn-Trace-Id': 'Root=1-5f0c87c3-3355ec90b9973128fe25d6d0'}, 'json': None, 'origin': 'XX.XX.XX.XX', 'url': 'https://httpbin.org/post'}
================
{'args': {}, 'data': '', 'files': {'file': ''}, 'form': {}, 'headers': {'Accept': '*/*', 'Accept-Encoding': 'gzip, deflate', 'Content-Length': '148', 'Content-Type': 'multipart/form-data; boundary=b9e13ed8891641a6b10faaf5cded597b', 'Host': 'httpbin.org', 'User-Agent': 'python-requests/2.22.0', 'X-Amzn-Trace-Id': 'Root=1-5f0c87c4-38a66f895aee787c28ce8910'}, 'json': None, 'origin': 'XX.XX.XX.XX', 'url': 'https://httpbin.org/post'}
因此,正如您所看到的,第二个POST
请求没有文件信息。我是做错了什么,还是一个bug?
奇怪的是,这是有效的:
import requests
files = [('file',open(os.path.join(os.getcwd(),"textFile.txt")))]
op1 = requests.post("https://httpbin.org/post",files=files)
files = [('file',open(os.path.join(os.getcwd(),"textFile.txt")))]
op2 = requests.post("https://httpbin.org/post",files=files)
print(op1.json())
print("================")
print(op2.json())
输出:
{'args': {}, 'data': '', 'files': {'file': "I'm Mr. TextSeeks look at meeee!"}, 'form': {}, 'headers': {'Accept': '*/*', 'Accept-Encoding': 'gzip, deflate', 'Content-Length': '186', 'Content-Type': 'multipart/form-data; boundary=870c451b9854b5d7265b0f0681f9b4bb', 'Host': 'httpbin.org', 'User-Agent': 'python-requests/2.22.0', 'X-Amzn-Trace-Id': 'Root=1-5f0c8ad9-c0469aaa6d8a4d0023885a4d'}, 'json': None, 'origin': 'XX.XX.XX.XX', 'url': 'https://httpbin.org/post'}
================
{'args': {}, 'data': '', 'files': {'file': "I'm Mr. TextSeeks look at meeee!"}, 'form': {}, 'headers': {'Accept': '*/*', 'Accept-Encoding': 'gzip, deflate', 'Content-Length': '186', 'Content-Type': 'multipart/form-data; boundary=aadfc00c1cb0a6f1019eb2080f2a8461', 'Host': 'httpbin.org', 'User-Agent': 'python-requests/2.22.0', 'X-Amzn-Trace-Id': 'Root=1-5f0c8ada-1776e20418dda96c39a1bc48'}, 'json': None, 'origin': 'XX.XX.XX.XX', 'url': 'https://httpbin.org/post'}
因此,人们想知道一旦requests
使用该文件,该文件可能会被关闭,但是:
import requests
files = [('file',open(os.path.join(os.getcwd(),"textFile.txt")))]
op1 = requests.post("https://httpbin.org/post",files=files)
#files = [('file',open(os.path.join(os.getcwd(),"textFile.txt")))]
print(files[0][1].closed) #<=============
op2 = requests.post("https://httpbin.org/post",files=files)
print(op1.json())
print("================")
print(op2.json())
提供:
False
{'args': {}, 'data': '', 'files': {'file': "I'm Mr. TextSeeks look at meeee!"}, 'form': {}, 'headers': {'Accept': '*/*', 'Accept-Encoding': 'gzip, deflate', 'Content-Length': '186', 'Content-Type': 'multipart/form-data; boundary=a93b1c26216d7d905a5b684b0c32fe51', 'Host': 'httpbin.org', 'User-Agent': 'python-requests/2.22.0', 'X-Amzn-Trace-Id': 'Root=1-5f0c8b69-23e6606819acb268e57edf78'}, 'json': None, 'origin': 'XX.XX.XX.XX', 'url': 'https://httpbin.org/post'}
================
{'args': {}, 'data': '', 'files': {'file': ''}, 'form': {}, 'headers': {'Accept': '*/*', 'Accept-Encoding': 'gzip, deflate', 'Content-Length': '148', 'Content-Type': 'multipart/form-data; boundary=222f5304294b85527ae355bbd714a4e3', 'Host': 'httpbin.org', 'User-Agent': 'python-requests/2.22.0', 'X-Amzn-Trace-Id': 'Root=1-5f0c8b6c-5ded97a4da068830f0b38840'}, 'json': None, 'origin': 'XX.XX.XX.XX', 'url': 'https://httpbin.org/post'}
所以我绝对不知道这里发生了什么。
我知道这个问题很老了,但我遇到了同样的问题并解决了它。以下是对问题的解释和解决方案。
您的示例中发生了什么
在你的代码示例中,当你写:
import requests
files = [('file', open("textFile.txt"))]
op1 = requests.post("https://httpbin.org/post", files=files)
op2 = requests.post("https://httpbin.org/post", files=files)
实际上,您正在创建某种io.IOBase(在本例中特别是io.TextIOWrapper(。第一个post
请求将读取该文件,将文件的流位置移动到末尾。第二个post
请求使用完全相同的实例(不再打开该文件(。文件流现在指向文件的末尾,没有可读取的内容。然后发送一个空文件。
你的例子真的可以简化为";我调用fileobj.read()
两次,第二次调用显示空内容";。
fobj = open("textFile.txt")
print(fobj.read()) # "I'm Mr. TextSeeks look at meeee!"
print(fobj.read()) # ""
这就是为什么您的版本再次打开文件时没有遇到任何问题。
可能的解决方案
一种可能的解决方案是使用seek
方法重置字节流的位置:
fobj = open("textFile.txt")
print(fobj.read()) # "I'm Mr. TextSeeks look at meeee!"
fobj.seek(0)
print(fobj.read()) # "I'm Mr. TextSeeks look at meeee!"
应用于初始代码示例:
import requests
files = [('file',open("textFile.txt"))]
op1 = requests.post("https://httpbin.org/post", files=files)
files[0][1].seek(0)
op2 = requests.post("https://httpbin.org/post", files=files)
print(op1.json()) # {..., 'files': {'file': "I'm Mr. TextSeeks look at meeee!"}, ...}
print(op2.json()) # {..., 'files': {'file': "I'm Mr. TextSeeks look at meeee!"}, ...}
总之:requests
只读取作为参数给定的文件对象。它不会重置字节流。如果您使用同一个文件对象两次,则需要自己重置它。