(我喜欢请求,但我的解决方案无法使用第三方)
我有使用Python2的mutlipart-form上传,我正在尝试调整代码以使用Py3但是遇到了障碍。下面的代码在Py2中没有问题。使用Py3,我得到错误 typeerror:序列项28:预期的str实例,找到的字节无法执行,这可以通过在发送之前对数据进行编码来解决(根据下面的addPart中的注释掉的代码)。但是,当我对数据进行编码时,发布到服务器的文件是垃圾。
如果我捕获了与Fiddler发送的请求,我看到Py2看起来像:
------ WebKitFormBoundaryr90dqz9vOZM8UTsZ Content-Disposition:form-data; NAME = “文件”;文件名= “C:\ MYFILE \ fileto.Upload” 内容类型:application / octet-stream7z¼¯'Zø¼ª$
ķ‰( h3¾†0瓦特ô¤„*@v'‚ò‘†ÜˆÊ'ºÑÿE—1Y¥l!ÝRÿÃù]óƂ悈J)·&~\´8øÂ
¾çÃÒ+È¡¨þPX·A和?I +kýLÀýrMaà “×2HY ... O [ZSS»âÞ½*§³d
虽然Py3看起来像(对数据进行编码):
------ WebKitFormBoundarykpfIOEvOvu3Wi2F2 Content-Disposition:form-data; NAME = “文件”; filename =“C:\ myfile \ fileto.Upload”Content-Type: 应用/八位字节流> b'7z \ XBC \ XAF \'\ X1C \ X00 \ x03Z \ XF8 \ X04 \ X13 \ XBC \的Xaa
字节字符串vs ...以及二进制文件的区别是显而易见的吗?
有什么建议吗? (如果这是重复的,请标记为 - 我找不到任何东西) 请注意,我正在进行的测试是使用10mb以下的文件,因此只需一次上传
def multipart_request(params, files):
letters_digits = "".join(string.digits + string.ascii_letters)
boundary = "----WebKitFormBoundary{}".format("".join(random.choice(letters_digits) for i in range(16)))
file_lines = []
for name, value in params.items():
file_lines.extend(("--{}".format(boundary),
'Content-Disposition: form-data; name="{}"'.format(name),
"", str(value)))
for name, value in files.items():
if "filename" in value:
filename = value.get("filename")
else:
raise Exception("The filename key is required.")
if "mimetype" in value:
mimetype = value.get("mimetype")
else:
mimetype = mimetypes.guess_type(filename)[0] or "application/octet-stream"
if "content" in value:
file_lines.extend(("--{}".format(boundary),
'Content-Disposition: form-data; name="{}"; filename="{}"'.format(name, filename),
"Content-Type: {}".format(mimetype), "",
(value.get("content"))))
else:
raise Exception("The content key is required.")
file_lines.extend(("--{}--".format(boundary), ""))
request_data = "\r\n".join([str(i) for i in file_lines])
request_headers = {"Content-Type": "multipart/form-data; boundary={}".format(boundary),
"Content-Length": str(len(request_data))}
return request_data, request_headers
def addPart(url, itemID, file2Upload, title, uploadType, uploadSize):
def read_in_chunks(file_object, chunk_size=10000000):
"""Generate file chunks of 10mb"""
while True:
data = file_object.read(chunk_size)
if not data:
break
yield data
addpartURL = '{}/content/items/{}/addPart'.format(url, itemID)
f = open(file2Upload, 'rb')
for part_num, piece in enumerate(read_in_chunks(f), start=1):
files = {"file": {"filename": file2Upload, "content": piece}}
params = {"f": "json",
"token": token,
'partNum' : part_num,
'title': title,
'itemType':'file',
'type': uploadType
}
request_data, request_headers = multipart_request(params, files)
#request_data = request_data.encode('utf-8') #py3
req = request(addpartURL, request_data, request_headers)
jsonResponse = urlopen(req)
response = json.loads(jsonResponse.read())
#response = json.loads(jsonResponse.read().decode('utf-8')) #py3