首页 > 解决方案 > 使用 Python 通过 POST 多部分表单数据上传文件

问题描述

我在 C# 中有以下代码,需要将其转换为 Python。

C# 中的代码:

{
            var fileName = new FileInfo(file);
            
            string requestString = "url to be used"
            var request = (HttpWebRequest)WebRequest.Create(requestString);
            request.KeepAlive = false;      
            request.AllowAutoRedirect = false;
            request.Method = "POST";
            request.Timeout = 50000;

            var boundary = "------WebKitFormBoundaryv4JOuEW2XZeLh2TK";
            byte[] startBoundaryBytes = Encoding.ASCII.GetBytes("--" + boundary + "\r\n");
            string bodyHeader = "Content-Disposition: form-data; name=\"BackupFile\"; filename=\"" + fileName.Name + "\"\r\nContent-Type: application/octet-stream\r\n\r\n";
            byte[] bodyHeaderBytes = Encoding.ASCII.GetBytes(bodyHeader);
            byte[] trailerBytes = Encoding.ASCII.GetBytes("\r\n--" + boundary + "--\r\n");

            request.ContentType = string.Format("multipart/form-data; boundary={0}", boundary);
            using (var requestStream = request.GetRequestStream()) {
                requestStream.Write(startBoundaryBytes, 0, startBoundaryBytes.Length);
                requestStream.Write(bodyHeader2Bytes, 0, bodyHeader2Bytes.Length);
                //read file and add it to request
                using(var fileStream = new FileStream(fileName.FullName, FileMode.Open, FileAccess.Read)) {
                    var buffer = new byte[4096];
                    int bytesRead = 0;
                    do {
                        bytesRead = fileStream.Read(buffer, 0, buffer.Length);
                        if(bytesRead > 0) {
                            requestStream.Write(buffer, 0, bytesRead);
                        }
                    } while(bytesRead > 0);
                }
                //write body trailer bytes
                requestStream.Write(trailerBytes, 0, trailerBytes.Length);
            }
            
            try {
                var response = request.GetResponse();
                using(var reader = new StreamReader(response.GetResponseStream())) {
                    string responseText = reader.ReadToEnd();
                }
            } catch (WebException e) {
                ...
        }

将此代码转换为 Python 的最佳方法是什么?到目前为止,我已经掌握了 Python 的基础知识,并且从我的搜索结果来看,我认为我应该使用 requests 库。但是如何将这些边界字节以及文件本身添加到请求中?

到目前为止,Python 中的代码(实际上只是基本的东西,我一直在用 requests 库尝试不同的东西,但根本没有成功):

        url = "url_to_be_used"

        fileName = "sample.sample"
        boundary = "------WebKitFormBoundaryv4JOuEW2XZeLh2TK"
        startBoundaryBytes = ("--" + boundary + "\r\n").encode("ascii")
        bodyHeader2 = "Content-Disposition: form-data; name=\"BackupFile\"; filename=\"" + fileName + "\"\r\nContent-Type: application/octet-stream\r\n\r\n"
        bodyHeader2Bytes = bodyHeader2.encode("ascii")
        trailerBytes = ("\r\n--" + boundary + "--\r\n").encode("ascii")

        headers = {"Content-Type": "multipart/form-data; boundary={}".format(boundary)}

任何帮助,将不胜感激!

谢谢

标签: pythonc#python-requests

解决方案


只需在没有流字节和标题魔术的情况下发布它:

file = {'BackupFile': open(file_name, 'rb')}
response = requests.post(url, files=file)

其余的都将requests:将发送一个多部分表单 POST 正文,其中BackupFile字段设置为file.txt文件的内容。此外,文件名将包含在特定字段的 mime 标头中。

例子:

>>> files = {'BackupFile': open('file.txt', 'rb')}
>>> print(requests.Request('POST', 'http://example.com', files=files).prepare().body.decode('ascii'))
--0c249de0e6243e92307003732e49ffe9
Content-Disposition: form-data; name="BackupFile"; filename="file.txt"
--0c249de0e6243e92307003732e49ffe9--

推荐阅读