使用带有Python3的URLLIB上传文件

时间:2015-04-21 00:14:46

标签: python-3.x file-upload urllib

(我喜欢请求,但我的解决方案无法使用第三方)

我有使用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

0 个答案:

没有答案